У меня есть грамматика ниже (упрощенная для демонстрации), и у меня возникла проблема в конкретном случае, связанном с логическими операторами.ANTLR C# 4 Грамматика - Приоритет
Все, что я тестировал, кроме случая, когда логический оператор находится в моем цитированном идентификаторе. Например, это работает:
@m = "ABC12345"
Но это не делает:
@m = "ABC12OR345"
Что происходит, ИЛИ внутри строки дает приводит к следующему ошибка
посторонний вход 'ИЛИ' ожидает { "", LOWCHAR < HIGHCAR, DIGIT}
Я в недоумении относительно того, как Ге t приоритет правильный.
Благодаря
grammar PRDL;
options
{
language=CSharp;
}
statement
: expression (logicalOperator expression)*
;
logicalOperator
: logicalOR | logicalAND
;
logicalOR
: OR
;
logicalAND
: AND
;
expression
: mVar
| nVar
| parenStatement
| notExpression
;
parenStatement
: LPAREN statement RPAREN
;
notExpression
: NOT expression
;
mVar
: M equalityOperator quotedIdentifier
;
nVar
: N equalityOperator quotedIdentifier
;
equalityOperator
: EQUAL
;
quotedIdentifier
: '"' identifier '"'
;
identifier
: (HIGHCHAR | LOWCHAR | DIGIT)+
;
// ============ Lexer Defintions ========================
// OPERATORS
NOT_ALLOWED : '*' | '/' | '+' | '-' | '#' | '$' | '%' | '^';
EQUAL : '=';
COMMA : ',';
LPAREN : '(';
RPAREN : ')';
LPARENSQ : '[';
RPARENSQ : ']';
OR : ('OR' | 'or' | '||');
AND : ('AND' | 'and' | '&&');
NOT : ('NOT' | 'not' | '!') ;
M : '@M';
N : '@N';
LOWCHAR : 'a'..'z';
HIGHCHAR : 'A'..'Z';
DIGIT : '0'..'9';
// Whitespace -- ignored
WS : [ \n\t\r\f]+ -> skip;
Привет, Лукас, спасибо за ответ. Я попробовал пару вариантов, учитывая вашу информацию, но все еще имел проблемы. –
Извините, нажмите enter, а затем не успели вернуться. Одна из вещей, о которых я не упоминал, это то, что я использую прослушиватель, поэтому у меня больше правил в парсере (например, public override void ExitQuotedIdentifier ...). Во время разбора я создаю внутренний список, который позже могу применить к переменным значения реальных значений и оценить истинное/ложное условие. Похоже, мне нужно больше читать, чтобы лучше понять эту версию antlr - несколько иначе, чем версия, которую я использовал 8 или 10 лет назад. –
Хорошо, я понял. Изменяя это: идентификатор \t: (HIGHCHAR | LOWCHAR | DIGIT) + \t; Для этого: идентификатор \t: ИДЕНТИФИКАТОР + \t; , а затем положить IDENTIFIER в лексер следующим образом: IDENTIFIER \t: (HIGHCHAR | LOWCHAR | DIGIT) +; Я смог заставить все работать. Спасибо, –