Lexer DFA 导致“代码太大”错误
我正在尝试使用 ANTLR 3 解析 Java 服务器页面。
Java 对单个方法的字节码有 64k 的限制,在编译 ANTLR 生成的 Java 源代码时,我一直遇到“代码太大”错误。
在某些情况下,我可以通过破坏我的词法分析器来修复它。例如,JSP 使用 XML“名称”标记,它可以包含多种字符。我决定在我的“名称”标记中只接受 ASCII 字符,这极大地简化了一些测试,并且词法分析器允许它编译。
但是,我已经到了不能再偷工减料的地步了,但是 DFA 仍然太复杂了。
我该怎么办?
是否存在导致复杂 DFA 的常见错误?
有没有办法抑制 DFA 的生成,也许依靠语义谓词或固定的前瞻来帮助预测?
手工编写这个词法分析器很容易,但在我放弃 ANTLR 之前,我想确保我没有忽略一些明显的东西。
背景
ANTLR 3 词法分析器使用 DFA 来决定如何标记输入。在生成的 DFA 中,有一个方法叫做specialStateTransition()
. 此方法包含一个switch
语句,其中包含 DFA 中每个状态的案例。在每种情况下,都有一系列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 中似乎存在阻止它的错误。