В настоящее время я работаю над проектом, и у меня есть задача проверить идентификатор с использованием грамматики ANTLR4. Эта часть проекта, если интерфейс использует Angular 6, и грамматика также будет скомпилирована в микросервис серверной части.
Проверка состоит в проверке строки, которая начинается с буквы | цифры | символа, затем может иметь букву | цифру | подчеркивания и заканчивается буквой | цифрой.
В настоящее время у меня проблемы с реализацией грамматики (поскольку у меня нет опыта работы с Lex) и обработкой ошибок. Вот моя грамматика и реализация ошибки.
grammar test;
goal: identifier;
identifier: Alphanum+ Alphanumsymb* Alphanum+;
Alphanum: [a-zA-Z0-9];
Alphanumsymb: [a-zA-Z0-9_];
И моя реализация для определения правильности строки в соответствии с грамматикой.
const teststring = "2019_Test_Identifier";
const inputStream = new ANTLRInputStream(teststring);
const lex = new lexer.TestGrammarLexer(inputStream);
const tokenStream = new CommonTokenStream(lex);
const pars = new parser.TestGrammarParser(tokenStream);
pars.goal();
console.info(pars.numberOfSyntaxErrors);
if ( pars.numberOfSyntaxErrors > 0 ) {
return false;
}
return true;
Моя проблема в том, что даже если я правильно понимаю грамматику, моя реализация обработки ошибок неверна, и я не нашел материала для изучения обработки ошибок с помощью antlr4ts.
Итак, если вы можете мне помочь, я был бы признателен за отзывы о грамматике (как она должна быть или о проблемах с банкоматом) и о реализации обработки ошибок (некоторая информация об этом, потому что при тестировании я вижу ConsoleErrorListener выдает синтаксическую ошибку на консоль, но моя функция показывает 0 синтаксических ошибок).
Спасибо за чтение и надеюсь, что вы можете мне помочь.
Я думаю, что использование ANTLR немного излишне для вашей задачи. ANTLR или любой другой инструмент синтаксического анализа хорош для построения структуры строки, но здесь вы просто хотите знать, является ли строка идентификатором или нет. Если вам действительно нужен ANTLR, объясните, почему, и тогда я могу помочь вам с обработкой ошибок.
Для этой задачи я бы посоветовал вам просто использовать регулярное выражение, подобное приведенному ниже, для проверки идентификатора:
const regex = /^[a-zA-Z0-9]+|[a-zA-Z0-9][a-zA-Z0-9_]*[a-zA-Z0-9]+$/
А потом используйте его как regex.text(str)
.
Он вернет false
, если строка не будет принята в качестве идентификатора.
Обратите внимание, что ваше определение identifier
в грамматике ANTLR неверно. Он требует как минимум двух символов из-за двух квантификаторов +
и не работает в строках длиной 1, таких как a
. Версия с регулярным выражением также исправляет это.
Нет проблем, не могли бы вы уточнить, какие сообщения об ошибках вы имеете в виду? ANTLR сообщит о лексической ошибке, и вы сможете распечатать ее на консоли. Вы также можете настроить сообщение об ошибке, но я не уверен, что вы ищете.
Предполагая, что этот серверный микросервис будет «делать больше» в будущем, текущие минимальные требования к грамматике могут быть выполнены с помощью
ident : Alphanum (( Alphanum | Symb )* Alphanum )? ;
Alphanum : [a-zA-Z0-9] ;
Symb : '_' ;
Теперь правило ident
допускает использование односимвольного идентификатора, что явно разрешено исходной спецификацией. Правило Symb
теперь представляет собой единственный контент, который не был затенен правилом Alphanum
в исходной грамматике.
Лексический анализатор и анализатор по умолчанию включают прослушиватель ошибок консоли.
Используйте Recognizer#addErrorListener
, чтобы добавить собственное расширение ANTLRErrorListener
, которое подсчитывает и сообщает, по желанию, любые ошибки. ConsoleErrorListener
является примером источника. Один и тот же слушатель может быть установлен как на лексере, так и на синтаксическом анализаторе.
Используйте Recognizer#removeErrorListeners
, чтобы сначала удалить консольный слушатель, если консольные сообщения нежелательны.
Кстати, все среды выполнения ANTLR функционально идентичны и очень похожи по архитектуре. Итак, любой пример кода ANTLR на {Java, Python, ...} будет иметь почти эквивалентную реализацию на TypeScript.
Хорошо, спасибо за ваше объяснение. Я придерживаюсь того же мнения, что и вы, в настоящее время у меня есть код с этим регулярным выражением: / ^ [a-zA-Z0-9] {1} [a-zA-Z0-9 '_'] * [a-zA-Z0 -9] {1} $ /. Test () И он работает, но мне нужно сделать версию этой функции с помощью Antlr4 ... В любом случае, большое спасибо за ваш ответ