Skip to content

Commit 1abd532

Browse files
committed
SystemVerilog: separate scanner and parser state
This introduces a new data structure for the state of the Verilog scanner, as opposed to using the data structure for the parser state.
1 parent c036dd5 commit 1abd532

File tree

3 files changed

+50
-18
lines changed

3 files changed

+50
-18
lines changed

src/verilog/scanner.l

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ static int isatty(int) { return 0; }
1818
#include <util/expr.h>
1919

2020
#define PARSER (*verilog_parser_ptr)
21+
#define SCANNER (PARSER.scanner)
2122
#define YYSTYPE unsigned
2223

2324
#include "verilog_parser.h"
2425
#include "verilog_y.tab.h"
26+
#include "verilog_scanner.h"
2527

2628
int yyverilogerror(const char *error);
2729

@@ -68,34 +70,34 @@ static void preprocessor()
6870
return PARSER.scopes.identifier_token(irep_id); \
6971
}
7072
#define KEYWORD(s, x) \
71-
{ if(PARSER.parse_tree.standard >= verilog_standardt::s) \
73+
{ if(SCANNER.standard >= verilog_standardt::s) \
7274
return x; \
7375
else \
7476
IDENTIFIER(yytext); \
7577
}
7678
#define SYSTEM_VERILOG_OPERATOR(token, text) \
77-
{ if(PARSER.parse_tree.standard >= verilog_standardt::SV2005) \
79+
{ if(SCANNER.standard >= verilog_standardt::SV2005) \
7880
return token; \
7981
else \
8082
yyverilogerror(text " is a System Verilog operator"); \
8183
}
8284
#define VL2SMV_OR_SYSTEM_VERILOG_KEYWORD(x) \
83-
{ if(PARSER.parse_tree.standard >= verilog_standardt::SV2005 || \
84-
PARSER.parse_tree.standard == verilog_standardt::V2005_SMV) \
85+
{ if(SCANNER.standard >= verilog_standardt::SV2005 || \
86+
SCANNER.standard == verilog_standardt::V2005_SMV) \
8587
return x; \
8688
else \
8789
IDENTIFIER(yytext); \
8890
}
8991
#define VL2SMV_VERILOG_KEYWORD(x) \
90-
{ if(PARSER.parse_tree.standard == verilog_standardt::V2005_SMV) \
92+
{ if(SCANNER.standard == verilog_standardt::V2005_SMV) \
9193
return x; \
9294
else \
9395
IDENTIFIER(yytext); \
9496
}
9597
#define VIS_OR_VL2SMV_OR_SYSTEM_VERILOG_KEYWORD(x) \
96-
{ if(PARSER.parse_tree.standard >= verilog_standardt::SV2005 || \
97-
PARSER.parse_tree.standard == verilog_standardt::V2005_SMV || \
98-
PARSER.parse_tree.standard == verilog_standardt::V2005_VIS) \
98+
{ if(SCANNER.standard >= verilog_standardt::SV2005 || \
99+
SCANNER.standard == verilog_standardt::V2005_SMV || \
100+
SCANNER.standard == verilog_standardt::V2005_VIS) \
99101
return x; \
100102
else \
101103
IDENTIFIER(yytext); \
@@ -161,18 +163,18 @@ void verilog_scanner_init()
161163

162164
<STRING>{
163165
"\"" { BEGIN(GRAMMAR);
164-
stack_expr(yyveriloglval).id(PARSER.string_literal);
166+
stack_expr(yyveriloglval).id(SCANNER.string_literal);
165167
return TOK_QSTRING;
166168
}
167169

168170
<<EOF>> { yyverilogerror("Unterminated string constant");
169171
return TOK_SCANNER_ERROR;
170172
}
171173

172-
"\\n" { PARSER.string_literal += '\n'; } // NL (0x0a) */
173-
"\\t" { PARSER.string_literal += '\t'; } // HT (0x09) */
174-
"\\". { PARSER.string_literal += yytext[1]; } // ignore the backslash
175-
[^\\\"\n]* { PARSER.string_literal += &yytext[0]; } // everything else
174+
"\\n" { SCANNER.string_literal += '\n'; } // NL (0x0a) */
175+
"\\t" { SCANNER.string_literal += '\t'; } // HT (0x09) */
176+
"\\". { SCANNER.string_literal += yytext[1]; } // ignore the backslash
177+
[^\\\"\n]* { SCANNER.string_literal += &yytext[0]; } // everything else
176178

177179
\n { yyverilogerror("Unterminated string constant");
178180
return TOK_SCANNER_ERROR;
@@ -186,7 +188,7 @@ void verilog_scanner_init()
186188
"/*" { BEGIN COMMENT; continue; }
187189
"\"" { BEGIN(STRING);
188190
newstack(yyveriloglval);
189-
PARSER.string_literal.clear();
191+
SCANNER.string_literal.clear();
190192
}
191193

192194
/* Attributes */

src/verilog/verilog_parser.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Author: Daniel Kroening, [email protected]
1313
#include <util/parser.h>
1414

1515
#include "verilog_parse_tree.h"
16+
#include "verilog_scanner.h"
1617
#include "verilog_scope.h"
1718
#include "verilog_standard.h"
1819

@@ -28,9 +29,9 @@ class verilog_parsert:public parsert
2829
public:
2930
verilog_parse_treet parse_tree;
3031

31-
// for lexing strings
32-
std::string string_literal;
33-
32+
// scanner state
33+
verilog_scannert scanner;
34+
3435
typedef enum { LANGUAGE, EXPRESSION, TYPE } grammart;
3536
grammart grammar;
3637

@@ -42,7 +43,7 @@ class verilog_parsert:public parsert
4243
explicit verilog_parsert(
4344
verilog_standardt standard,
4445
message_handlert &message_handler)
45-
: parsert(message_handler), parse_tree(standard)
46+
: parsert(message_handler), parse_tree(standard), scanner(standard)
4647
{
4748
PRECONDITION(verilog_parser_ptr == nullptr);
4849
verilog_parser_ptr = this;

src/verilog/verilog_scanner.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*******************************************************************\
2+
3+
Module: Verilog Scanner
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#ifndef CPROVER_VERILOG_SCANNER_H
10+
#define CPROVER_VERILOG_SCANNER_H
11+
12+
#include "verilog_standard.h"
13+
14+
/// the state of the Verilog scanner
15+
class verilog_scannert
16+
{
17+
public:
18+
explicit verilog_scannert(verilog_standardt __standard) : standard(__standard)
19+
{
20+
}
21+
22+
// to determine the set of keyworkds
23+
verilog_standardt standard;
24+
25+
// for lexing strings
26+
std::string string_literal;
27+
};
28+
29+
#endif

0 commit comments

Comments
 (0)