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:
parent
3e95966d70
commit
49cf5556a2
23
lexor.lex
23
lexor.lex
|
|
@ -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
25
parse.y
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue