Lexer DFA приводит к ошибке "слишком большой код"
Я пытаюсь разобрать страницы сервера Java с помощью ANTLR 3.
Java имеет ограничение в 64 КБ для байтового кода одного метода, и я продолжаю сталкиваться с ошибкой «слишком большой код» при компиляции исходного кода Java, созданного ANTLR.
В некоторых случаях мне удавалось исправить это, скомпрометировав лексер. Например, JSP использует токен XML «Name», который может включать в себя широкий спектр символов. Я решил принимать только символы ASCII в моем токене «Name», что значительно упростило некоторые тесты в лексере и позволило ему скомпилировать.
Однако я дошел до того, что больше не могу срезать углы, но 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 есть ошибки, которые мешают этому.
specialStateTransition
. - person Gunther   schedule 22.09.2011