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; }
<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>\(\?1\) { return '+'; }
<UDPTABLE>\(\?[xX]\) { return '%'; }
@ -253,7 +255,7 @@ TU [munpf]
<UDPTABLE>[xX] { return 'x'; }
<UDPTABLE>[nN] { return 'n'; }
<UDPTABLE>[pP] { return 'p'; }
<UDPTABLE>[01\?\*\-] { return yytext[0]; }
<UDPTABLE>[01\?\*\-:;] { return yytext[0]; }
<EDGES>"01" { return K_edge_descriptor; }
<EDGES>"0x" { return K_edge_descriptor; }
@ -296,6 +298,10 @@ TU [munpf]
in_UDP = false;
break;
case K_table:
BEGIN(UDPTABLE);
break;
/* Translate these to checks if we already have or are
* outside the declaration region. */
case K_timeunit:
@ -440,10 +446,18 @@ TU [munpf]
generation_flag = generation_save;
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_]* {
if (YY_START==UDPTABLE) {
REJECT;
} else {
yylval.number = make_unsized_dec(yytext);
based_size = yylval.number->as_ulong();
return DEC_NUMBER; }
return DEC_NUMBER;
}
}
/* This rule handles scaled time values for SystemVerilog. */
[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,
* so the parser needs to switch my mode when it believes in needs to.
*/
void lex_start_table()
{
BEGIN(UDPTABLE);
}
void lex_end_table()
{
BEGIN(INITIAL);

25
parse.y
View File

@ -33,7 +33,6 @@
class PSpecPath;
extern void lex_start_table();
extern void lex_end_table();
bool have_timeunit_decl = false;
@ -6076,10 +6075,26 @@ tf_port_list_opt
| { $$ = 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
: K_table { lex_start_table(); }
udp_entry_list
K_endtable { lex_end_table(); $$ = $3; }
: K_table udp_entry_list K_endtable
{ lex_end_table();
$$ = $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
@ -6202,6 +6217,7 @@ udp_input_sym
| 'q' { $$ = 'q'; }
| '_' { $$ = '_'; }
| '+' { $$ = '+'; }
| DEC_NUMBER { yyerror(@1, "internal error: Input digits parse as decimal number!"); $$ = '0'; }
;
udp_output_sym
@ -6209,6 +6225,7 @@ udp_output_sym
| '1' { $$ = '1'; }
| '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