From e9914417df22786e43ec4398a2b9f5630bcf8cf0 Mon Sep 17 00:00:00 2001 From: Daniel Kroening Date: Thu, 30 Jan 2025 13:56:15 +0000 Subject: [PATCH 1/2] Verilog: add missing dependency on verilog_y.tab.h --- src/verilog/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/verilog/Makefile b/src/verilog/Makefile index d4b6c3272..2e4bc1a6d 100644 --- a/src/verilog/Makefile +++ b/src/verilog/Makefile @@ -61,4 +61,4 @@ verilog_preprocessor_lex.yy.cpp: verilog_preprocessor_tokenizer.l # extra dependencies verilog_y.tab$(OBJEXT): verilog_y.tab.cpp verilog_y.tab.h verilog_lex.yy$(OBJEXT): verilog_y.tab.cpp verilog_lex.yy.cpp verilog_y.tab.h - +verilog_scope$(OBJEXT): verilog_y.tab.h From 4d6916f31c99674d46a61d509ce095349e01a890 Mon Sep 17 00:00:00 2001 From: Daniel Kroening Date: Tue, 28 Jan 2025 13:25:30 +0000 Subject: [PATCH 2/2] SystemVerilog: package identifier tokens This introduces a separate token type for package identifiers, to enable parsing with just one token lookahead. --- src/verilog/parser.y | 23 ++++++++++++++------- src/verilog/scanner.l | 5 +---- src/verilog/verilog_scope.cpp | 39 +++++++++++++++++++++++++++++++++++ src/verilog/verilog_scope.h | 12 +++++++++++ 4 files changed, 68 insertions(+), 11 deletions(-) diff --git a/src/verilog/parser.y b/src/verilog/parser.y index a460ac86e..06bc91e4a 100644 --- a/src/verilog/parser.y +++ b/src/verilog/parser.y @@ -537,6 +537,7 @@ int yyverilogerror(const char *error) /* Others */ %token TOK_ENDOFFILE %token TOK_NON_TYPE_IDENTIFIER +%token TOK_PACKAGE_IDENTIFIER %token TOK_TYPE_IDENTIFIER %token TOK_NUMBER // number, any base %token TOK_TIME_LITERAL // number followed by time unit @@ -837,9 +838,9 @@ package_declaration: attribute_instance_brace TOK_PACKAGE { init($$, ID_verilog_package); } lifetime_opt - package_identifier ';' + any_identifier ';' { - push_scope(stack_expr($5).id(), "::", verilog_scopet::PACKAGE); + push_scope(stack_expr($5).get(ID_base_name), "::", verilog_scopet::PACKAGE); } timeunits_declaration_opt package_item_brace @@ -848,7 +849,7 @@ package_declaration: pop_scope(); $$ = $3; addswap($$, ID_module_items, $9); - stack_expr($$).set(ID_base_name, stack_expr($5).id()); + stack_expr($$).set(ID_base_name, stack_expr($5).get(ID_base_name)); } ; @@ -4224,9 +4225,11 @@ part_select_range: primary: primary_literal | hierarchical_identifier_select | package_scope hierarchical_identifier_select - { init($$, ID_verilog_package_scope); - mto($$, $1); - mto($$, $2); } + { $$ = $1; + mto($$, $2); + // exit the package scope + pop_scope(); + } | concatenation | multiple_concatenation | function_subroutine_call @@ -4405,9 +4408,15 @@ checker_identifier: TOK_NON_TYPE_IDENTIFIER; net_identifier: identifier; -package_identifier: TOK_NON_TYPE_IDENTIFIER; +package_identifier: TOK_PACKAGE_IDENTIFIER; package_scope: package_identifier "::" + { + init($$, ID_verilog_package_scope); + // enter that scope + PARSER.scopes.enter_package_scope(stack_expr($1).id()); + mto($$, $1); + } ; param_identifier: TOK_NON_TYPE_IDENTIFIER; diff --git a/src/verilog/scanner.l b/src/verilog/scanner.l index 72ec3830d..1d924fcf5 100644 --- a/src/verilog/scanner.l +++ b/src/verilog/scanner.l @@ -65,10 +65,7 @@ static void preprocessor() { newstack(yyveriloglval); \ irep_idt irep_id = text; \ stack_expr(yyveriloglval).id(irep_id); \ - auto name = PARSER.scopes.lookup(irep_id); \ - return name == nullptr ? TOK_NON_TYPE_IDENTIFIER : \ - name->kind == verilog_scopet::TYPEDEF ? TOK_TYPE_IDENTIFIER : \ - TOK_NON_TYPE_IDENTIFIER; \ + return PARSER.scopes.identifier_token(irep_id); \ } #define KEYWORD(s, x) \ { if(PARSER.parse_tree.standard >= verilog_standardt::s) \ diff --git a/src/verilog/verilog_scope.cpp b/src/verilog/verilog_scope.cpp index f343f9b73..545f62077 100644 --- a/src/verilog/verilog_scope.cpp +++ b/src/verilog/verilog_scope.cpp @@ -10,6 +10,8 @@ Author: Daniel Kroening, dkr@amazon.com #include "verilog_y.tab.h" +#include + const verilog_scopet *verilog_scopest::lookup(irep_idt base_name) const { // 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 return nullptr; } +void verilog_scopet::print_rec(std::size_t indent, std::ostream &out) const +{ + out << std::string(indent, ' ') << prefix << '\n'; + for(auto &scope_it : scope_map) + scope_it.second.print_rec(indent + 2, out); +} + void verilog_scopest::enter_package_scope(irep_idt base_name) { // look in the global scope @@ -36,3 +45,33 @@ void verilog_scopest::enter_package_scope(irep_idt base_name) else enter_scope(name_it->second); // found it } + +unsigned verilog_scopest::identifier_token(irep_idt base_name) const +{ + auto scope = lookup(base_name); + if(scope == nullptr) + { + return TOK_NON_TYPE_IDENTIFIER; + } + else + { + switch(scope->kind) + { + // clang-format off + case verilog_scopet::GLOBAL: return TOK_NON_TYPE_IDENTIFIER; + case verilog_scopet::FILE: return TOK_NON_TYPE_IDENTIFIER; + case verilog_scopet::PACKAGE: return TOK_PACKAGE_IDENTIFIER; + case verilog_scopet::MODULE: return TOK_NON_TYPE_IDENTIFIER; + case verilog_scopet::CLASS: return TOK_NON_TYPE_IDENTIFIER; + case verilog_scopet::BLOCK: return TOK_NON_TYPE_IDENTIFIER; + case verilog_scopet::ENUM_NAME: return TOK_NON_TYPE_IDENTIFIER; + case verilog_scopet::TASK: return TOK_NON_TYPE_IDENTIFIER; + case verilog_scopet::FUNCTION: return TOK_NON_TYPE_IDENTIFIER; + case verilog_scopet::TYPEDEF: return TOK_TYPE_IDENTIFIER; + case verilog_scopet::OTHER: return TOK_NON_TYPE_IDENTIFIER; + // clang-format on + } + + UNREACHABLE; + } +} diff --git a/src/verilog/verilog_scope.h b/src/verilog/verilog_scope.h index 8812cb805..ae3b41be5 100644 --- a/src/verilog/verilog_scope.h +++ b/src/verilog/verilog_scope.h @@ -11,6 +11,7 @@ Author: Daniel Kroening, dkr@amazon.com #include +#include #include // parser scopes and identifiers @@ -62,6 +63,13 @@ struct verilog_scopet return __base_name; } + void print(std::ostream &out) const + { + print_rec(0, out); + } + + void print_rec(std::size_t indent, std::ostream &) const; + // sub-scopes using scope_mapt = std::map; scope_mapt scope_map; @@ -121,6 +129,10 @@ class verilog_scopest // Look up an identifier, starting from the current scope, // going upwards until found. Returns nullptr when not found. const scopet *lookup(irep_idt base_name) const; + + // token to be returned by the scanner for the given identifier + // in the current scope + unsigned identifier_token(irep_idt base_name) const; }; #endif