Antlr 处理异常

2024-05-09

我使用 Antlr 3 和 AST 树开发了一个复杂的语法。 ANTLR 生成词法分析器和解析器。问题是,例如,当用户输入无效的语法时,该语法需要“;”。用户没有输入此内容,然后在我的 Eclipse IDE 中出现以下异常:

 line 1:24 mismatched input '<EOF>' expecting ';'

如何处理这个异常,因为我尝试捕获这个异常,但是异常没有被捕获。这是一个例外吗?我似乎不明白为什么这个异常没有被捕获。我试图找出答案,但 Antlr 网站似乎已经关闭了一段时间了。

我查看了以下内容:ANTLR 异常处理与“$”,Java https://stackoverflow.com/questions/7705845/antlr-exception-handling-with-java并遵循该示例,但是当 Lexer 通过添加 RuntimeException() 生成代码时,我得到无法访问的代码。

我不知道该怎么办。

当我尝试从解析器获取语法错误数时,它显示 0。

EDIT:

我找到了一个可行的解决方案:ANTLR 不会在无效输入时抛出错误 https://stackoverflow.com/questions/8658753/antlr-not-throwing-errors-on-invalid-input

但是,当我尝试取回异常消息时,它为空。我是否已正确设置所有内容?请参阅示例语法:

grammar i;

options {
output=AST;
}

@header {
package com.data;
}

@rulecatch {
    catch(RecognitionException e) {
        throw e;
   }
}

// by having these below it makes no difference
/**@parser::members {
    @Override
    public void reportError(RecognitionException e) {
        throw new RuntimeException("Exception : " + " " + e.getMessage());
    }
}

@lexer::members {
    @Override
    public void reportError(RecognitionException e) {
       throw new RuntimeException("Exception : " + " " + e.getMessage());
    }
}*/

EDIT:

请看看我到目前为止所拥有的:

grammar i;

options {
output=AST;
}

@header {
package com.data;
}

@rulecatch {
    // ANTLR does not generate its normal rule try/catch
    catch(RecognitionException e) {
        throw e;
    }
}

@parser::members {
    @Override
    public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
        String hdr = getErrorHeader(e);
        String msg = getErrorMessage(e, tokenNames);
        throw new RuntimeException(hdr + ":" + msg);
    }
}

@lexer::members {
    @Override
    public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
        String hdr = getErrorHeader(e);
        String msg = getErrorMessage(e, tokenNames);
        throw new RuntimeException(hdr + ":" + msg);
    }
}

operatorLogic   : 'AND' | 'OR';
value       : STRING;
query       : (select)*;
select      : 'SELECT'^ functions 'FROM table' filters?';';
operator    : '=' | '!=' | '<' | '>' | '<=' | '>=';
filters : 'WHERE'^ conditions;
members : STRING operator value;
conditions  : (members (operatorLogic members)*);
functions   : '*';
STRING  : ('a'..'z'|'A'..'Z')+;
WS      : (' '|'\t'|'\f'|'\n'|'\r')+ {skip();}; // handle white space between keywords

public class Processor {

public Processor() {

}

/**
 * This method builds the MQL Parser.
 * @param args the args.
 * @return the built IParser.
 */
private IParser buildMQLParser(String query) {
    CharStream cs = new ANTLRStringStream(query);
    // the input needs to be lexed
    ILexer lexer = new ILexer(cs);
          CommonTokenStream tokens = new CommonTokenStream();
    IParser parser = new IParser(tokens);
    tokens.setTokenSource(lexer);
    // use the ASTTreeAdaptor so that the grammar is aware to build tree in AST format
    parser.setTreeAdaptor((TreeAdaptor) new ASTTreeAdaptor().getASTTreeAdaptor());
return parser;
}

/**
 * This method parses the MQL query.
 * @param query the query.
 */
public void parseMQL(String query) {
    IParser parser = buildMQLParser(query);
    CommonTree commonTree = null;
    try {
                     commonTree = (CommonTree) parser.query().getTree();
                    }
    catch(Exception e) {
        System.out.println("Exception :" + " " + e.getMessage());
    }
}
}

public class ASTTreeAdaptor {

public ASTTreeAdaptor() {

}

/**
 * This method is used to create a TreeAdaptor.
 * @return a treeAdaptor.
 */
public Object getASTTreeAdaptor() {
    TreeAdaptor treeAdaptor = new CommonTreeAdaptor() {
        public Object create(Token payload) {
        return new CommonTree(payload);
        }
    };
    return treeAdaptor; 
}
}

