2016-10-30 8 views
1

Язык, на котором я лечу, требует возможности «горячей» замены ключевых слов в зависимости от конфигурации времени исполнения.ANTLR4 динамический токен типа

Это относительно просто, как сделать это так долго, как вы исправны вложение целевой конкретный код в вашей грамматике (Java):

lexer grammar LanguageLexer; 

tokens { 
If, Else, While // etc 
} 

@header { 
import java.util.Map; 
} 

@members { 
private Map<String, Integer> keywords; 
public NafiLexer(CharStream input, Map<String, Integer> keywords) { 
    this(input); 
    this.keywords = keywords; 
} 
} 

WS: [ \n\t\r]+ -> skip; 
ID: [a-zA-Z]+ { if(keywords.containsKey(getText())) setType(keywords.get(getText())); }; 

Однако, я хотел бы, чтобы удалить все мишени специфические код из моего файла .g4, так как мои .g4 s будут использоваться на нескольких целевых языках для отдельных проектов.

В Parser вы можете использовать Listener, чтобы удалить внедренные действия и отделить грамматику от кода приложения. Однако, если существует способ сделать это на уровне Lexer , мне еще не найти его (таким образом задавая этот вопрос).

Способ сделать это, похоже, состоит в том, чтобы обернуть TokenStream, снятый с Lexer. Эта упаковка TokenStream будет читать Token с, как они были предоставлены, и применить преобразование, находящееся во встроенном действии, к любым токенам ID.

Это (теоретически) было бы непросто реализовать; однако это похоже на функциональность, которая должна быть возможна только с уже определенными символами ANTLR. Итак, вопрос: можно условно изменить тип токенов, проходящих через TokenStream в существующей системе ANTLR? Если нет, то каков способ наименьшего трения для выполнения этой задачи? Примером может служить пример с использованием библиотеки Java, поскольку это тот, с которым я больше всего знаком.

И как вопрос: если я создаю TokenTransformationStream для моих целевых целей, стоит ли добавить его в существующие библиотеки? (Я могу создать символы для всех текущих поставляемых целей.)


Да, это приведет к краху, если вы строите Lexer с обычным конструктором. В реальном приложении, возможно, стоит исправить это, но для этого примера это не имеет значения.

Я считаю, что это подходящая задача для уровня lexer по нескольким причинам. Основная причина заключается в том, что обычно считается, что ключевые слова всегда используются как ключевые слова, а затем, если необходимо, разрешают их как идентификаторы на уровне анализатора (например, контекстно-зависимые ключевые слова). Кроме того, другие вопросы, задающие просто , как для достижения этого эффекта, предлагают метод, в основном эквивалентный приведенному выше решению встроенных действий.

+0

Наиболее перспективным символом я могу найти для этой задачи 'org.antlr .v4.runtime.TokenStreamRewriter', но если я правильно читаю его javadoc, это только для изменения текстового представления. – CAD97

+0

Не могли бы вы как-то узнать эту «конфигурацию времени выполнения» до начала лексинга/синтаксического анализа? – cantSleepNow

+0

@cantSleepNow Да, это известно раньше и постоянно в каждой рабочей среде. – CAD97

ответ

0

Это не может быть ответом на вопрос, но это слишком долго для комментариев.
Я имел в виду режимы lexer в комментариях, потому что я сосредоточился на этой части hot-swap keywords. Я не знаю, почему вам нужно изменить тип токена, но если вы используете режимы lexer, возможно, вам это не понравится.

Единственный улов - это некоторые ключевые слова, которые указывают на изменение режима лексера. В принципе, один лексерский режим был бы грамматикой суб-лексера (вроде бы.)

RUNTIME_CFG_! : 'runtime_cfg_1' -> mode(m_CGF_1); 
... 
mode m_CGF_1; 
KEYWORD1 : 'key1; 
... 

Если есть некоторые же ключевые слова вы также можете использовать функцию лексического анализатора type * явно задать тип маркера.

* Я не могу вспомнить, в тот момент, как это называется, но функцией лексического анализатора Я имею в виду один из тех, кто, как mode, skip и т.д ..

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

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