有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用ANTLR构建交互式解析器?

我一直在研究Java和ANTRL4,这是构建解析器的一个非常好的组合。然而,当我测试它们时,我注意到解析直到我向输入发送EOF(例如Mac上的CMD-D)才开始。这对于解析文件来说很好,但我可以很容易地想象使用ANTLR快速构建命令行shell/处理器等工具。但这是不可行的,除非我能让它在键入字符时进行解析(这样,事情就发生在返回之后,或者如果想完成命令,甚至在一个选项卡之后)

有人知道怎么做吗


共 (1) 个答案

  1. # 1 楼答案

    “交互式”使用Antlr4的最简单方法是认识到解析操作相当快,并且在温暖的VM中,重新实例化解析器也相当快。实际上,它的速度远远超过了在每次击键之间重新解析整个输入文本的速度

    基本策略是,从一个关键事件抓取整个当前输入文本,并在非显示线程中处理它。如果处理没有在下一个键事件之前完成,则丢弃处理线程并启动一个新线程。当处理迭代完成时,将下一个键事件设置为buffer(根据需要),并将结果应用于输入文本

    持续的击键流不太可能超过每个按键事件100毫秒(约每分钟80次)。在我的系统中,使用Java语言对编辑器的代码“页面”进行重复的简单解析。g4语法平均5毫秒左右。即使有相当重要的处理,后台线程也很少需要超过25毫秒才能完成。当然,YMWV

    更新

    如果需要的是连续流处理而不是“交互式”,那么Antlr可以适应这个目的。这将需要满足lexer&;TokenStream接口,但等待实际输入数据,以响应解析器的getCurrentToken()解析器的主要函数,从lexer获取下一个令牌

        StreamLexer tokens = new StreamLexer(yourInputStream); // custom lexer
        YourParser parser = new YourParser(tokens);
        parser.removeErrorListeners(); // remove ConsoleErrorListener
        parser.addErrorListener(new YourErrorListener());
        parser.setErrorHandler(new YourParserErrorStrategy());
        parser.start();
    

    没有实际的lexer语法,自定义lexer只是将每个输入字符包装为一个单独的标记,并相应地编写解析器规则

    实际上,这将标准的Antlr解析器转变为语法定义的“推式解析器”。速度将受限于解析器匹配函数的运行时间或输入流的数据速率,以较慢者为准

    为了获得更高的解析速度,可能需要专门构建的状态机