【发布时间】:2019-06-11 15:47:22
【问题描述】:
我正在尝试创建自己的 ANTLR4 语法,以便可以解析一些表达式,例如:
STARTS_WITH(this.sequence, "startSeq")
ENDS_WITH("sequenceToTest", "endSeq")
(我混合了常量和变量作为函数参数)。
已经创建了 Lexer 和 Parser 规则,但是当我尝试显示函数 ToStringTree 时,似乎以错误的方式解析了树。
我正在使用 Antlr 4 和 ASP.Net Core 2.1。
语法文件:
grammar expression;
expression : bool_function (OPERATOR bool_function)* ;
bool_function : (FUNCTION_NAME PAR_OPEN parameter (COMMA parameter)* PAR_CLOSE) ;
parameter : constant | current_object_field ;
constant : DOUBLE_QUOTE ANY_BUT_DOUBLE_QUOTE DOUBLE_QUOTE ;
current_object_field : THIS ALPHANUM ;
WHITESPACE : (' ' | '\t' | '\n' |'\r' )+ -> skip ;
COMPARATOR : ('==' | '<=' | '>=' | '<>') ;
OPERATOR : ('&&' | '||') ;
PAR_OPEN : '(' ;
PAR_CLOSE : ')' ;
COMMA : ',' ;
DOLLAR : '$' ;
DOUBLE_QUOTE : '"' ;
THIS : 'this.' ;
NUMBER : [0-9]+ ;
ALPHANUM : [a-zA-Z_0-9]+ ;
ANY_BUT_DOUBLE_QUOTE : ~('"')+ ;
FUNCTION_NAME : ('STARTS_WITH' | 'ENDS_WITH' | 'CONTAINS' | 'EQUALS') ;
单元测试,尝试解析一个基本表达式:
try
{
expressionParser expressionParser = Setup("STARTS_WITH(this.sequence, \"startSeq\")");
expressionParser.ExpressionContext expressionContext = expressionParser.expression();
var a = expressionContext.ToStringTree(expressionParser);
}
catch (Exception e)
{
var a = e.Message;
throw;
}
我通过 ToStringTree 解析我的表达式时收到的输出如下:
(expression (bool_function STARTS_WITH(this.sequence, " startSeq " )))
但我希望有一个更深入的结果,例如:
(expression (bool_function STARTS_WITH((parameter(current_objet_field this.sequence)),(parameter(constant "startSeq")))))
我定义 Lexer/Parser 的方式有什么明显的错误吗?
【问题讨论】:
-
您是否遇到任何语法错误?
-
不,我在执行这段代码时没有任何语法错误:-(
-
当我刚刚在您的输入上测试您的语法时,我收到错误“第 1:0 行不匹配的输入 'STARTS_WITH(this.sequence, ' Expecting FUNCTION_NAME”。所以我相信您确实收到了错误,但你没有看到它。你运行你的应用程序的方式是否可以看到它的 stderr 输出?如果没有,你应该添加你自己的错误处理程序,它会以你会注意到的方式通知你错误。
-
感谢您的帮助,我已经添加了我在测试期间使用的 try catch(没有抛出异常)我在我的 ANTLR 单元测试中遗漏了什么吗?
-
默认错误监听器不会抛出异常 - 它只是将错误打印到 stderr 并继续解析(返回一棵树,其中某些字段可能是
null,当它们无法正确解析时)。您可以使用parser.NumberOfSyntaxErrors检查是否有错误(以及有多少错误)。对于测试,我建议使用一个错误侦听器,它收集一组中的所有错误消息,然后检查您是否收到了正确数量的错误以及正确的消息(对于应该产生错误的输入)。