【问题标题】:Expanding a token selection operator扩展令牌选择运算符
【发布时间】:2014-03-06 00:37:18
【问题描述】:

我在 ANTLR3 中有一个表达式

num_addition
    : num_multi ((plus^|minus^) num_multi)*
    ;

我想将标记“加号”和“减号”更改为不同的标记所以我尝试制定这个重写规则。

num_addition
    : num_multi (plus num_multi)* -> ^(num_multi ^(plus_special num_multi)*)
    | num_multi (minus num_multi)* -> ^(num_multi ^(minus_special num_multi)*)
    ;

如果我这样做,ANTLRWORKS 中的生成似乎需要更长的时间,但它生成了正确的语法和标记。如果我将此样式应用于其他规则,例如“multi”、“divide”和“equalequal”等。它最终会达到当我按下 Generate 时 ANTLRWORKS 不会做任何事情的地步。

根据 ANTLRWORKS 没有错误,但是当我预生成时没有任何反应。

我是否错误地重写了我想要实现的目标?

【问题讨论】:

    标签: java antlr antlr3 lexer


    【解决方案1】:

    您不能将任何与您创建 AST 的解析器规则不匹配的生产或终端注入到您的 AST 中。在您的情况下,您可以插入plusminus,因为它们与解析器规则匹配,但您不能插入plus_specialminus_special,因为它们与解析器规则num_addition 不匹配。

    可以注入虚构的令牌。

    试试这样的:

    grammar T;
    
    tokens {
      // Some imaginary tokens:
      PLUS_SPECIAL;
      MINUS_SPECIAL;
    }
    
    // ...
    
    num_addition
     : (a=num_multi -> $a) ( PLUS  b=num_multi -> ^(PLUS_SPECIAL  $num_addition $b)
                           | MINUS b=num_multi -> ^(MINUS_SPECIAL $num_addition $b)
                           )*
     ;
    
    // ...
    
    PLUS : '+';
    MINUS : '-';
    

    【讨论】:

    • 我希望您也可以插入普通令牌(PLUS 而不是 PLUS_SPECIAL)。但你对任意制作是正确的。
    • @MikeLischke,是的,您可以插入普通标记(或作品中的 AST),只要它们在作品中匹配即可:您不能插入在您想要的作品中不匹配的普通标记创建 AST。我会改写我的答案。
    • 很好的答案。正是我想要的!语法生成,但它肯定看起来更慢。
    • 我在我所有的数学和逻辑运算符中都使用了这段代码,甚至开始使用 ANTLRWorks 生成代码需要大约 4 分钟。之前只有大约 20 秒。这似乎出乎意料。
    • @meriley 你有没有定义backtrack=true;?如果是这样,您也可以尝试启用memoize=true; 以加快速度。给 ANTLR 更多的堆空间也值得尝试。还要检查它不是把事情搞砸的 ANTLRWorks:也从你的 shell 测试。
    猜你喜欢
    • 2018-08-30
    • 2019-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-20
    • 2016-09-20
    • 2020-04-13
    • 2018-07-29
    相关资源
    最近更新 更多