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

How to make ANTLR consume all visible elements?

这是我的语法:

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

我正在解析这段文字:

X? X! X X

这是我得到的树:

应该在语法上做些什么更改,以便我只得到一个 tail 元素,其中包含所有 foo 元素的集合?

在现实世界中,任务要复杂得多,仅使用扫描仪无法解决问题。

据我所知,你想要的是:

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)*;

你的版本只给你 1-item 列表的原因是 footail 之间的相互递归消耗了所有的项目,所以没有什么可以重复消耗。

通常当你有一些可以重复的东西时,你要么想使用 */+(如果你想在结果树中列出列表)要么 使用递归(如果你想要一个更多的 tree-like 树) - 不是两者。