我正在使用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(@$) }; }
;
任何帮助将不胜感激
将运算符优先级转换为上下文无关语法的最佳方法是使用多个指示优先级级别的规则。例如,使用简单的算术:
expression : expression PLUS term
| expression MINUS term
| term
;
term : term MULTIPLY factor
| term DIVIDE factor
| factor
;
factor : IDENTIFIER
| CONSTANT
| LEFT expression RIGHT
;
使用此层次结构,实现了算术的BODMAS规则。
你可以对语法做类似的事情:分成几个代表不同优先级层的规则。
(有关更多详细信息,请参阅编写计算机科学文本的标准编译器)