树重写语法中的ANTLR3语义谓词
本文关键字:ANTLR3 语义 谓词 重写 语法 | 更新日期: 2023-09-27 18:28:33
我正在创建一个解析器,它创建一个AST,然后重写它以解决所有歧义,然后遍历它并计算结果。
重写的一部分是根据ID
所代表的变量的类型将类似^(QUERY ID)
的节点转换为^(DECIMALQUERY ID)
或^(DATEQUERY ID)
。
query
: ^(QUERY ID)
{
var type = GetQueryType($ID.text);
}
-> { type == QueryType.Decimal }? ^(DECIMALQUERY ID)
-> { type == QueryType.Date }? ^(DATEQUERY ID)
-> { type == QueryType.String }? ^(STRINGQUERY ID)
;
也就是说,基于type
值,QUERY
令牌被转换为DECIMALQUERY
、DATEQUERY
或STRINGQUERY
。
问题是ANTLR拒绝为该语法生成代码。命令是:
java -jar ..'..'binaries'antlr-3.4-complete.jar -message-format vs2005 .'TreeTransform.g
错误:
.'TreeTransform.g(54,2) : error 100 : syntax error: antlr: MismatchedTokenException(52!=84)
.'TreeTransform.g(53,52) : error 100 : syntax error: assign.types: NoViableAltException(0@[])
org'antlr'grammar'v3'DefineGrammarItemsWalker.g: node from line 53:51 no viable alternative at input ')'
.'TreeTransform.g(53,52) : error 100 : syntax error: buildnfa: NoViableAltException(0@[])
.'TreeTransform.g(53,52) : error 100 : syntax error: codegen: NoViableAltException(0@[])
.'TreeTransform.g(53,52) : error 100 : syntax error: antlr.print: NoViableAltException(0@[])
.'TreeTransform.g(53,52) : error 100 : syntax error: antlr.print: NoViableAltException(0@[])
但当我删除最后一个语义谓词时,一切都正常:
query
: ^(QUERY ID)
{
var type = GetQueryType($ID.text);
}
-> { type == QueryType.Decimal }? ^(DECIMALQUERY ID)
-> { type == QueryType.Date }? ^(DATEQUERY ID)
-> ^(STRINGQUERY ID)
;
但我不喜欢string
类型是"默认"分支的想法。如果三个谓词都不为true,我宁愿有一个例外(即,一个新类型被添加到枚举中,但没有添加到语法中;如果我删除最后一个谓词,它将仍然返回字符串)。
所以,我的问题是:
如何明确指定这种基于类型的切换的所有情况?如果三个备选方案都没有得到满足,有没有办法强制例外?
完整的解析器和树转换器语法如下:
https://bitbucket.org/ik/public/src/8f91e683e79a084138d6b55beabf8d5e18d965d4/AntlrSemanticPredicatesProblem?at=default
为了最大限度地支持正常的错误消息,您应该使用以下内容:
-> { type == QueryType.Decimal }? ^(DECIMALQUERY[$QUERY] ID)
-> { type == QueryType.Date }? ^(DATEQUERY[$QUERY] ID)
-> { type == QueryType.String }? ^(STRINGQUERY[$QUERY] ID)
-> ^(INVALIDQUERY[$QUERY] ID)
然后,您可以报告INVALIDQUERY
出现在树中的情况,而不会导致解析器失败。
PS:我添加的[$QUERY]
参数确保了标记行/列信息保留在重写的树中。