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

时间:2013-10-09 18:41:33

标签: antlr antlr4

我正在尝试使用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中读取一下后,我认为首先定义的规则优先。但是,我认为这是一场贪婪的比赛?

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

2 个答案:

答案 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提出的语法。它似乎在解析。我还删除了一些引起警告的额外可选括号。请尝试下拉再做一次。 叔