如何在ANTLR4中实现错误处理

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,这是添加错误处理的地方.

如果解析失败,则返回解析异常; 否则,我已指定以下情况返回错误消息.

  1. -> condition在条件等于的情况下,不能有1个量词,后面跟着(这是一个公式元素)atom=atom.换句话说,如果只有quantifier那么condition应该等于atom EQUALS assignment.

  2. 如果有2个量词,则第一个应该从第一个开始 FOREACH

  3. 量词中的变量应该在condition语句中使用

  4. 表达式的左侧不能有两个以上的量词(因为在我开发的应用程序中,只有两个图形).因此,如果量词的数量大于那么两个返回错误

  5. 如果有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的哪些功能来实现错误情况?任何帮助或建议将不胜感激!

Sam*_*ell 6

您可能希望在侦听器中与辅助访问者一起实现这些语义检查.这里有些例子.

规则:quantifier应该使用的变量condition

执行:

  1. 创建一个访问者,该访问者返回指定的分析树节点使用的变量.您将要覆盖defaultResult()aggregateResult(T, T)为您完成大部分工作,然后覆盖visitNodevvisitEdgev处理正在使用的特定变量.
  2. 在您的侦听器中,覆盖该enterFormula方法.在此方法中,如果ctx.quantifier()不为null,则使用您的访问者获取声明ctx.quantifier()的变量列表和使用的变量列表ctx.formula().
  3. 根据两个结果报告适当的错误.

规则:如果有2个量词,那么它们应该有不同的变量

执行:

  1. 从上一个规则实现的步骤1中描述的访问者开始.
  2. 在您的侦听器中,覆盖该enterFormula方法.在该方法中,如果ctx.quantifier()不为null,则需要获取QuantifierContext返回的树下所有其他实例的集合ctx.formula().你可以通过电话来做到这一点XPath.findAll(ctx.formula(), "//quantifier", parser).
  3. 使用上述访问者收集每个链接QuantifierContext实例中声明的变量列表.如果任何集重叠,请根据需要报告错误.

规则:如果有2个量词,则第一个应该从第一个开始 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)