所以当我输入以下内容时: 从表中选择 *

没有 ';'我得到 MismatchedTokenException:

catch(Exception e) {
     System.out.println("Exception : " + " " e);
}

当我尝试时:

e.getMessage();

它返回 null。


尝试覆盖displayRecognitionError反而:

@parser::members { 
   ...

    @Override    
    public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
        String hdr = getErrorHeader(e);
        String msg = getErrorMessage(e, tokenNames);
        throw new RuntimeException(hdr + ":" + msg);
    }
    ...
}
//same code in @lexer::members

如果您想跟踪错误而不是中止,您可以创建一个处理程序接口来跟踪它们:

@parser::members { 
   ...
    private YourErrorTrackerInterface errorTracker;

    //getter/setter for errorTracker here        

    @Override    
    public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
        String hdr = getErrorHeader(e);
        String msg = getErrorMessage(e, tokenNames);
        if (errorTracker != null){
          errorTracker.addError(e, tokenNames, hdr, msg);
        }
    }
    ...
}
//same code in @lexer::members

然后错误跟踪器可以决定是抛出异常还是继续。


上面的代码允许您跟踪“可恢复”错误,ANTLR 可以跳过的错误。仍然有一些场景会产生不可恢复的错误,例如SELECT * FROM table(没有结局;)。在这种情况下,您必须捕获异常parseMQL或者那里附近的某个地方。 (您可以尝试编写自己的恢复代码,但我不建议您这样做。)

这是修改后的parseMQL显示两种不同类型的解析错误。请注意,我删除了对getMessage因为并非所有异常都源自RecognitionException填入。

public void parseMQL(String query) {
    iParser parser = buildMQLParser(query);
    CommonTree commonTree = null;
    try {
        commonTree = (CommonTree) parser.query().getTree();
    } catch (MismatchedTokenException e){
        //not production-quality code, just forming a useful message
        String expected = e.expecting == -1 ? "<EOF>" : iParser.tokenNames[e.expecting];
        String found = e.getUnexpectedType() == -1 ? "<EOF>" : iParser.tokenNames[e.getUnexpectedType()];

        System.out.println("Fatal mismatched token exception: expected " + expected + " but was " + found);   

    } catch (RecognitionException e) {
        System.out.println("Fatal recognition exception " + e.getClass().getName()
                + " : " + e);

    } catch (Exception e) {
        System.out.println("Other exception : " + e.getMessage());
    }
}

Input SELECT * FROM table产生消息“致命的不匹配令牌异常:预期';'但是”。这个异常是由ANTLR直接产生的。

