Rewire VHDL addition expression parsing.

The VHDL LRM addition expression rules are ... different.
This commit is contained in:
Stephen Williams 2011-10-23 17:31:58 -07:00
parent 2be682f8a5
commit 4f98a6d181
1 changed files with 22 additions and 12 deletions

View File

@ -177,6 +177,8 @@ const VType*parse_type_by_name(perm_string name)
range_t* range;
ExpArithmetic::fun_t arithmetic_op;
ExpAggregate::choice_t*choice;
std::list<ExpAggregate::choice_t*>*choice_list;
ExpAggregate::element_t*element;
@ -225,6 +227,8 @@ const VType*parse_type_by_name(perm_string name)
%type <flag> direction
%type <arithmetic_op> adding_operator
%type <interface_list> interface_element interface_list
%type <interface_list> port_clause port_clause_opt
%type <interface_list> generic_clause generic_clause_opt
@ -286,6 +290,12 @@ const VType*parse_type_by_name(perm_string name)
where I put some run-time initializations. */
design_file : { yylloc.text = file_path; } design_units ;
adding_operator
: '+' { $$ = ExpArithmetic::PLUS; }
| '-' { $$ = ExpArithmetic::MINUS; }
| '&' { $$ = ExpArithmetic::CONCAT; }
;
architecture_body
: architecture_body_start
K_of IDENTIFIER
@ -1705,21 +1715,21 @@ sequential_statement
shift_expression : simple_expression { $$ = $1; } ;
/*
* The LRM rule for simple_expression is:
* simple_expression ::= [sign] term { adding_operator term }
*
* This is functionally a list of terms, with the adding_operator used
* as a list element separator instead of a ','. The LRM rule,
* however, is right-recursive, which is not to nice is real LALR
* parsers. The solution is to rewrite it as below, to make it
* left-recursive. This is must more effecient use of the parse stack.
*/
simple_expression
: term
{ $$ = $1; }
| term '+' term
{ ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::PLUS, $1, $3);
FILE_NAME(tmp, @2);
$$ = tmp;
}
| term '-' term
{ ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::MINUS, $1, $3);
FILE_NAME(tmp, @2);
$$ = tmp;
}
| term '&' term
{ ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::CONCAT, $1, $3);
| simple_expression adding_operator term
{ ExpArithmetic*tmp = new ExpArithmetic($2, $1, $3);
FILE_NAME(tmp, @2);
$$ = tmp;
}