Можно ли настроить правила/парсер/лексер, чтобы принять ввод, соответствующий ожидаемой структуре, но статические (предопределенные) токены не написаны полностью?
У меня есть грамматика ANTLR4 (цель С#), которую я использую для анализа ввода и использования его для запуска определенных методов моего приложения.
(выдумал):
grammar:
setWage
: SETWAGE userId=STRING value=NUMBER
;
SETWAGE
: 'setWage'
;
input:
setWage john.doe 2000
Слушатель, который обрабатывает дерево разбора в методе для правила setWage (после получения текста из помеченных токенов), вызовет, например:
SalaryManager.SetWage(User.GetById("john.doe"), 2000);
Мой вопрос: может ли быть установлен Antlr (или грамматика), чтобы можно было, например, ввести такой ввод:
setW john.doe 2000
предполагая, что нет правил, например, "setWater" или "setWindow", или если предположить, что есть, и я в порядке с Antlr, выбирая один из них сам по себе (хотя и последовательно один и тот же).
Обратите внимание, что этот вопрос в основном является академическим, и я не ищу лучшего способа достижения этой input-> ссылки на действия.
Вы, наверное, уже это знаете, но вы можете разработать набор возможных совпадений ввода
SETWAGE : 'setW' | 'setWa' | 'setWag' | 'setWage' ;
или
SETWAGE : 'set' ('W' ('a' ('g' ('e')? )? )? ) ;
Не уверен, что последний удовлетворяет вашему требованию, чтобы "статические (предопределенные) токены не были написаны полностью".
Жестко-кодирование "синонимов" может быть утомительным, но сколько вам нужно?
Вот пример, который я написал для проверки подхода. (Цель Java, но это не имеет значения)
actions.g4
grammar actions ;
actions : action+;
action : setWage | deductSum ;
setWage : SETWAGEOP userId=SYMBOL value=NUMBER ;
deductSum : DEDUCTSUMOP userId=SYMBOL value=NUMBER ;
//SETWAGEOP : 'setW' | 'setWa' | 'setWag' | 'setWage' ;
SETWAGEOP : 'set' ('W' ('a' ('g' ('e')? )? )? ) ;
DEDUCTSUMOP : 'deduct' ('S' ('u' ('m')? )? ) ;
WS : [ \t\n\r]+ -> channel(HIDDEN) ;
SYMBOL : [a-zA-Z][a-zA-Z0-9\.]* ;
NUMBER : [0-9]+ ;
testinput
setW john.doe 2000
deductS john.doe 50
setWag joe.doe.III 2002
deductSu joe.doe 40
setWage jane.doe 2004
deductSum john.doe 50
Стенограмма:
$ antlr4 actions.g4 ; javac actions*.java ; grun actions actions -tree < testinput
(actions (action (setWage setW john.doe 2000)) (action (deductSum deductS john.doe 50)) (action (setWage setWag joe.doe.III 2002)) (action (deductSum deductSu joe.doe 40)) (action (setWage setWage jane.doe 2004)) (action (deductSum deductSum john.doe 50)))