使递归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。。。什么样的解析规则使得层次结构的结果比平面结构的结果更受欢迎(假设这两种语法都允许)?天真地说,对我来说,“尽可能多地匹配”似乎更倾向于平坦的结果。啊,我想我看到了——在解析过滤器
规则时,解析器首先在规则定义中下降到过滤器
中的一个,并在那里尽可能多地匹配(同时确保顶级过滤器模式仍然可以匹配)。这就是想法吗?