2

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

我对这一切都很陌生,但我猜测该行中的 '(*' 标记与代码中的 (* 匹配并且搞砸了。

在阅读了 The Definitive ANTLR 4 Reference 的一些内容后,我认为首先定义的规则将优先。但是,我认为它正在做一个贪婪的比赛?

关于如何修复语法的任何想法?

4

2 回答 2

2

我对这一切都很陌生,但我猜该'(*'行中的标记与(*代码中的匹配并且搞砸了。

你是对的。

在阅读了 The Definitive ANTLR 4 Reference 的一些内容后,我认为首先定义的规则将优先。但是,我认为它正在做一个贪婪的比赛?

尽管在解析器规则中定义,文字标记实际上是词法分析器规则,仅在它们匹配相同数量的字符的情况下,它们的定义顺序优先。如果词法分析器规则可以匹配更多,它会这样做(如您所见)。

我不知道任何 Verilog,但一个快速的解决方法是让它attribute_instance看起来像:

attribute_instance : '(' '*' attr_spec ( ',' attr_spec )* '*' ')' ;

但是,如果词法分析器丢弃字符,如空格,则输入"( *"(括号、空格、星号)也将匹配为 a 的开头attribute_instance。如果这不是可取的,你可以让你event_control看起来像这样:

event_control 
 : '@' event_identifier
 | '@' '(' event_expression ')'
 | '@' '*'
 | '@' ( '(' '*' | '(*' ) ')'
 ;

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

于 2013-10-09T19:48:06.933 回答
1

我只是按照 Bart 的建议调整了语法。它似乎解析。我还删除了一些导致警告的额外可选大括号。请尝试拉下并再做一次。三

于 2013-10-09T19:56:32.307 回答