Java 如何使用递归使ANTLR使用所有可用元素?

Java 如何使用递归使ANTLR使用所有可用元素?,java,antlr,antlr4,Java,Antlr,Antlr4,这是我的语法: grammar test; text: foo EOF; foo: 'X' | '(' foo ')' | foo '!' | foo tail ; tail: (' ' foo)+; 这是它完美解析的输入: X (X! (X)! (X X X)!!!) X 但是,正如我前面解释的,输出树有太多的tail元素。有可能解决这个问题吗?多亏了@kaby76,我们找到了解决方案:

这是我的语法:

grammar test;

text: foo EOF;

foo:
    'X'
    |
    '('
    foo
    ')'
    |
    foo
    '!'
    |
    foo
    tail
    ;

tail: (' ' foo)+;
这是它完美解析的输入:

X (X! (X)! (X X X)!!!) X

但是,正如我前面解释的,输出树有太多的
tail
元素。有可能解决这个问题吗?

多亏了@kaby76,我们找到了解决方案:

foo:  
  'X' tail? 
  | 
  '(' foo ')' tail? 
  | 
  foo '!' tail? 
  ; 
tail: 
  (
    ' ' 'X' 
    | 
    ' ' '(' foo ')' 
    | 
    ' ' foo '!'
  )+ 
  ;

当然,但是您必须假设
tail
出现在哪里。e、 从根开始,深度=1:
foo:'X'尾;尾:('foo2)+;foo2:‘X’|’(‘foo3’)‘foo2’!’;foo3:'X'('foo3)*|'('foo3')'| foo3'。或者,您可以从原始的
foo
规则开始,添加alt
|(''foo)+
,并添加语义谓词以仅选择一次
tail
。然而,它依赖于语言,可能需要一些调整。为什么这是一个问题呢?有了监听器,你甚至看不到深层嵌套。如果你能看到自己真正想要解决的问题,那就太好了。使用相当复杂的语言,篡改语法以获得特定的输出不会很好。@Mike在听众中,我看到太多的
tail
,这对于我的商业案例是错误的。对于
xx
输入,我需要看到一个
foo
和一个
tail
实例,其中
tail
包含两个
foo
。有意义吗?我想你要找的是
foo:'X'尾?|'(‘foo’)‘tail?|福尾巴;尾巴:('X'|'('foo')'|'foo'!')+通过重做语法获得,使“tail”特殊,然后进行多次重构以删除间接左递归。但是,您可能会回答“它仍然有太多的尾巴”。这个问题差不多被问了三次。我们只是不知道“太多尾巴”是什么意思。画出你想要的树,然后从中写出语法,或者在你需要的树中写一个树到树的转换器。@yegor256--很高兴它能工作。但让我们把它留在这里。我很少把任何东西作为“答案”发表,因为我不希望人们修改我的文章。5分钟后的评论不能修改,我不能!如果有人不同意,只需继续使用“评论”线程,并说我弄错了。这是我不喜欢堆栈溢出的一点。