Язык, на котором я лечу, требует возможности «горячей» замены ключевых слов в зависимости от конфигурации времени исполнения.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 по нескольким причинам. Основная причина заключается в том, что обычно считается, что ключевые слова всегда используются как ключевые слова, а затем, если необходимо, разрешают их как идентификаторы на уровне анализатора (например, контекстно-зависимые ключевые слова). Кроме того, другие вопросы, задающие просто , как для достижения этого эффекта, предлагают метод, в основном эквивалентный приведенному выше решению встроенных действий.
Наиболее перспективным символом я могу найти для этой задачи 'org.antlr .v4.runtime.TokenStreamRewriter', но если я правильно читаю его javadoc, это только для изменения текстового представления. – CAD97
Не могли бы вы как-то узнать эту «конфигурацию времени выполнения» до начала лексинга/синтаксического анализа? – cantSleepNow
@cantSleepNow Да, это известно раньше и постоянно в каждой рабочей среде. – CAD97