Redesign selected_name rule to better handle complex prefixes

Prefixes of hierarchical names are complex and cannot be handled
by simple strings, to the rules must be reworked.
This commit is contained in:
Stephen Williams 2012-09-01 12:05:40 -07:00
parent a14b8c517c
commit 7fad717a1e
3 changed files with 82 additions and 118 deletions

View File

@ -50,28 +50,6 @@ bool Expression::symbolic_compare(const Expression*) const
return false; return false;
} }
bool ExpName::symbolic_compare(const Expression*that) const
{
const ExpName*that_name = dynamic_cast<const ExpName*> (that);
if (that_name == 0)
return false;
if (name_ != that_name->name_)
return false;
if (that_name->index_ && !index_)
return false;
if (index_ && !that_name->index_)
return false;
if (index_) {
assert(that_name->index_);
return index_->symbolic_compare(that_name->index_);
}
return true;
}
ExpAttribute::ExpAttribute(ExpName*bas, perm_string nam) ExpAttribute::ExpAttribute(ExpName*bas, perm_string nam)
: base_(bas), name_(nam) : base_(bas), name_(nam)
{ {
@ -366,6 +344,36 @@ const char* ExpName::name() const
return name_; return name_;
} }
bool ExpName::symbolic_compare(const Expression*that) const
{
const ExpName*that_name = dynamic_cast<const ExpName*> (that);
if (that_name == 0)
return false;
if (name_ != that_name->name_)
return false;
if (that_name->index_ && !index_)
return false;
if (index_ && !that_name->index_)
return false;
if (index_) {
assert(that_name->index_);
return index_->symbolic_compare(that_name->index_);
}
return true;
}
void ExpName::set_range(Expression*msb, Expression*lsb)
{
assert(index_==0);
index_ = msb;
assert(lsb_==0);
lsb_ = lsb;
}
ExpRelation::ExpRelation(ExpRelation::fun_t ty, Expression*op1, Expression*op2) ExpRelation::ExpRelation(ExpRelation::fun_t ty, Expression*op1, Expression*op2)
: ExpBinary(op1, op2), fun_(ty) : ExpBinary(op1, op2), fun_(ty)
{ {

View File

@ -528,6 +528,8 @@ class ExpName : public Expression {
void dump(ostream&out, int indent = 0) const; void dump(ostream&out, int indent = 0) const;
const char* name() const; const char* name() const;
void set_range(Expression*msb, Expression*lsb);
private: private:
const VType* elaborate_adjust_type_with_range_(Entity*ent, Architecture*arc, const VType*type); const VType* elaborate_adjust_type_with_range_(Entity*ent, Architecture*arc, const VType*type);

View File

@ -7,6 +7,7 @@
%{ %{
/* /*
* Copyright (c) 2011-2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2011-2012 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -167,37 +168,6 @@ static Expression*aggregate_or_primary(const YYLTYPE&loc, std::list<ExpAggregate
return el1->extract_expression(); return el1->extract_expression();
} }
static ExpName*make_name_from_prefix(const YYLTYPE&loc, const vector<perm_string>*names)
{
ExpName*cur = new ExpName(names->at(0));
FILE_NAME(cur, loc);
for (size_t idx = 1 ; idx < names->size() ; idx += 1) {
ExpName*tmp = new ExpName(cur, names->at(idx));
FILE_NAME(tmp, loc);
cur = tmp;
}
return cur;
}
static ExpName*make_name_from_prefix(const YYLTYPE&loc, const vector<perm_string>*names, Expression*msb, Expression*lsb)
{
ExpName*cur = new ExpName(names->at(0));
FILE_NAME(cur, loc);
for (size_t idx = 1 ; idx < (names->size()-1) ; idx += 1) {
ExpName*tmp = new ExpName(cur, names->at(idx));
FILE_NAME(tmp, loc);
cur = tmp;
}
ExpName*result = new ExpName(cur, names->back(), msb, lsb);
FILE_NAME(result, loc);
return result;
}
static list<VTypeRecord::element_t*>* record_elements(list<perm_string>*names, static list<VTypeRecord::element_t*>* record_elements(list<perm_string>*names,
const VType*type) const VType*type)
{ {
@ -220,8 +190,6 @@ static list<VTypeRecord::element_t*>* record_elements(list<perm_string>*names,
char*text; char*text;
std::list<perm_string>* name_list; std::list<perm_string>* name_list;
std::vector<perm_string>* compound_name;
std::list<std::vector<perm_string>* >* compound_name_list;
bool flag; bool flag;
int64_t uni_integer; int64_t uni_integer;
@ -331,7 +299,7 @@ static list<VTypeRecord::element_t*>* record_elements(list<perm_string>*names,
%type <expr> expression factor primary relation %type <expr> expression factor primary relation
%type <expr> expression_logical expression_logical_and expression_logical_or %type <expr> expression_logical expression_logical_and expression_logical_or
%type <expr> expression_logical_xnor expression_logical_xor %type <expr> expression_logical_xnor expression_logical_xor
%type <expr> name %type <expr> name prefix selected_name
%type <expr> shift_expression signal_declaration_assign_opt %type <expr> shift_expression signal_declaration_assign_opt
%type <expr> simple_expression term waveform_element %type <expr> simple_expression term waveform_element
%type <expr> interface_element_expression %type <expr> interface_element_expression
@ -339,6 +307,7 @@ static list<VTypeRecord::element_t*>* record_elements(list<perm_string>*names,
%type <expr_list> waveform waveform_elements %type <expr_list> waveform waveform_elements
%type <expr_list> name_list expression_list %type <expr_list> name_list expression_list
%type <expr_list> process_sensitivity_list process_sensitivity_list_opt %type <expr_list> process_sensitivity_list process_sensitivity_list_opt
%type <expr_list> selected_names use_clause
%type <named_expr> association_element %type <named_expr> association_element
%type <named_expr_list> association_list port_map_aspect port_map_aspect_opt %type <named_expr_list> association_list port_map_aspect port_map_aspect_opt
@ -353,8 +322,6 @@ static list<VTypeRecord::element_t*>* record_elements(list<perm_string>*names,
%type <text> identifier_opt identifier_colon_opt logical_name suffix %type <text> identifier_opt identifier_colon_opt logical_name suffix
%type <name_list> logical_name_list identifier_list %type <name_list> logical_name_list identifier_list
%type <name_list> enumeration_literal_list enumeration_literal %type <name_list> enumeration_literal_list enumeration_literal
%type <compound_name> prefix selected_name
%type <compound_name_list> selected_names use_clause
%type <sequ_list> sequence_of_statements if_statement_else %type <sequ_list> sequence_of_statements if_statement_else
%type <sequ> sequential_statement if_statement signal_assignment_statement %type <sequ> sequential_statement if_statement signal_assignment_statement
@ -1497,8 +1464,8 @@ mode
mode_opt : mode {$$ = $1;} | {$$ = PORT_NONE;} ; mode_opt : mode {$$ = $1;} | {$$ = PORT_NONE;} ;
name name /* IEEE 1076-2008 P8.1 */
: IDENTIFIER : IDENTIFIER /* simple_name (IEEE 1076-2008 P8.2) */
{ ExpName*tmp = new ExpName(lex_strings.make($1)); { ExpName*tmp = new ExpName(lex_strings.make($1));
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
delete[]$1; delete[]$1;
@ -1506,16 +1473,13 @@ name
} }
| selected_name | selected_name
{ ExpName*tmp = make_name_from_prefix(@1, $1); { $$ = $1; }
delete $1;
$$ = tmp;
}
/* Note that this rule can match array element selects and various /* Note that this rule can match array element selects and various
function calls. The only way we can tell the difference is from function calls. The only way we can tell the difference is from
left context, namely whether the name is a type name or function left context, namely whether the name is a type name or function
name. If none of the above, treat it as a array element select. */ name. If none of the above, treat it as a array element select. */
| IDENTIFIER '(' expression_list ')' | IDENTIFIER '(' expression_list ')'
{ perm_string name = lex_strings.make($1); { perm_string name = lex_strings.make($1);
delete[]$1; delete[]$1;
if (active_scope->is_vector_name(name)) { if (active_scope->is_vector_name(name)) {
@ -1527,15 +1491,15 @@ name
} }
FILE_NAME($$, @1); FILE_NAME($$, @1);
} }
| IDENTIFIER '(' range ')' | IDENTIFIER '(' range ')'
{ ExpName*tmp = new ExpName(lex_strings.make($1), $3->msb(), $3->lsb()); { ExpName*tmp = new ExpName(lex_strings.make($1), $3->msb(), $3->lsb());
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
delete[]$1; delete[]$1;
$$ = tmp; $$ = tmp;
} }
| selected_name '(' range ')' | selected_name '(' range ')'
{ ExpName*tmp = make_name_from_prefix(@1, $1, $3->msb(), $3->lsb()); { ExpName*tmp = dynamic_cast<ExpName*> ($1);
delete $1; tmp->set_range($3->msb(), $3->lsb());
$$ = tmp; $$ = tmp;
} }
; ;
@ -1667,20 +1631,9 @@ port_map_aspect_opt
| { $$ = 0; } | { $$ = 0; }
; ;
prefix
: IDENTIFIER prefix /* IEEE 1076-2008 P8.1 */
{ std::vector<perm_string>* tmp = new std::vector<perm_string>(); : name
tmp->push_back(lex_strings.make($1));
delete[] $1;
$$ = tmp;
}
| STRING_LITERAL
{ std::vector<perm_string>* tmp = new std::vector<perm_string>();
tmp->push_back(lex_strings.make($1));
delete[] $1;
$$ = tmp;
}
| selected_name
{ $$ = $1; } { $$ = $1; }
; ;
@ -1926,34 +1879,42 @@ secondary_unit
| package_body | package_body
; ;
selected_name selected_name /* IEEE 1076-2008 P8.3 */
: prefix '.' suffix : prefix '.' suffix
{ std::vector<perm_string>* tmp = $1; { Expression*pfx = $1;
tmp->push_back(lex_strings.make($3)); ExpName*pfx1 = dynamic_cast<ExpName*>(pfx);
delete[] $3; assert(pfx1);
$$ = tmp; perm_string tmp = lex_strings.make($3);
$$ = new ExpName(pfx1, tmp);
FILE_NAME($$, @3);
delete[]$3;
}
| error '.' suffix
{ errormsg(@1, "Syntax error in prefix in front of \"%s\".\n", $3);
yyerrok;
$$ = new ExpName(lex_strings.make($3));
FILE_NAME($$, @3);
delete[]$3;
} }
; ;
selected_names selected_names
: selected_names ',' selected_name : selected_names ',' selected_name
{ { std::list<Expression*>* tmp = $1;
std::list<std::vector<perm_string>* >* tmp = $1; tmp->push_back($3);
tmp->push_back($3); $$ = tmp;
$$ = tmp;
} }
| selected_name | selected_name
{ { std::list<Expression*>* tmp = new std::list<Expression*>();
std::list<std::vector<perm_string>* >* tmp = new std::list<std::vector<perm_string>* >(); tmp->push_back($1);
tmp->push_back($1); $$ = tmp;
$$ = tmp;
} }
; ;
/* The *_use variant of selected_name is used by the "use" /* The *_lib variant of selected_name is used by the "use"
clause. It is syntactically identical to other selected_name clause. It is syntactically identical to other selected_name
rules, but is a convenient place to attach use_clause actions. */ rules, but is a convenient place to attach use_clause actions. */
selected_name_use selected_name_lib
: IDENTIFIER '.' K_all : IDENTIFIER '.' K_all
{ library_use(@1, active_scope, 0, $1, 0); { library_use(@1, active_scope, 0, $1, 0);
delete[]$1; delete[]$1;
@ -1971,9 +1932,9 @@ selected_name_use
} }
; ;
selected_names_use selected_names_lib
: selected_names_use ',' selected_name_use : selected_names_lib ',' selected_name_lib
| selected_name_use | selected_name_lib
; ;
@ -2102,17 +2063,12 @@ subtype_indication
suffix suffix
: IDENTIFIER : IDENTIFIER
{ { $$ = $1; }
$$ = $1;
}
| CHARACTER_LITERAL | CHARACTER_LITERAL
{ { $$ = $1; }
$$ = $1;
}
| K_all | K_all
{ { //do not have now better idea than using char constant
//do not have now better idea than using char constant $$ = strcpy(new char[strlen("all"+1)], "all");
$$ = strcpy(new char[strlen("all"+1)], "all");
} }
; ;
@ -2191,30 +2147,28 @@ type_definition
use_clause use_clause
: K_use selected_names ';' : K_use selected_names ';'
{ { $$ = $2; }
$$ = $2;
}
| K_use error ';' | K_use error ';'
{ errormsg(@1, "Syntax error in use clause.\n"); yyerrok; } { errormsg(@1, "Syntax error in use clause.\n"); yyerrok; }
; ;
use_clause_lib use_clause_lib
: K_use selected_names_use ';' : K_use selected_names_lib ';'
| K_use error ';' | K_use error ';'
{ errormsg(@1, "Syntax error in use clause.\n"); yyerrok; } { errormsg(@1, "Syntax error in use clause.\n"); yyerrok; }
; ;
use_clauses use_clauses_lib
: use_clauses use_clause : use_clauses_lib use_clause_lib
| use_clause | use_clause_lib
; ;
use_clauses_opt use_clauses_opt
: use_clauses : use_clauses_lib
| |
; ;
variable_assignment_statement variable_assignment_statement /* IEEE 1076-2008 P10.6.1 */
: name VASSIGN expression ';' : name VASSIGN expression ';'
{ VariableSeqAssignment*tmp = new VariableSeqAssignment($1, $3); { VariableSeqAssignment*tmp = new VariableSeqAssignment($1, $3);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);