如何在ANTLR4中实现错误处理 [英] How to implement error handling in ANTLR4

查看:33
本文介绍了如何在ANTLR4中实现错误处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下语法来解析应用于图形的一阶逻辑公式:

I have the following grammar for parsing first-order logic formulas applied over graphs:

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 ;

我相信这是我的语法的最终版本,所以现在我想为输入指定一些错误处理.问题是我不知道怎么做.我所知道的是,在解析输入后,我可以遍历生成的 AST,这是添加错误处理的地方.

I believe that this is the final version of my grammar so now I want to specify some error handling for the input. The problem is that I don't know how. What I know is that after I parse the input I can iterate over the generated AST and this is the place to add the error handling.

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

If the parse fails, return the parse exception; otherwise, I have specified the following cases for returning error message.

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

  1. There can't be 1 quantifier followed by -> condition (this is a formula element) where condition is equal to atom=atom. In other words, if there is only quantifier then condition should be equal to atom EQUALS assignment.

如果有 2 个量词,第一个应该以 FOREACH

If there are 2 quantifiers the first should start with FOREACH

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

The variable(s) in the quantifiers should be used in the condition statement

表达式左侧的量词不能超过两个(因为在我开发的应用程序中只有两个图形).因此,如果量词的数量更多,则也会返回两个错误

There can't be more than two quantifiers on the left hand-side of the expression (because in the app I am developing there are only two graphs). So if the number of quantifiers is greater then two return error as well

如果有 2 个量词,那么它们应该绑定不同的变量

If there are 2 quantifiers then they should have different variables bound on them

例如,当我们将输入作为输入时,应该引发第一种情况

For example, the first case should be raised when as an input we have

Exists node in GraphA -> node.color = node1.color 

因为 node1 未在表达式的左侧指定.

because node1 isn't specified in the left hand-side of the expression.

第二种情况的一个例子是以下输入

An example for the second case would be the following input

Exists node in GraphA Exists node1 in GraphB -> node.color = node1.color

所以我的问题是我是否必须对生成的解析树执行所有错误检查,或者我可以使用一些 java 代码在语法中指定其中的一些错误.如果在解析输入后发生错误处理,我可以使用 ANTLR 4 的哪些功能来实现错误情况?任何帮助或建议将不胜感激!

So my question is do I have to implement all the error checking over the generated parse tree or I can specify some of it in the grammar using some java code. If the error handling should happen after the input is parsed what functionality of ANTLR 4 can I use in order to implement the error cases? Any help or advice would be much appreciated!

推荐答案

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

You'll probably want to implement these semantic checks in a listener, in combination with helper visitors. Here are some examples.

实施:

  1. 创建一个访问者,返回指定解析树节点使用的变量.你会想要覆盖 defaultResult()aggregateResult(T, T) 为你做大部分工作,然后覆盖visitNodevvisitEdgev 来处理正在使用的特定变量.
  2. 在您的侦听器中,覆盖 enterFormula 方法.在此方法中,如果 ctx.quantifier() 不为 null,则使用访问者获取 ctx.quantifier() 中声明的变量列表和变量列表在 ctx.formula() 中使用.
  3. 根据两个结果酌情报告错误.
  1. Create a visitor that returns the variables used by a specified parse tree node. You'll want to override defaultResult() and aggregateResult(T, T) to do most of the work for you, and then override visitNodev and visitEdgev to handle the specific variables in use.
  2. In your listener, override the enterFormula method. In this method, if ctx.quantifier() is not null, then use your visitor to get the list of variables declared in ctx.quantifier() and the list of variables used in ctx.formula().
  3. Report an error as appropriate based on the two results.

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

实施:

  1. 从上一个规则实施的第 1 步中描述的访问者开始.
  2. 在您的侦听器中,覆盖 enterFormula 方法.方法中,如果ctx.quantifier()不为null,则需要获取ctx返回的树下所有其他QuantifierContext实例的集合.formula().您可以通过调用 XPath.findAll(ctx.formula(), "//quantifier",解析器).
  3. 使用上述访问者收集在每个链接的 QuantifierContext 实例中声明的变量列表.如果任何集合重叠,请酌情报告错误.
  1. Start with the visitor described in step 1 of the previous rule implementation.
  2. In your listener, override the enterFormula method. In the method, if ctx.quantifier() is not null, then you need to get a collection of all the other QuantifierContext instances underneath the tree returned by ctx.formula(). You can do this by calling XPath.findAll(ctx.formula(), "//quantifier", parser).
  3. Use the visitor described above to gather a list of variables declared in each of the linked QuantifierContext instances. If any of the sets overlap, report an error as appropriate.

规则:如果有 2 个量词,第一个应该以 FOREACH

开头

实施:

Rule: If there are 2 quantifiers the first should start with FOREACH

Implementation:

使用上一步中描述的侦听器模式来定位公式包含多个量词的情况.如果这些公式中的第一个具有 ctx.quantifier().FOREACH() == null 则适当地发出错误.

Use the listener pattern described in the previous step to locate cases where a formula contains more than one quantifier. If the first of these formulas has ctx.quantifier().FOREACH() == null emit an error as appropriate.

实施:

更新上面第二条规则的实现,如果XPath.findAllformula中返回多个QuantifierContext,则报错量词.

Update the implementation of the 2nd rule above to report an error if XPath.findAll returns more than one QuantifierContext in the formula for a quantifier.

实施:

首先,创建一个ParseTreePattern 对象.

First, create a ParseTreePattern object.

String patternString = "<quantifier> -> <condition>";
ParseTreePattern pattern =
    parser.compileParseTreePattern(patternString, GraphParser.RULE_formula);

然后,在您的解析树中找到此模式的所有实例.

Then, find all instances of this pattern in your parse tree.

List<ParseTreeMatch> matches = pattern.findAll(tree, "//formula");

验证匹配就相当简单了.

Validating the matches is then rather simple.

for (ParseTreeMatch match : matches) {
  ConditionContext condition = (ConditionContext)match.get("condition");
  if (condition.assignment() == null) {
    // TODO: report error here
  }
}

这篇关于如何在ANTLR4中实现错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