我正在尝试使用ANTLR4来解析Verilog代码。我使用的是https://github.com/antlr/grammars-v4/blob/master/verilog/Verilog2001.g4
中的Verilog语法示例代码是
module blinker(
input clk,
input rst,
output blink
);
reg [24:0] counter_d, counter_q;
assign blink = counter_q[24];
always @(*) begin
counter_d = counter_q + 1'b1;
end
always @(posedge clk) begin
if (rst) begin
counter_q <= 25'b0;
end else begin
counter_q <= counter_d;
end
end
endmodule
问题在于
行always @(*) begin
(*)被分成了代币'(*'和')'。
在语法文件的第723行有
event_control :
'@' event_identifier
| '@' '(' event_expression ')'
| '@' '*'
| '@' '(' '*' ')'
;
如果不是第1329行
,那么它应匹配@(*)行attribute_instance : '(*' attr_spec ( ',' attr_spec )* '*)' ;
我是所有这一切的新手,但我猜测'(*'来自该行的令牌与代码中的*匹配并搞砸了。
从The Definitive ANTLR 4 Reference中读取一下后,我认为首先定义的规则优先。但是,我认为这是一场贪婪的比赛?
关于如何修复语法的任何想法?
答案 0 :(得分:2)
我是所有这一切的新手,但我猜测该行中的
'(*'
令牌与代码中的(*
匹配并搞砸了。
你是对的。
从The Definitive ANTLR 4 Reference中读取一下后,我认为首先定义的规则优先。但是,我认为这是一场贪婪的比赛?
虽然在解析器规则中定义,但文字标记实际上是词法规则,它们按照它们定义的顺序优先于 ,以防它们匹配相同数量的字符。如果词法分析器规则可以匹配更多,则它会这样(如您所见)。
我不知道任何Verilog,但快速修复它会让attribute_instance
看起来像:
attribute_instance : '(' '*' attr_spec ( ',' attr_spec )* '*' ')' ;
但是,如果词法分析器丢弃字符(如空格),则输入"( *"
(括号,空格,星号)也将作为attribute_instance
的开头进行匹配。如果这不合适,您可以让event_control
看起来像这样:
event_control
: '@' event_identifier
| '@' '(' event_expression ')'
| '@' '*'
| '@' ( '(' '*' | '(*' ) ')'
;
请注意上一个替换中的( '(' '*' | '(*' )
,它匹配两个单个令牌'('
和'*'
(中间可能有空格!)或单个令牌'(*'
答案 1 :(得分:1)
我只是调整了Bart提出的语法。它似乎在解析。我还删除了一些引起警告的额外可选括号。请尝试下拉再做一次。 叔