首页 > 解决方案 > 使递归 antlr4 规则变得贪婪

问题描述

我想要一个语法,其中 afilter可以是一个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

解决方案


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

你得到的输出结构是由你的语法决定的。filter如果您不想要一棵树,请不要制定递归规则。像这样反对编写过滤器的原因是:

filter:
    OPERATION (PIPE OPERATION)?

如果您绝对需要包含过滤器的过滤器,那么恐怕没有办法绕过像结果一样的树。


推荐阅读