2015-03-03 3 views
3

Оператор import или опция tokenVocab могут быть помещены в грамматику анализатора для повторного использования грамматики лексера.ANTLR4: Любая разница между импортом и tokenVocab?

Сэм Харвелл советует всегда использовать tokenVocab, а не import [1].

Есть ли разница между import и tokenVocab? Если нет никакой разницы (и Сэм говорит, чтобы использовать tokenVocab), то почему есть заявление import?

[1] I actually recommend avoiding the import statement altogether in ANTLR. Use the tokenVocab feature instead. [Sam Harwell]

См ANTLR4: Unrecognized constant value in a lexer command

ответ

6

Во-первых, давайте поговорим о import.

Что такое import делает аналогично #include на языке C/C++, который копирует src в dst. ANTLR4 попытается объединить две грамматики, если есть конфликты.

Использование import является своего рода разочарование, потому что есть очень много ограничений:

  1. Не каждый вид грамматики может импортировать любой другой вид грамматики.

    • Lexer grammars может импортировать лексерные грамматики.
    • Углеродные грамматики могут импортировать грамматики парсера.
    • Комбинированные грамматики могут импортировать лексеры или грамматики парсера.
  2. При импорте options в грамматике будет проигнорирован.

  3. При импорте в лексерской грамматике не допускается mode.

Таким образом, вы фактически не можете импортировать грамматику лексера в грамматику парсера, потому что они не такие же. Но вы можете импортировать лексер в комбинированную грамматику.

Эти ограничения сузили использование import. Я думаю, что лучшая ситуация для использования import будет разделять большую лексируемую или парсерную грамматику на несколько частей, чтобы упростить управление.

Теперь, помните, что мы не можем импортировать грамматику лексера в грамматику анализатора, используя import? Вот почему нам нужен tokenVocab, который предназначен для использования отдельного лексера в парсере или комбинированной грамматике.

Заключение выше будет:

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

Для третьего, какая теперь разница?

Разница заключается в том, что с использованием tokenVocab необходимо скомпилировать лексер, потому что tokenVocab - это только вариант, объявляющий о необходимости использования другой грамматики. Хотя использование import не нуждается в этом, потому что оно скопирует src в текущую грамматику.

Например, есть три файлы грамматики:

G1.g4

grammar G1; 
r: B; 

G2.g4

grammar G2; 
import G1 

G3.g4

grammar G3; 
options { tokenVocab=G2; } 
t: A; 

Если мы напрямую скомпилируйте G2, все будет в порядке. Но если попытаться скомпилировать G3, приходит сообщение об ошибке:

error(160): G3.g4:3:21: cannot find tokens file ./G1.tokens

Однако, если мы составляем G1 первых, будет G1.tokens. Теперь сбор G3 будет успешным.

 Смежные вопросы

  • Нет связанных вопросов^_^