【问题标题】:Ignoring whitespace (in certain parts) in Antlr4忽略 Antlr4 中的空格(在某些部分)
【发布时间】:2020-10-26 08:16:49
【问题描述】:

我对 antlr 不是很熟悉。我使用的是第 4 版,并且我有一个语法,其中空格在某些部分并不重要(但它可能在其他部分中,或者更确切地说是运气)。

假设我们有以下语法

grammar Foo;
program : A* ;
A  : ID '@' ID '(' IDList ')' ';' ;
ID : [a-zA-Z]+ ;
IDList : ID (',' IDList)* ;
WS : [ \t\r\n]+ -> skip ;

和一个测试输入

foo@bar(X,Y);
foo@baz  ( z,Z) ;

第一行解析正确,而第二行解析不正确。 我不想用空白不相关的地方来破坏我的规则,因为我的实际语法比玩具示例更复杂。如果不清楚零件 ID '@'ID 不应该有空格。任何其他位置的空格都不重要。

【问题讨论】:

    标签: parsing antlr4 removing-whitespace


    【解决方案1】:

    即使您跳过 WS,词法分析器规则仍然对空白字符的存在很敏感。跳过只是意味着解析器不会生成任何令牌供使用。因此,词法分析器Addr 规则明确不允许任何内部空白字符。

    相反,aidList 解析器规则永远不会看到内部空白标记,因此这些规则对生成的标记之间出现的空白字符不敏感。

    grammar Foo;
    
    program : a* EOF ; // EOF will require parsing the entire input
    
    a  : Addr LParen IDList RParen Semi ;
    idList : ID (Comma ID)* ;  // simpler equivalent construct
    
    Addr : ID '@' ID ;
    ID : [a-zA-Z]+ ;
    WS : [ \t\r\n]+ -> skip ;
    

    【讨论】:

      【解决方案2】:

      ID '@' ID 定义为词法分析器标记而不是解析器标记。

      A  : AID '(' IDList ')' ';' ;
      
      AID : [a-zA-Z]+ '@' [a-zA-Z]+;
      

      其他选项

      • 在令牌流中启用/禁用空格,例如here
      • 使用词法分析器模式启用/禁用空格(可能是一个问题,因为词法分析器模式是根据上下文触发的,这在您的情况下不容易确定)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-06-27
        • 2013-10-20
        • 2020-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多