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:
parent
a14b8c517c
commit
7fad717a1e
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
146
vhdlpp/parse.y
146
vhdlpp/parse.y
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue