ANTLR Verilog @(*) 匹配两个令牌



我正在尝试使用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 ')'
 | '@' '*'
 | '@' ( '(' '*' | '(*' ) ')'
 ;

请注意最后一个备选方案中的( '(' '*' | '(*' ),它匹配两个单个标记,'(''*'(中间可能有空格!(,或者单个标记'(*'

我只是按照巴特的建议调整了语法。它似乎解析了。我还删除了一些导致警告的额外可选大括号。请尝试向下拉并重新执行。之三

最新更新