Input SELECT FROM table;生成消息“其他异常:第 1:7 行:'FROM table' 处缺少 '*'”。这个异常是由上面的代码产生的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Antlr 处理异常 的相关文章

  • 如何使用 Java 中的 Web 服务(例如 Axis2)发送复杂对象的数组或集合?

    我对 SOAP Web 服务还比较陌生 虽然我完成了一些较小的 Web 服务项目 但我偶然从来不需要返回 或用作参数 复杂 对象的数组或集合 当我尝试这样做时 根据我的 SOAP 绑定风格 我会得到不同的奇怪行为 当我使用RPC 文字 我可
  • org.apache.sling.api.resource,version=[2.3,3) -- 无法解析

    您好 我无法访问我的项目内容 我已经上传了从 CQ 访问内容所需的所有包 我唯一能看到的是 org apache sling api resource version 2 3 3 无法解析 这是否是异常的原因 如果是 请告诉我如何解决 中Q
  • OpenCV 中的 Gabor 内核参数

    我必须在我的应用程序中使用 Gabor 过滤器 但我不知道这个 OpenCV 方法参数值 我想对虹膜进行编码 启动 Gabor 过滤器并获取特征 我想对 12 组 Gabor 参数值执行此操作 然后我想计算 Hamming Dystans
  • Android在排序列表时忽略大小写

    我有一个名为路径的列表 我目前正在使用以下代码对字符串进行排序 java util Collections sort path 这工作正常 它对我的 列表进行排序 但是它以不同的方式处理第一个字母的情况 即它用大写字母对列表进行排序 然后用
  • OSGi:如果不取消服务会发生什么

    这是我获取 OSGi 服务的方式 ServiceReference reference bundleContext getServiceReference Foo class getName Foo foo Foo bundleContex
  • 我需要什么库才能在 Java 中访问这个 com.sun.image.codec.jpeg?

    我正在用java创建一个图像水印程序 并导入了以下内容 import com sun image codec jpeg JPEGCodec import com sun image codec jpeg JPEGEncodeParam im
  • 将 SignedHash 插入 PDF 中以进行外部签名过程 -workingSample

    遵循电子书第 4 3 3 节 PDF 文档的数字签名 https jira nuxeo com secure attachment 49931 digitalsignatures20130304 pdf 我正在尝试创建一个工作示例 其中 客
  • 以编程方式在java的resources/source文件夹中创建文件?

    我有两个资源文件夹 src 这是我的 java 文件 资源 这是我的资源文件 图像 properties 组织在文件夹 包 中 有没有办法以编程方式在该资源文件夹中添加另一个 properties 文件 我尝试过这样的事情 public s
  • 如何在 Java 中测试一个类是否正确实现了 Serialized(不仅仅是 Serialized 的实例)

    我正在实现一个可序列化的类 因此它是一个与 RMI 一起使用的值对象 但我需要测试一下 有没有办法轻松做到这一点 澄清 我正在实现该类 因此在类定义中添加 Serialized 很简单 我需要手动序列化 反序列化它以查看它是否有效 我找到了
  • Javafx过滤表视图

    我正在尝试使用文本字段来过滤表视图 我想要一个文本字段 txtSearch 来搜索 nhs 号码 名字 姓氏 和 分类类别 我尝试过在线实施各种解决方案 但没有运气 我对这一切仍然很陌生 所以如果问得不好 我深表歉意 任何帮助将不胜感激 我
  • 如何知道抛出了哪个异常

    我正在对我们的代码库进行审查 有很多这样的陈述 try doSomething catch Exception e 但我想要一种方法来知道 doSomething 抛出了哪个异常 在 doSomething 的实现中没有 throw 语句
  • Netty:阻止调用以获取连接的服务器通道?

    呼吁ServerBootstrap bind 返回一个Channel但这不是在Connected状态 因此不能用于写入客户端 Netty 文档中的所有示例都显示写入Channel从它的ChannelHandler的事件如channelCon
  • Cucumber Java 与 Spring Boot 集成 - Spring @Autowired 抛出 NullPointer 异常

    我正在为 Spring boot 应用程序编写 cucumber java 单元测试来测试每个功能 当我与 Spring Boot 集成时 Autowired 类抛出 NullPointer 异常 Spring Boot应用程序类 Spri
  • 游戏内的java.awt.Robot?

    我正在尝试使用下面的代码来模拟击键 当我打开记事本时 它工作正常 但当我打开我想使用它的游戏时 它没有执行任何操作 所以按键似乎不起作用 我尝试模拟鼠标移动和点击 这些动作确实有效 有谁知道如何解决这个问题 我发现这个问题 如何在游戏中使用
  • spring中如何使用jackson代替JdkSerializationRedisSerializer

    我在我的一个 Java 应用程序中使用 Redis 并且正在序列化要存储在 Redis 中的对象列表 但是 我注意到使用 RedisTemplate 会使用 JdkSerializationRedisSerializer 相反 我想使用 J
  • 为什么这个作业不起作用?

    我有课Results which extends ArrayList
  • ServletContainer 类未找到异常

    我无法再编译我的球衣项目 并且出现以下异常 GRAVE Servlet Project API threw load exception java lang ClassNotFoundException com sun jersey spi
  • 调整添加的绘制组件的大小和奇怪的摆动行为

    这个问题困扰了我好几天 我正在制作一个特殊的绘画程序 我制作了一个 JPanel 并添加了使用 Paint 方法绘制的自定义 jComponent 问题是 每当我调整窗口大小时 所有添加的组件都会 消失 或者只是不绘制 因此我最终会得到一个
  • Antlr 解析器运算符优先级

    考虑以下语法 我对运算符优先级有疑问 例如 res 2 a b有一个类似的解析树res 2 a b 我知道问题出在哪里 但我没有想到没有相互左递归的 漂亮 解决方案 你能帮我一点忙吗 该语法与自定义访问者一起使用 grammar Math
  • GUI Java 程序 - 绘图程序

    我一直试图找出我的代码有什么问题 这个想法是创建一个小的 Paint 程序并具有红色 绿色 蓝色和透明按钮 我拥有我能想到的让它工作的一切 但无法弄清楚代码有什么问题 该程序打开 然后立即关闭 import java awt import

随机推荐