From 49cf5556a29e6ece3287edbdad5db44a404d9082 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 2 Feb 2014 10:57:53 -0800 Subject: [PATCH] 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. --- lexor.lex | 27 ++++++++++++++++++--------- parse.y | 27 ++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/lexor.lex b/lexor.lex index 7c7a79649..68435444c 100644 --- a/lexor.lex +++ b/lexor.lex @@ -229,6 +229,8 @@ TU [munpf] return STRING; } . { yymore(); } + /* The UDP Table is a unique lexical environment. These are most + tokens that we can expect in a table. */ \(\?0\) { return '_'; } \(\?1\) { return '+'; } \(\?[xX]\) { return '%'; } @@ -253,7 +255,7 @@ TU [munpf] [xX] { return 'x'; } [nN] { return 'n'; } [pP] { return 'p'; } -[01\?\*\-] { return yytext[0]; } +[01\?\*\-:;] { return yytext[0]; } "01" { return K_edge_descriptor; } "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_]* { - yylval.number = make_unsized_dec(yytext); - based_size = yylval.number->as_ulong(); - return DEC_NUMBER; } + if (YY_START==UDPTABLE) { + REJECT; + } else { + yylval.number = make_unsized_dec(yytext); + based_size = yylval.number->as_ulong(); + 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); diff --git a/parse.y b/parse.y index 15e4a9814..aeb6c6007 100644 --- a/parse.y +++ b/parse.y @@ -33,7 +33,6 @@ class PSpecPath; -extern void lex_start_table(); extern void lex_end_table(); bool have_timeunit_decl = false; @@ -6076,11 +6075,27 @@ 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 : udp_comb_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