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

ANTLR Verilog@(*)匹配两个令牌,antlr,antlr4,Antlr,Antlr4,我正在尝试使用ANTLR4解析Verilog代码。我使用的是这里的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 = cou

我正在尝试使用ANTLR4解析Verilog代码。我使用的是这里的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
(*)被拆分为标记“(*”和“')”

在语法文件的第723行有

event_control :
'@' event_identifier
| '@' '(' event_expression ')'
| '@' '*'
| '@' '(' '*' ')'
;
如果不是第1329行,那么哪个应该匹配@(*)行

attribute_instance : '(*' attr_spec ( ',' attr_spec )* '*)' ;
我对所有这些都不熟悉,但我猜那行中的“(*”标记与代码中的(*)匹配,并且把事情搞砸了

在阅读了权威的ANTLR 4参考资料后,我认为首先定义的规则将优先。然而,我认为它正在进行贪婪匹配

关于如何修改语法有什么想法吗

我对这一切都不熟悉,但我猜那行的
'(*')
标记与代码中的
(*
匹配,并把事情搞砸了

你说得对

在阅读了权威的ANTLR 4参考资料后,我认为首先定义的规则将优先。然而,我认为它正在进行贪婪匹配

虽然在解析器规则中定义,但文字标记实际上是lexer规则,只有当它们匹配相同数量的字符时,才会按照定义的顺序优先。如果lexer规则可以匹配更多字符,它就会这样做(正如您所观察到的)

我不知道任何Verilog,但它的一个快速修复方法是让
属性\u实例
看起来像:

attribute_instance : '(' '*' attr_spec ( ',' attr_spec )* '*' ')' ;
但是,如果lexer丢弃字符,如空格,则输入的
(*”
(括号、空格、星形)也将匹配为
属性\u实例的开头。如果不希望这样做,您可以让
事件\u控件
如下所示:

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

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

我刚刚按照巴特的建议调整了语法。它似乎在解析。我还删除了一些导致警告的可选大括号。请尝试向下拉,然后再次执行。
Ter

我看到您选择了删除“(*”标记的选项。这允许属性_实例出错。您不能有(*attrib*),它必须是(*attrib*)。另一个选项也是匹配(*'事件控制标记似乎也不是正确的方法。啊。我们可以添加一个语义谓词,只检查列以确保它们彼此相邻。我在>>移位运算符与嵌套泛型的Java语法中这样做。我刚刚阅读了权威的ANTLR 4参考(第213页)的一节这是关于>>问题的,它说在所有内容都被解析为有效性后检查它。似乎最简单的解决方案是使用Bart Kiers解决方案,并匹配(*token.cool。免费更改我的语法更新。发送拉取请求。因为在(*”,您必须使用第二个选项。但是,这似乎并不太好,因为将*附加到(.s)似乎很奇怪。是否无法将属性的“(*”保持在一起,并将它们单独用于事件?@EmbMicro如果
*
附在附件中?我还没有研究过实际使用ANTLR的目的,但这似乎会使我们更难找出()。我想只要你能区分star和not star大小写,你就可以了。@EmbMicro我看不出任何问题:当处理解析树时,你知道当你在
事件控件中时,(可能)单个
(*
*)
可以被视为两个标记。我必须使用行“|'@”((“(“*”)(“*”|“(*”)(*”)“|”(“(“*”)“|“*”)”)来处理“*)”标记。
event_control 
 : '@' event_identifier
 | '@' '(' event_expression ')'
 | '@' '*'
 | '@' ( '(' '*' | '(*' ) ')'
 ;