代码之家  ›  专栏  ›  技术社区  ›  yegor256

如何让ANTLR消耗所有可见元素?

  •  0
  • yegor256  · 技术社区  · 4 年前

    这是我的语法:

    grammar test;
    text: foo EOF;
    foo:
        'X'
        |
        foo
        '!'
        |
        foo
        '?'
        |
        foo
        tail
        ;
    tail: (' ' foo)+;
    

    我正在解析此文本:

    X? X! X X
    

    这是我得到的树:

    enter image description here

    语法应该改变什么,这样我只能得到一个 tail 包含所有元素的集合 foo 内部元素?

    在现实世界中,这项任务要复杂得多,仅使用扫描仪并不能解决问题。

    0 回复  |  直到 4 年前
        1
  •  0
  •   sepp2k    4 年前

    据我所知,你想要的是:

    item: 'X' ('!' | '?')*;
    // Alternatively to get a tree per operator instead of a list of operators:
    // item
    //   : 'X'
    //   | item '!'
    //   | item '?'
    //   ;
    foo: item (' ' item)*;
    

    也许这样,如果你想让尾部在树中仍然有自己的节点:

    item: 'X' ('!' | '?')*;
    foo: item tail;
    tail: (' ' item)*;
    

    你的版本只给你一个项目列表的原因是,它们之间的相互递归 foo tail 消耗了所有的物品,所以没有什么可以重复消耗的了。

    通常,当你有可以重复的东西时,你要么想用 * / + (如果你想在生成的树中列出列表) 使用递归(如果你想要一个更像树的树),而不是两者兼而有之。