ANTLR4 грамматика для проверки поля - PullRequest
0 голосов
/ 18 сентября 2018

В настоящее время я работаю над проектом, и у меня есть задача проверить идентификатор с помощью грамматики 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.log(pars.numberOfSyntaxErrors);
if ( pars.numberOfSyntaxErrors > 0 ) {
  return false;
}
return true;

Моя проблема в том, что даже еслиЯ правильно понял грамматику, моя реализация обработки ошибок не правильная, и я не нашел материала для изучения обработки ошибок с помощью antlr4ts.

Так что, если вы можете мне помочь, я был бы признателен за отзыв ограмматика (как это должно быть, или проблемы, которые у него есть), а также о реализации обработки ошибок (некоторая информация об этом, потому что при тестировании я вижу, как ConsoleErrorListener выдает синтаксическую ошибку на консоль, но моя функция показывает 0 синтаксических ошибок).

Спасибо за чтение и надеюсь, что вы можете мне помочь.

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

Предвидя, что этот внутренний микросервис «сделает больше» в будущем, текущее минимальное грамматическое требование может быть удовлетворено с помощью

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.

0 голосов
/ 18 сентября 2018

Я думаю, что использование 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.Версия regex также исправляет это.

...