Lexer DFA приводит к ошибке «слишком большой код»
Я пытаюсь проанализировать страницы сервера Java с помощью ANTLR 3.
Java имеет ограничение 64 КБ для байтового кода одного метода, и я продолжаю сталкиваться с ошибкой «слишком большой код» при компиляции исходного кода Java, сгенерированного ANTLR.
В некоторых случаях я смог исправить это, скомпрометировав свой лексер. Например, 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. (Возможно, я что-то неправильно понимаю - этот код определенно не тот, который я мог бы написать вручную!)
Я нашел грамматику ANTLR 2 в инструменте Jsp2x, но меня не устраивает его дерево разбора, и я хочу обновить свои навыки ANTLR, поэтому я решил попробовать написать свои собственные. Я использую ANTLRWorks, и я попытался сгенерировать графики для DFA, но в ANTLRWorks, похоже, есть ошибки, которые этому препятствуют.