Как я могу упростить DFA прогнозирования токенов?

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 есть ошибки, которые мешают этому.

6
задан erickson 22 September 2011 в 15:34
поделиться