Приоритет оператора Jison
Я разрабатываю язык с использованием Jison, и проблема, с которой я сталкиваюсь, заключается в приоритете операторов. Я хочу, чтобы операторы сравнения были первыми операторами, которые будут оценены, например, 1 + 2 < 3 - 3 * 4
станет (1+2) < (3 - (3 * 4))
Правила у меня сейчас:
expression
: expression OP_COMPARISON expression
{ $$ = { type: "Comparison", operator: $2, args: [$1, $3], location: locationFromObject(@$) } }
| literal
{ $$ = $literal; }
| NAME
{ $$ = { type: "Variable", variable: $1, location: locationFromObject(@$) }; }
| field
{ $$ = { type: "Field", field: $field, location: locationFromObject(@$) }; }
| '(' ':' typename ')' expression
{ $$ = { type: "Cast", cast_type: $typename, expression: $expression, location: locationFromObject(@$) }; }
| function_call
{ $$ = $function_call; $$.type = "FunctionCall"; }
| method_call
{ $$ = $method_call; $$.type = "FunctionCall"; }
| '(' expression ')'
{ $$ = { type: "Grouped", expression: $expression, location: locationFromObject(@$) }; }
| OP_PREPOSTFIX expression
{ $$ = { type: "Prefix", operator: $1, arg: $expression, location: locationFromObject(@$) }; }
| expression OP_PREPOSTFIX
{ $$ = { type: "Postfix", operator: $2, arg: $expression, location: locationFromObject(@$) }; }
| expression OP_ARITHMETIC expression
{
if($1.type == "Arithmetic"){
$$ = $1;
$$.args.push($3);
$$.operators.push($2);
$$.location = locationFromObject(@$);
}else{
$$ = { type: "Arithmetic", operators: [$2], args: [$1, $3], location: locationFromObject(@$) };
}
}
| expression OP_LOGICAL expression
{
if($1.type == "Logical"){
$$ = $1;
$$.args.push($3);
$$.operators.push($2);
$$.location = locationFromObject(@$);
}else{
$$ = { type: "Logical", operators: [$2], args: [$1, $3], location: locationFromObject(@$) };
}
}
| '!' expression
{ $$ = {type: "LogicalNot", arg: $expression, location: locationFromObject(@$) }; }
;
Любая помощь будет принята с благодарностью
1 ответ
Лучший способ получить приоритет оператора в грамматике без контекста - использовать несколько правил, которые указывают уровни приоритета. Например, с простой арифметикой:
expression : expression PLUS term
| expression MINUS term
| term
;
term : term MULTIPLY factor
| term DIVIDE factor
| factor
;
factor : IDENTIFIER
| CONSTANT
| LEFT expression RIGHT
;
Используя эту иерархию, реализуются правила арифметики BODMAS.
Вы можете сделать нечто похожее с вашей грамматикой: разбить на несколько правил, представляющих различные уровни приоритета.
(См. Стандартный компилятор, пишущий тексты информатики для большего количества деталей)