Вручную выдать токен с помощью ANTLR - PullRequest
4 голосов
/ 12 января 2010

У меня небольшие проблемы с ручным выводом токена с правилом лексера в ANTLR. Я знаю, что необходимо использовать функцию emit (), но, похоже, по этому поводу явно отсутствует документация. У кого-нибудь есть хороший пример того, как это сделать?

Книга ANTLR дает хороший пример того, как вам нужно сделать это для анализа вложенности Python. Например, если вы видите определенное количество пробелов, превышающее пробел предыдущей строки, создайте токен INDENT, но если его меньше, используйте токен DEDENT. К сожалению, в книге скрыт фактический синтаксис, который требуется.

РЕДАКТИРОВАТЬ: Вот пример того, что я пытаюсь разобрать. Это вложенные цитаты Маркдауна:

before blockquote

> text1
>
> > text2
>
> text3

outside blockquote

Теперь мой подход состоит в том, чтобы по существу считать> символы на строку. Например, приведенное выше похоже на то, что оно должно выдавать (примерно ...) PARAGRAPH_START, CDATA, PARAGRAPH_END, BQUOTE_START, CDATA, BQUOTE_START, CDATA, BQUOTE_END, CDATA, BQUOTE_END, PARAGRAPH_START, CDATA, PARAGRAPH_END. Трудность здесь заключается в окончательном BQUOTE_END, который, я думаю, должен быть воображаемым токеном, выпущенным после того, как найден элемент, не являющийся блок-цитатой (и уровень вложенности>> 1)

Ответы [ 2 ]

2 голосов
/ 15 января 2010

Что ж, если токен, который вы хотите выдать, не определен правилом лексера, вам нужно добавить секцию токена следующим образом:

tokens
{
    MYFAKETOKEN
}

В вашем лексере вам все еще понадобится правило, которое сообщает лексеру, когда производить этот токен. Распространенным примером является определение, является ли что-то целым числом, диапазоном или действительным значением.

NUMBERS_OR_RANGE
: INT 
        ( { LA(1) == '.' && LA(2) == '.' }? { _ttype = INT; }
    | { LA(1) == '.' || LA(1) == 'e' || LA(1) == 'E' }? { _ttype = REAL; }
    )
| PERIOD 
    ( PERIOD { _ttype = RANGE; }
    INT (( 'e' | 'E' ) ( '-' | '+' )? INT )? { _ttype = REAL; }
)
;

Здесь вы можете видеть, что мы сопоставляем либо INT, а затем заглядываем вперед, если мы находим двойной период, то мы знаем, что INT действительно int, а не real. В этом случае мы устанавливаем переменную _ttype равной INT. Если мы найдем ПЕРИОД, а затем 'e', ​​мы знаем, что это реально.

Во втором случае, когда мы сопоставляем период, мы знаем, что если следующий символ представляет собой период, то у нас есть диапазон, в противном случае мы получаем реальное.

Мы могли бы использовать тип MYFAKETOKEN, который мы определили выше, чтобы присвоить _ttype, если это было уместно.

0 голосов
/ 25 января 2010

Хорошо, я провел некоторое исследование и нашел это: http://www.cforcoding.com/2010/01/markdown-and-introduction-to-parsing.html

Я не думаю, что ANTLR действительно настроен для такой задачи, и попытка наклониться назад, чтобы сделать это, не стоит.

...