使递归antlr4规则贪婪

使递归antlr4规则贪婪,antlr4,Antlr4,我想要一个语法,其中过滤器可以是操作或由|连接的任意数量的过滤器。我的语法是这样的: filter : filter ('|' filter)+ #pipedFilter | OPERATION #operation ; OPERATION : [a-z]+ ; (这是一个简化的示例,将有其他方法对过滤器进行分组,这些方法的优先级与管道不同) 在类似于xxx | yyy的输入中,这工作正常,我们得到: FILTER: [ OPERATION

我想要一个语法,其中
过滤器可以是
操作
或由
|
连接的任意数量的过滤器。我的语法是这样的:

filter
  : filter ('|' filter)+  #pipedFilter
  | OPERATION             #operation
  ;


OPERATION
  : [a-z]+
  ;
(这是一个简化的示例,将有其他方法对过滤器进行分组,这些方法的优先级与管道不同)

在类似于
xxx | yyy
的输入中,这工作正常,我们得到:

FILTER: [
  OPERATION: xxx,
  OPERATION: yyy
]
但是输入
xxx | yyy | zzz
我们得到:

FILTER: [
  OPERATION: xxx,
  FILTER: [
    OPERATION: yyy,
    OPERATION: zzz
  ]
]
我想

FILTER: [
  OPERATION: xxx,
  OPERATION: yyy,
  OPERATION: zzz
]

这两种解释似乎都是正确的,但我想要第二种。在我看来,问题在于
#pipedFilter
规则没有得到充分的应用。我的理解正确吗?解决办法是什么?

这与贪婪无关。ANTLR4中的默认值是在一个规则中尽可能多地匹配

您得到的输出结构由您的语法决定。如果您不需要树,请不要将
filter
设置为递归规则。是什么反对这样编写筛选器:

filter:
    OPERATION (PIPE OPERATION)?

如果您确实需要包含过滤器的过滤器,那么恐怕无法避免类似树的结果。

谢谢您的回答。“如果你不想要一棵树,就不要制定递归规则”是一个很有用的思考方法。我做了类似于您的建议,将不同的优先级运算符作为不同的规则,而不是试图将所有内容都放在一个规则中。ANTLR4中的默认设置是在一个规则中尽可能多地匹配。我仍然不明白为什么这条规则不会导致
过滤器
规则在单个
过滤器
中匹配尽可能多的管道
操作
s。。。什么样的解析规则使得层次结构的结果比平面结构的结果更受欢迎(假设这两种语法都允许)?天真地说,对我来说,“尽可能多地匹配”似乎更倾向于平坦的结果。啊,我想我看到了——在解析
过滤器
规则时,解析器首先在规则定义中下降到
过滤器
中的一个,并在那里尽可能多地匹配(同时确保顶级
过滤器
模式仍然可以匹配)。这就是想法吗?