Есть ли способ повлиять на разные способы анализа одного и того же выражения? (бизон)C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Есть ли способ повлиять на разные способы анализа одного и того же выражения? (бизон)

Сообщение Anonymous »

Итак, сейчас я работаю над грамматикой языка для проекта, и вот в чем дело. Я хочу, чтобы он действовал по-другому, независимо от того, есть ли в конце точка с запятой. Например, выражения «1+2» и «1+2;» следует относиться по-другому. Это легко сделать, но что произойдет, если у нас есть выражение «1+2 * 3;» тогда у нас будет два выражения внутри одного: (1+(выражение); где выражение равно 2 * 3).
И вот в чем проблема, в таком случае 2 * 3 будет рассматривается как выражение без точки с запятой, даже если оно находится внутри выражения с точкой с запятой в конце. Я хотел бы изменить это, чтобы дочернее выражение наследовало точку с запятой от корневого выражения.
Итак, функции OpAdd, OpMult, OpDivF, OpSub описывают способ выражений без точки с запятой. следует обрабатывать, а функции OpAdd2, OpMult2, OpDivF2, OpSu2b описывают способ обработки выражений с точкой с запятой. Итак, вот правила грамматики (кстати, это .yy):

Код: Выделить всё

`%%
program
: stmt
;

stmt
: assignment
| expression
| expression_with_semicolon
| str
;

assignment
: KW_LET id OP_ASSIGN expression {
$$ = Node::add($2, $4);
}
| KW_LET id OP_COLON type OP_ASSIGN expression {
$$ = Node::add($2, $4, $6);
}
| KW_LET id OP_COLON type {
$$ = Node::add($2, $4);
}
;

id
: IDENTIFIER { $$ = Node::add(curtoken); }
;

expression
: expression OP_PLUS expression { $$ = Node::add($1, $3); }
| expression OP_MINUS expression { $$ = Node::add($1, $3); }
| term
;

expression_with_semicolon
: expression OP_PLUS expression OP_SEMICOLON { $$ = Node::add($1, $3); }
| expression OP_MINUS expression OP_SEMICOLON { $$ = Node::add($1, $3); }
| term_with_semicolon
;

term
: term OP_MULT term { $$ = Node::add($1, $3); }
| term OP_DIVF term { $$ = Node::add($1, $3); }
| factor
;

term_with_semicolon
: term OP_MULT term OP_SEMICOLON { $$ = Node::add($1, $3); }
| term OP_DIVF term OP_SEMICOLON { $$ = Node::add($1, $3); }
| factor OP_SEMICOLON { $$ = $1; }
;

factor
: posneg
| OP_LPAREN expression OP_RPAREN { $$ = $2; }
;

posneg
: L_INTEGER { $$ = Node::add(curtoken); }
| OP_PLUS factor { $$ = Node::add(OP_PLUS, $2); }
| OP_MINUS factor { $$ = Node::add(OP_MINUS, $2); }
;

type
: TYPE { $$ = Node::add(curtoken); }
;

str
: SSTRING OP_SEMICOLON { $$ = Node::add(curtoken); }
;
%%`
Этот код всегда работает с «выражениями без точки с запятой» и работает с выражениями с точкой с запятой, пока они не инкапсулированы в другие. Я попытался добавить логический флаг, чтобы присвоить ему значение «истина», когда мы находимся в выражении с точкой с запятой, но это не сработало. Я считаю, что это связано с тем, что вы не можете изменить глобальную переменную на правило синтаксического анализатора. Я также пытался написать другие правила для управления выражениями, не являющимися точкой с запятой, внутри выражения с точкой с запятой, но это противоречило правилу выражения:

Код: Выделить всё

`expression_with_semicolon_inner
: expression OP_PLUS term { $$ = Node::add($1, $3); }
| expression OP_MINUS term { $$ = Node::add($1, $3); }
| term_with_semicolon_inner
;

term_with_semicolon_inner
: term OP_MULT factor { $$ = Node::add($1, $3); }
| term OP_DIVF factor { $$ = Node::add($1, $3); }
| posneg { $$ = $1; }
;`
У меня заканчиваются решения, поэтому, если у кого-нибудь есть предложения, я буду рад их попробовать.

Подробнее здесь: https://stackoverflow.com/questions/791 ... expression
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»