From ca9616dc7b3f7b29f237ae74bab751e085b8cd54 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Wed, 12 Jun 2013 14:01:43 -0700 Subject: [PATCH] Better simple_expression parse rules. --- vhdlpp/parse.y | 72 +++++++++++++++++++++++++++++++++++--------- vhdlpp/parse_types.h | 6 ++++ 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index d21de7f84..05c1dea36 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -233,6 +233,7 @@ static void touchup_interface_for_functions(std::list*ports) std::list*range_list; ExpArithmetic::fun_t arithmetic_op; + std::list*adding_terms; ExpAggregate::choice_t*choice; std::list*choice_list; @@ -287,6 +288,7 @@ static void touchup_interface_for_functions(std::list*ports) %type direction %type adding_operator +%type simple_expression_terms %type interface_element interface_list %type port_clause port_clause_opt @@ -314,7 +316,7 @@ static void touchup_interface_for_functions(std::list*ports) %type expression_logical_xnor expression_logical_xor %type name prefix selected_name %type shift_expression signal_declaration_assign_opt -%type simple_expression term waveform_element +%type simple_expression simple_expression_2 term waveform_element %type interface_element_expression %type waveform waveform_elements @@ -1788,12 +1790,12 @@ procedure_call $$ = tmp; } | IDENTIFIER '(' error ')' - { - errormsg(@1, "Errors in procedure call.\n"); - yyerrok; - delete[]$1; - $$ = 0; - }; + { errormsg(@1, "Errors in procedure call.\n"); + yyerrok; + delete[]$1; + $$ = 0; + } + ; procedure_call_statement : IDENTIFIER ':' procedure_call { $$ = $3; } @@ -2067,6 +2069,11 @@ sequential_statement shift_expression : simple_expression { $$ = $1; } ; +sign + : '+' + | '-' + ; + signal_declaration_assign_opt : VASSIGN expression { $$ = $2; } | { $$ = 0; } @@ -2085,18 +2092,55 @@ signal_declaration_assign_opt * Note that although the concatenation operator '&' is syntactically * an addition operator, it is handled differently during elaboration * so detect it and create a different expression type. + * + * Note too that I'm using *right* recursion to implement the {...} + * part of the rule. This is normally bad, but expression lists aren't + * normally that long, and the while loop going through the formed + * list fixes up the associations. */ simple_expression + : sign simple_expression_2 + { sorrymsg(@1, "Unary expression +- not supported.\n"); + $$ = $2; + } + | simple_expression_2 + { $$ = $1; } + ; + +simple_expression_2 : term { $$ = $1; } - | simple_expression adding_operator term - { Expression*tmp; - if ($2 == ExpArithmetic::xCONCAT) { - tmp = new ExpConcat($1, $3); - } else { - tmp = new ExpArithmetic($2, $1, $3); + | term simple_expression_terms + { Expression*tmp = $1; + list*lst = $2; + while (! lst->empty()) { + struct adding_term item = lst->front(); + lst->pop_front(); + if (item.op == ExpArithmetic::xCONCAT) + tmp = new ExpConcat(tmp, item.term); + else + tmp = new ExpArithmetic(item.op, tmp, item.term); } - FILE_NAME(tmp, @2); + delete lst; + $$ = tmp; + } + ; + +simple_expression_terms + : adding_operator term + { struct adding_term item; + item.op = $1; + item.term = $2; + list*tmp = new list; + tmp->push_back(item); + $$ = tmp; + } + | simple_expression_terms adding_operator term + { list*tmp = $1; + struct adding_term item; + item.op = $2; + item.term = $3; + tmp->push_back(item); $$ = tmp; } ; diff --git a/vhdlpp/parse_types.h b/vhdlpp/parse_types.h index fb9b5a9b5..2773aead8 100644 --- a/vhdlpp/parse_types.h +++ b/vhdlpp/parse_types.h @@ -90,4 +90,10 @@ class prange_t { prange_t(const prange_t&); prange_t operator=(const prange_t&); }; + +struct adding_term { + ExpArithmetic::fun_t op; + Expression*term; +}; + #endif