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



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

有人知道怎么做吗?

"交互式"使用Antlr4的最简单方法是认识到解析操作非常快,并且在热VM中,重新实例化解析器也非常快。实际上,在每次击键之间重新解析整个输入文本要快得多。

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

持续的击键流不太可能超过每个键事件100ms(约80wpm)。在我的系统上,使用Java重复简单解析编辑器的代码页。G4语法平均在5毫秒左右。即使有相当重要的处理,后台线程也很少需要超过25ms的时间来完成。当然,YMWV。

如果需要连续流处理——而不是"交互"——那么Antlr可以适应这个目的。这将需要一个最小的自定义词法分析器,以满足词法分析器&TokenStream接口,但是等待实际输入数据来响应解析器的getCurrentToken()——解析器的主要功能是从词法分析器中获取下一个令牌。

    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();

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

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

为了显著提高解析速度,可能需要专门构建的状态机。

相关内容

  • 没有找到相关文章

最新更新