2015-11-29 2 views
0

Я пытаюсь разобрать диалоги MS SQL. В соответствии со спецификацией «сверху» должны иметь скобки вокруг выраженияantlr4 lexer/parser конфликтует из-за двусмысленности

выберите верхние (@rows * 2) а, б, в ...

, но в качестве исключения они могут быть опущены, если значение без знака буквального целое, таким образом

выберите топ 75 а, б, в ...

Я пытался встроить это буквальное-целое специального случая в моем синтаксическом анализаторе (свободно):

top_clause: 'TOP' [0-9] + | 'TOP' '(' expression ')';

Итак, первая альтернатива - это правило чистого лексера, второе - правило синтаксического анализа. Поскольку целочисленная константа является допустимым выражением, она выбирает ее как выражение.

Вопрос в том, 1) могу ли я заставить его соответствовать правилам лексера без предикатов и 2) самое главное, должен ли я?

Я полагаю, что я не должен - это вопиющая двусмысленность (действительно, ошибка в моей грамматике), и я думаю, что я должен соответствовать ей как чистое правило парсера (просто выражение «TOP») и сортировать его вне после. Совет приветствовать.

изменить: изменен пункт Мэтта Тиммермана.

+0

не хотите '' TOP '[0-9] + | 'TOP' '(' expression ')' '? –

+0

Ну, выражение уже определено, между прочим, как ** '(' выражение ')' **, и потому, что я ожидаю удалить правило только для lexer, я пропустил их здесь (потому что я не хотел требуют, чтобы остальная часть выражения была целым числом). Но да, вы правы. Будет редактировать. – user3779002

+0

теперь это не двусмысленно –

ответ

0

Ответ зависит от того, чего вы на самом деле хотите достичь, но я предполагаю, что вы хотите разрешить, например, пробелы между TOP и цифрами. Если вы определяете это как правило lexer, вам придется явно указывать там пробелы. С правилом анализатора это не обязательно, потому что (опять же я угадываю здесь) у вас есть правило lexer, которое пропускает whitspaces.

Что я рекомендую, так это то, что вы всегда определяете свои литералы как правила lexer (нет «TOP» в правиле парсера, без цифр) и сохраняете top_clause как есть, только с помощью ваших новых правил lexer (и небольшого рефакторинга) :

DIGITS: [0-9]+; 
TOP: 'TOP'; 
OPEN_PAR: '('; 
CLOSE_PAR: ')'; 

top_clause: TOP (DIGITS | OPEN_PAR expression CLOSE_PAR); 
+0

Привет, нет, это не просто пробел, потому что в «верхней» конструкции есть специальный случай без скобок - нужны-если-только-цифры; Должен ли я рассматривать этот частный случай со своим собственным лексерским правилом? Мэтт Тиммерманс говорит «нет», и это звучит правильно. Число рейнольдса правила lexer, я упрощал этот пост; все мои лексики выполняются с именованными правилами, за исключением «(» и «)», которые по вашему убеждению я теперь буду en-rule-ify. – user3779002

+0

Небольшое примечание - лексер ANTLR настолько способный, что я вызвал проблемы, используя его вместо парсера для сложных структур. Подсказка к другим - поместить всю структуру в парсер и держать лексику просто. – user3779002

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