Fix primitive table lexical analysis.

Sequences of digits in the table of a primitive may be matched
as decimal numbers instead of digits, and this breaks some
primitives.
This commit is contained in:
Stephen Williams 2014-02-02 10:57:53 -08:00
parent 3e95966d70
commit 49cf5556a2
2 changed files with 40 additions and 14 deletions

View File

@ -229,6 +229,8 @@ TU [munpf]
return STRING; } return STRING; }
<CSTRING>. { yymore(); } <CSTRING>. { yymore(); }
/* The UDP Table is a unique lexical environment. These are most
tokens that we can expect in a table. */
<UDPTABLE>\(\?0\) { return '_'; } <UDPTABLE>\(\?0\) { return '_'; }
<UDPTABLE>\(\?1\) { return '+'; } <UDPTABLE>\(\?1\) { return '+'; }
<UDPTABLE>\(\?[xX]\) { return '%'; } <UDPTABLE>\(\?[xX]\) { return '%'; }
@ -253,7 +255,7 @@ TU [munpf]
<UDPTABLE>[xX] { return 'x'; } <UDPTABLE>[xX] { return 'x'; }
<UDPTABLE>[nN] { return 'n'; } <UDPTABLE>[nN] { return 'n'; }
<UDPTABLE>[pP] { return 'p'; } <UDPTABLE>[pP] { return 'p'; }
<UDPTABLE>[01\?\*\-] { return yytext[0]; } <UDPTABLE>[01\?\*\-:;] { return yytext[0]; }
<EDGES>"01" { return K_edge_descriptor; } <EDGES>"01" { return K_edge_descriptor; }
<EDGES>"0x" { return K_edge_descriptor; } <EDGES>"0x" { return K_edge_descriptor; }
@ -296,6 +298,10 @@ TU [munpf]
in_UDP = false; in_UDP = false;
break; break;
case K_table:
BEGIN(UDPTABLE);
break;
/* Translate these to checks if we already have or are /* Translate these to checks if we already have or are
* outside the declaration region. */ * outside the declaration region. */
case K_timeunit: case K_timeunit:
@ -440,10 +446,18 @@ TU [munpf]
generation_flag = generation_save; generation_flag = generation_save;
return UNBASED_NUMBER; } return UNBASED_NUMBER; }
/* Decimal numbers are the usual. But watch out for the UDPTABLE
mode, where there are no decimal numbers. Reject the match if we
are in the UDPTABLE state. */
[0-9][0-9_]* { [0-9][0-9_]* {
yylval.number = make_unsized_dec(yytext); if (YY_START==UDPTABLE) {
based_size = yylval.number->as_ulong(); REJECT;
return DEC_NUMBER; } } else {
yylval.number = make_unsized_dec(yytext);
based_size = yylval.number->as_ulong();
return DEC_NUMBER;
}
}
/* This rule handles scaled time values for SystemVerilog. */ /* This rule handles scaled time values for SystemVerilog. */
[0-9][0-9_]*(\.[0-9][0-9_]*)?{TU}?s { [0-9][0-9_]*(\.[0-9][0-9_]*)?{TU}?s {
@ -791,11 +805,6 @@ TU [munpf]
* lexor. The level characters are normally accepted as other things, * lexor. The level characters are normally accepted as other things,
* so the parser needs to switch my mode when it believes in needs to. * so the parser needs to switch my mode when it believes in needs to.
*/ */
void lex_start_table()
{
BEGIN(UDPTABLE);
}
void lex_end_table() void lex_end_table()
{ {
BEGIN(INITIAL); BEGIN(INITIAL);

27
parse.y
View File

@ -33,7 +33,6 @@
class PSpecPath; class PSpecPath;
extern void lex_start_table();
extern void lex_end_table(); extern void lex_end_table();
bool have_timeunit_decl = false; bool have_timeunit_decl = false;
@ -6076,11 +6075,27 @@ tf_port_list_opt
| { $$ = 0; } | { $$ = 0; }
; ;
/* Note that the lexor notices the "table" keyword and starts
the UDPTABLE state. It needs to happen there so that all the
characters in the table are interpreted in that mode. It is still
up to this rule to take us out of the UDPTABLE state. */
udp_body udp_body
: K_table { lex_start_table(); } : K_table udp_entry_list K_endtable
udp_entry_list { lex_end_table();
K_endtable { lex_end_table(); $$ = $3; } $$ = $2;
; }
| K_table K_endtable
{ lex_end_table();
yyerror(@1, "error: Empty UDP table.");
$$ = 0;
}
| K_table error K_endtable
{ lex_end_table();
yyerror(@2, "Errors in UDP table");
yyerrok;
$$ = 0;
}
;
udp_entry_list udp_entry_list
: udp_comb_entry_list : udp_comb_entry_list
@ -6202,6 +6217,7 @@ udp_input_sym
| 'q' { $$ = 'q'; } | 'q' { $$ = 'q'; }
| '_' { $$ = '_'; } | '_' { $$ = '_'; }
| '+' { $$ = '+'; } | '+' { $$ = '+'; }
| DEC_NUMBER { yyerror(@1, "internal error: Input digits parse as decimal number!"); $$ = '0'; }
; ;
udp_output_sym udp_output_sym
@ -6209,6 +6225,7 @@ udp_output_sym
| '1' { $$ = '1'; } | '1' { $$ = '1'; }
| 'x' { $$ = 'x'; } | 'x' { $$ = 'x'; }
| '-' { $$ = '-'; } | '-' { $$ = '-'; }
| DEC_NUMBER { yyerror(@1, "internal error: Output digits parse as decimal number!"); $$ = '0'; }
; ;
/* Port declarations create wires for the inputs and the output. The /* Port declarations create wires for the inputs and the output. The