Конфликт лексирования грамматики Antlr Matlab - PullRequest
1 голос
/ 19 июня 2020

Я использовал грамматику Antlr Matlab из грамматик Antlr

Я обнаружил, что мне нужно реализовать оператор Matlab. Это оператор комплексно-сопряженного транспонирования , используемый как таковой

result = input'

Я попробовал простое решение, добавив его в unary_expression в качестве опции postfix_expression '\''

Однако, это не удалось проанализировать, когда несколько таких операторов использовались в одной строке.

Вот значительно упрощенная версия грамматики, по-прежнему демонстрирующая точную проблему:

grammar Grammar;

unary_expression
   : IDENTIFIER
   | unary_expression '\''
   ;

translation_unit : unary_expression CR ;

STRING_LITERAL : '\'' [a-z]* '\'' ;

IDENTIFIER : [a-zA-Z] ;

CR : [\r\n] + ;

Тестовые примеры, будучи анализируется как translation_unit:

"x''\n" //fails getNumberOfSyntaxErrors returns 1
"x'\n" //passes

Ошибка также выводит сообщение line 1:1 extraneous input '''' expecting CR на stderr.

Ошибка исчезает, если я удаляю STRING_LITERAL или изменяю * на +. Конечно, это тоже не подходящее решение, так как его удаление полностью исключено из таблицы, а обязательное использование непустых строк не совсем правильно, хотя я мог бы смириться с этим. Кроме того, принудительное использование непустой строки не помогает в реальном варианте использования, когда вводится что-то вроде x' + y' вместо того, чтобы использовать оператор дважды.

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

Что я могу сделать с грамматикой, чтобы она работала правильно? Я предполагаю, что это проблема с лексированием именно потому, что удаление STRING_LITERAL или невозможность сопоставления '' приводит к удалению go.

1 Ответ

1 голос
/ 20 июня 2020

Я думаю, лексер никогда не сможет быть осведомленным о контексте, но я недостаточно хорошо знаю Matlab, чтобы быть уверенным. Как вы могли проверить во время токенизации, что эти одинарные кавычки являются операторами:

x' + y';

в то время как это строки:

x = 'x' + ' + y';

?

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

Если что-то подобное невозможно, я вижу нет другого пути, кроме как «продвигать» создание строк к синтаксическому анализатору. Это означало бы удаление STRING_LITERAL и введение правила синтаксического анализатора, которое соответствует примерно так:

string_literal
 : QUOTE ~(QUOTE | CR)* QUOTE
 ;

// Needed to match characters inside strings
OTHER
 : .
 ;

Однако это не удастся, когда встречается строка типа 'hi there': пробел между hi и there теперь будет пропущено правилом WS. Так что WS также следует удалить (пробелы будут соответствовать правилу OTHER). Но теперь (конечно) все пробелы будут засорять поток токенов, и вам придется учитывать их во всех правилах парсера (на самом деле это не жизнеспособное решение).

В общем: я не вижу ANTLR как подходящий инструмент в этом случае. Вы можете изучить генераторы парсеров, где нет разделения между токенизацией и синтаксическим анализом. Google для "PEG" и / или "разбора без сканирования".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...