gpt4 book ai didi

java - 如何简化 token 预测 DFA?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:11:00 24 4
gpt4 key购买 nike

词法分析器 DFA 导致“代码太大”错误

我正在尝试使用 ANTLR 3 解析 Java 服务器页面。

Java 对单个方法的字节码有64k 的限制,我在编译ANTLR 生成的Java 源代码时一直遇到“code too large”的错误。

在某些情况下,我已经能够通过破坏我的词法分析器来修复它。例如,JSP 使用 XML“名称”标记,它可以包含多种字符。我决定在我的“名称” token 中只接受 ASCII 字符,这极大地简化了一些测试,词法分析器允许它编译。<​​/p>

然而,我已经到了无法再偷工减料的地步,但 DFA 仍然太复杂。

我该怎么办?

是否存在导致复杂 DFA 的常见错误?

有没有办法抑制 DFA 的生成,也许是依靠语义谓词或固定前瞻来帮助预测?

手动编写这个词法分析器很容易,但在我放弃 ANTLR 之前,我想确保我没有忽略一些明显的东西。

背景

ANTLR 3 词法分析器使用 DFA 来决定如何标记输入。在生成的 DFA 中,有一个名为 specialStateTransition() 的方法。此方法包含一个 switch 语句,其中包含 DFA 中每个状态的 case。在每种情况下,都有一系列 if 语句,每个语句对应状态的每个转换。每个 if 语句的条件测试输入字符以查看它是否匹配转换。

这些字符测试条件可能非常复杂。它们通常具有以下形式:

int ch = … ; /* "ch" is the next character in the input stream. */
switch(s) { /* "s" is the current state. */

case 13 :
if ((('a' <= ch) && (ch <= 'z')) || (('A' <= ch) && (ch <= 'Z')) || … )
s = 24; /* If the character matches, move to the next state. */
else if …

对我的词法分析器的一个看似微小的更改可能会导致对单个转换、每个状态的多个转换以及多个状态进行数十次比较。我认为由于我的语义谓词,某些正在考虑的状态是不可能达到的,但 DFA 似乎忽略了语义谓词。 (虽然我可能会误读 - 这段代码绝对不是我能够手写的!)

我在 Jsp2x 工具中找到了一个 ANTLR 2 语法,但我对它的解析树不满意,我想刷新我的 ANTLR 技能,所以我想我会尝试编写自己的语法。我正在使用 ANTLRWorks,我尝试为 DFA 生成图表,但 ANTLRWorks 中似乎存在阻止它的错误。

最佳答案

不幸的是,非常大的语法(许多不同的标记)有这个问题(SQL 语法也有这个问题)。

有时这可以通过制定某些词法分析器规则片段来解决按照您已经尝试过的方式,我怀疑您的情况会有所收获。但是,如果您愿意在 SO 上发布您的词法分析器语法,我或其他人可能会看到可以更改的内容。

通常,通过将词法分析器语法拆分为 2 个或更多单独的词法分析器语法,然后将它们导入一个“主”语法来解决此问题。在 ANTLR 术语中,这些称为复合语法。请参阅有关它们的 ANTLR Wiki 页面:http://www.antlr.org/wiki/display/ANTLR3/Composite+Grammars

编辑

正如 @Gunther 在 OP 下方的评论中正确提到的那样,请参阅问答:Why my antlr lexer java class is "code too large"?一个小的变化(删除某个谓词)导致这个“代码太大”错误消失。

关于java - 如何简化 token 预测 DFA?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7517438/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com