Wos*_*osh 6 java error-handling antlr4
我有以下语法来解析应用于图形的一阶逻辑公式:
grammar Graph;
/*------------------------------------------------------------------
* PARSER RULES
*------------------------------------------------------------------*/
input
:
formula EOF
;
formula
:
TRUE
| FALSE
| formula AND formula
| formula OR formula
| quantifier formula
| ST condition
;
condition
:
atom EQUALS QUOTE? (assignment | atom) QUOTE?
;
quantifier
:
(FOREACH | EXISTS) variable IN domain
;
domain
:
(GRAPH_A | GRAPH_B)
;
atom
:
variable DOT property
;
variable
:
(nodev | edgev)
;
nodev
:
(NODE | NODE1)
;
edgev
:
(EDGE | EDGE1)
;
property
:
(COLOR | VALUE)
;
assignment
:
(COLORTYPE | NUMBER)
;
/*------------------------------------------------------------------
* LEXER RULES
*------------------------------------------------------------------*/
TRUE : 'True' ;
FALSE : 'False' ;
AND : '&' ;
OR : '|' ;
ST : '->' ;
EXISTS : 'Exists' ;
FOREACH : 'Foreach' ;
NODE : 'node' ;
NODE1 : 'node1' ;
EDGE : 'edge' ;
EDGE1 : 'edge1' ;
IN : 'in' ;
GRAPH_A : 'GraphA' ;
GRAPH_B : 'GraphB' ;
EQUALS : '=' ;
DOT : '.' ;
COLOR : 'color' ;
VALUE : 'value' ;
NUMBER : ('0'..'9')+ (DOT ('0'..'9')+)? ;
QUOTE : '\'' ;
COLORTYPE : ('a'..'z')+ ;
WS : [ \t\r\n]+ -> skip ;
Run Code Online (Sandbox Code Playgroud)
我相信这是我的语法的最终版本,所以现在我想为输入指定一些错误处理.问题是我不知道怎么做.我所知道的是,在我解析输入后,我可以迭代生成的AST,这是添加错误处理的地方.
如果解析失败,则返回解析异常; 否则,我已指定以下情况返回错误消息.
-> condition在条件等于的情况下,不能有1个量词,后面跟着(这是一个公式元素)atom=atom.换句话说,如果只有quantifier那么condition应该等于atom EQUALS assignment.
如果有2个量词,则第一个应该从第一个开始 FOREACH
量词中的变量应该在condition语句中使用
表达式的左侧不能有两个以上的量词(因为在我开发的应用程序中,只有两个图形).因此,如果量词的数量大于那么两个返回错误
如果有2个量词,那么它们应该有不同的变量
例如,当我们作为输入时,应该提出第一种情况
Exists node in GraphA -> node.color = node1.color
Run Code Online (Sandbox Code Playgroud)
因为node1未在表达式的左侧指定.
第二种情况的一个例子是以下输入
Exists node in GraphA Exists node1 in GraphB -> node.color = node1.color
Run Code Online (Sandbox Code Playgroud)
所以我的问题是我是否必须在生成的解析树上实现所有错误检查,或者我可以使用一些java代码在语法中指定一些错误检查.如果在解析输入后发生错误处理,我可以使用ANTLR 4的哪些功能来实现错误情况?任何帮助或建议将不胜感激!
您可能希望在侦听器中与辅助访问者一起实现这些语义检查.这里有些例子.
quantifier应该使用的变量condition执行:
defaultResult()并aggregateResult(T, T)为您完成大部分工作,然后覆盖visitNodev并visitEdgev处理正在使用的特定变量.enterFormula方法.在此方法中,如果ctx.quantifier()不为null,则使用您的访问者获取声明ctx.quantifier()的变量列表和使用的变量列表ctx.formula().执行:
enterFormula方法.在该方法中,如果ctx.quantifier()不为null,则需要获取QuantifierContext返回的树下所有其他实例的集合ctx.formula().你可以通过电话来做到这一点XPath.findAll(ctx.formula(), "//quantifier", parser).QuantifierContext实例中声明的变量列表.如果任何集重叠,请根据需要报告错误.FOREACH执行:
使用上一步中描述的侦听器模式来查找公式包含多个的情况quantifier.如果这些公式中的第ctx.quantifier().FOREACH() == null一个在适当时发出错误.
执行:
更新上面第二条规则的实现,如果在for中XPath.findAll返回多个,则报告错误.QuantifierContextformulaquantifier
执行:
首先,创建一个ParseTreePattern对象.
String patternString = "<quantifier> -> <condition>";
ParseTreePattern pattern =
parser.compileParseTreePattern(patternString, GraphParser.RULE_formula);
Run Code Online (Sandbox Code Playgroud)
然后,在解析树中查找此模式的所有实例.
List<ParseTreeMatch> matches = pattern.findAll(tree, "//formula");
Run Code Online (Sandbox Code Playgroud)
验证匹配是相当简单的.
for (ParseTreeMatch match : matches) {
ConditionContext condition = (ConditionContext)match.get("condition");
if (condition.assignment() == null) {
// TODO: report error here
}
}
Run Code Online (Sandbox Code Playgroud)