我已经为C风格的编程语言编写了ANTLR 4语法,并且正试图改善缺少分隔符的错误消息,例如缺少逗号或函数参数列表中的右括号。
我认为ANTLR的单令牌插入机制可以准确地检测到丢失的令牌,但是相反,我经常会遇到“无可行选择”错误。这是一个示例:
root
: expr+ EOF
;
expr
: '(' expr ')'
| '(' ')' '->' expr
| ID
;
ID: [a-zA-Z0-9$_]+;
Whitespace
: [ \t\r\n\f]+ -> skip
;
解析输入( -> foo
会导致:
line 1:2 no viable alternative at input '(->'
相反,我想看看missing ')'
。建议采用什么方法来实现这一目标?
到目前为止,我找到的唯一可行的解决方案是使所有定界符在语法中都是可选的,并根据访问者缺席的情况采取措施。 但是,这感觉像是一种解决方法,并且有很多我想避免的缺点。
答案 0 :(得分:0)
首先要注意的是,如果删除'(' expr ')'
规则,您将得到几乎完全想要的错误消息:
expr
: '(' ')' '->' expr
| ID
;
错误消息:
line 1:2 missing ')' at '->'
line 1:4 mismatched input '<EOF>' expecting {'(', ID}
我相信对于LL(1)语法和no viable alternative
,当在当前位置或类似位置需要提前查找时,会出现诸如“输入X不匹配,期望Y”和“缺少X”之类的错误。
因此请记住,我们可以尝试将您的语法重写为LL(1):
expr
: '(' ( expr ')' | ')' '->' expr )
| ID
;
然后错误消息变为:
line 1:2 mismatched input '->' expecting {'(', ')', ID}
这与您想要的非常接近。