Правильно принимать скобки в bisonStack Overflow

Я пытался написать базовую проверку синтаксиса с помощью bisonc++

Правила таковы:

expression -> OPEN_BRACKET expression CLOSE_BRACKET
expression -> expression operator expression

operator -> PLUS
operator -> MINUS

Если я пытаюсь запустить скомпилированный код, я получаю сообщение об ошибке в этой строке:

(a+b)-(c+d)

Первое правило применяется, крайние левые и крайние правые скобки являются OPEN_BRACKET и CLOSE_BRACKET, Остальные expression является: a+b)-(c+d

Как можно предотвратить такое поведение? Можно ли считать открытые и закрытые скобки?


редактировать

Грамматика выражения:

expression:
OPEN_BRACKET expression CLOSE_BRACKET
{
//
}
| operator
{
//
}
| VARIABLE
{
//
}

;operator:
expression PLUS expression
{
//
}

| expression MINUS expression
{
//
}

;

Edit2

Лексер

CHAR  [a-z]
WS    [ \t\n]

%%

{CHAR}+     return Parser::VARIABLE;

"+"         return Parser::PLUS;
"-"         return Parser::MINUS;

"("         return Parser::OPEN_BRACKET;
")"         return Parser::CLOSE_BRACKET;

0

Решение

Это не нормальная грамматика выражения. Попробуйте нормальный.

expression
: term
| expression '+' term
| expression '-' term
;
term
: factor
| term '*' factor
| term '/' factor
| term '%' factor
;
factor
: primary
| '-' factor // unary minus
| primary '^' factor // exponentiation, right-associative
;
primary
: identifier
| literal
| '(' expression ')'
;

Обратите также внимание на приведенный выше метод отступа и выравнивания, и вам нужно только вернуть yytext[0] из лексера для отдельных специальных символов: вам не нужны специальные имена токенов, и они более читабельны без них:

CHAR [a-zA-Z]
DIGIT [0-9]
WHITESPACE [ \t\r\n]
%%
{CHAR}+       { return Parser::VARIABLE; }
{DIGIT}+      { return Parser::LITERAL; }
{WHITESPACE}+ ;
.             { return yytext[0]; }
4

Другие решения

Ваше правило оператора выглядит не очень хорошо.

Попробуйте поэкспериментировать с:

expression:
OPEN_BRACKET expression CLOSE_BRACKET
{
//
}

|

expression operator expression
{
//
}

|

VARIABLE
{
//
}

;operator:
PLUS
{
//
}

|

MINUS
{
//
}
;

Как показывает ваш псевдокод …

1