我正在尝试使用ANTLR4来解析Verilog代码。我正在使用此处的Verilog语法 https://github.com/antlr/grammars-v4/blob/master/verilog/Verilog2001.g4
示例代码为
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 )* '*)' ;
我对这一切都是新手,但我猜该行中的"(*"标记与代码中的 (*( 匹配并搞砸了事情。
在阅读了《权威ANTLR 4参考》之后,我认为首先定义的规则将优先。但是,我认为这是在做贪婪的比赛?
关于如何修复语法的任何想法?
我对这一切都是新手,但我猜该行的
'(*'
令牌与代码中的(*
匹配并搞砸了事情。
你是对的。
在阅读了《权威ANTLR 4参考》之后,我认为首先定义的规则将优先。但是,我认为这是在做贪婪的比赛?
尽管在分析器规则中定义,但文本标记实际上是词法分析器规则,只有在它们匹配相同数量的字符时,它们才按定义的顺序优先。如果词法分析器规则可以匹配更多,它就会这样做(如您所观察到的(。
我不知道任何Verilog,但是快速解决方法是让attribute_instance
如下所示:
attribute_instance : '(' '*' attr_spec ( ',' attr_spec )* '*' ')' ;
但是,如果词法分析器丢弃字符(如空格(,则输入"( *"
(括号、空格、星号(也将匹配为attribute_instance
的开头。如果这不可取,你可以让你的event_control
看起来像这样:
event_control
: '@' event_identifier
| '@' '(' event_expression ')'
| '@' '*'
| '@' ( '(' '*' | '(*' ) ')'
;
请注意最后一个备选方案中的( '(' '*' | '(*' )
,它匹配两个单个标记,'('
和 '*'
(中间可能有空格!(,或者单个标记'(*'
。
我只是按照巴特的建议调整了语法。它似乎解析了。我还删除了一些导致警告的额外可选大括号。请尝试向下拉并重新执行。之三