Skip to content

Commit 4d6916f

Browse files
committed
SystemVerilog: package identifier tokens
This introduces a separate token type for package identifiers, to enable parsing with just one token lookahead.
1 parent e991441 commit 4d6916f

File tree

4 files changed

+68
-11
lines changed

4 files changed

+68
-11
lines changed

src/verilog/parser.y

+16-7
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ int yyverilogerror(const char *error)
537537
/* Others */
538538
%token TOK_ENDOFFILE
539539
%token TOK_NON_TYPE_IDENTIFIER
540+
%token TOK_PACKAGE_IDENTIFIER
540541
%token TOK_TYPE_IDENTIFIER
541542
%token TOK_NUMBER // number, any base
542543
%token TOK_TIME_LITERAL // number followed by time unit
@@ -837,9 +838,9 @@ package_declaration:
837838
attribute_instance_brace TOK_PACKAGE
838839
{ init($$, ID_verilog_package); }
839840
lifetime_opt
840-
package_identifier ';'
841+
any_identifier ';'
841842
{
842-
push_scope(stack_expr($5).id(), "::", verilog_scopet::PACKAGE);
843+
push_scope(stack_expr($5).get(ID_base_name), "::", verilog_scopet::PACKAGE);
843844
}
844845
timeunits_declaration_opt
845846
package_item_brace
@@ -848,7 +849,7 @@ package_declaration:
848849
pop_scope();
849850
$$ = $3;
850851
addswap($$, ID_module_items, $9);
851-
stack_expr($$).set(ID_base_name, stack_expr($5).id());
852+
stack_expr($$).set(ID_base_name, stack_expr($5).get(ID_base_name));
852853
}
853854
;
854855

@@ -4224,9 +4225,11 @@ part_select_range:
42244225
primary: primary_literal
42254226
| hierarchical_identifier_select
42264227
| package_scope hierarchical_identifier_select
4227-
{ init($$, ID_verilog_package_scope);
4228-
mto($$, $1);
4229-
mto($$, $2); }
4228+
{ $$ = $1;
4229+
mto($$, $2);
4230+
// exit the package scope
4231+
pop_scope();
4232+
}
42304233
| concatenation
42314234
| multiple_concatenation
42324235
| function_subroutine_call
@@ -4405,9 +4408,15 @@ checker_identifier: TOK_NON_TYPE_IDENTIFIER;
44054408

44064409
net_identifier: identifier;
44074410

4408-
package_identifier: TOK_NON_TYPE_IDENTIFIER;
4411+
package_identifier: TOK_PACKAGE_IDENTIFIER;
44094412

44104413
package_scope: package_identifier "::"
4414+
{
4415+
init($$, ID_verilog_package_scope);
4416+
// enter that scope
4417+
PARSER.scopes.enter_package_scope(stack_expr($1).id());
4418+
mto($$, $1);
4419+
}
44114420
;
44124421

44134422
param_identifier: TOK_NON_TYPE_IDENTIFIER;

src/verilog/scanner.l

+1-4
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,7 @@ static void preprocessor()
6565
{ newstack(yyveriloglval); \
6666
irep_idt irep_id = text; \
6767
stack_expr(yyveriloglval).id(irep_id); \
68-
auto name = PARSER.scopes.lookup(irep_id); \
69-
return name == nullptr ? TOK_NON_TYPE_IDENTIFIER : \
70-
name->kind == verilog_scopet::TYPEDEF ? TOK_TYPE_IDENTIFIER : \
71-
TOK_NON_TYPE_IDENTIFIER; \
68+
return PARSER.scopes.identifier_token(irep_id); \
7269
}
7370
#define KEYWORD(s, x) \
7471
{ if(PARSER.parse_tree.standard >= verilog_standardt::s) \

src/verilog/verilog_scope.cpp

+39
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Author: Daniel Kroening, [email protected]
1010

1111
#include "verilog_y.tab.h"
1212

13+
#include <ostream>
14+
1315
const verilog_scopet *verilog_scopest::lookup(irep_idt base_name) const
1416
{
1517
// we start from the current scope, and walk upwards to the root
@@ -27,6 +29,13 @@ const verilog_scopet *verilog_scopest::lookup(irep_idt base_name) const
2729
return nullptr;
2830
}
2931

32+
void verilog_scopet::print_rec(std::size_t indent, std::ostream &out) const
33+
{
34+
out << std::string(indent, ' ') << prefix << '\n';
35+
for(auto &scope_it : scope_map)
36+
scope_it.second.print_rec(indent + 2, out);
37+
}
38+
3039
void verilog_scopest::enter_package_scope(irep_idt base_name)
3140
{
3241
// look in the global scope
@@ -36,3 +45,33 @@ void verilog_scopest::enter_package_scope(irep_idt base_name)
3645
else
3746
enter_scope(name_it->second); // found it
3847
}
48+
49+
unsigned verilog_scopest::identifier_token(irep_idt base_name) const
50+
{
51+
auto scope = lookup(base_name);
52+
if(scope == nullptr)
53+
{
54+
return TOK_NON_TYPE_IDENTIFIER;
55+
}
56+
else
57+
{
58+
switch(scope->kind)
59+
{
60+
// clang-format off
61+
case verilog_scopet::GLOBAL: return TOK_NON_TYPE_IDENTIFIER;
62+
case verilog_scopet::FILE: return TOK_NON_TYPE_IDENTIFIER;
63+
case verilog_scopet::PACKAGE: return TOK_PACKAGE_IDENTIFIER;
64+
case verilog_scopet::MODULE: return TOK_NON_TYPE_IDENTIFIER;
65+
case verilog_scopet::CLASS: return TOK_NON_TYPE_IDENTIFIER;
66+
case verilog_scopet::BLOCK: return TOK_NON_TYPE_IDENTIFIER;
67+
case verilog_scopet::ENUM_NAME: return TOK_NON_TYPE_IDENTIFIER;
68+
case verilog_scopet::TASK: return TOK_NON_TYPE_IDENTIFIER;
69+
case verilog_scopet::FUNCTION: return TOK_NON_TYPE_IDENTIFIER;
70+
case verilog_scopet::TYPEDEF: return TOK_TYPE_IDENTIFIER;
71+
case verilog_scopet::OTHER: return TOK_NON_TYPE_IDENTIFIER;
72+
// clang-format on
73+
}
74+
75+
UNREACHABLE;
76+
}
77+
}

src/verilog/verilog_scope.h

+12
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Author: Daniel Kroening, [email protected]
1111

1212
#include <util/irep.h>
1313

14+
#include <iosfwd>
1415
#include <map>
1516

1617
// parser scopes and identifiers
@@ -62,6 +63,13 @@ struct verilog_scopet
6263
return __base_name;
6364
}
6465

66+
void print(std::ostream &out) const
67+
{
68+
print_rec(0, out);
69+
}
70+
71+
void print_rec(std::size_t indent, std::ostream &) const;
72+
6573
// sub-scopes
6674
using scope_mapt = std::map<irep_idt, verilog_scopet>;
6775
scope_mapt scope_map;
@@ -121,6 +129,10 @@ class verilog_scopest
121129
// Look up an identifier, starting from the current scope,
122130
// going upwards until found. Returns nullptr when not found.
123131
const scopet *lookup(irep_idt base_name) const;
132+
133+
// token to be returned by the scanner for the given identifier
134+
// in the current scope
135+
unsigned identifier_token(irep_idt base_name) const;
124136
};
125137

126138
#endif

0 commit comments

Comments
 (0)