我试图通过定义非关联优先级来强制执行一些解析错误。 这是我的语法文件的一部分:
Comparison :
Value ComparisonOp Value
{
$2->Left($1);
$2->Right($3);
$$ = $2;
}
;
1 = 2之类的表达式应该解析,但语法中不允许使用类似1 = 2 = 3的表达式。为了适应这种情况,我尝试将运算符设置为非关联,如下所示:
%nonassoc NONASSOCIATIVE
.
.(rest of the grammar)
.
Comparison :
Value ComparisonOp Value %prec NONASSOCIATIVE
{
$2->Left($1);
$2->Right($3);
$$ = $2;
}
;
1 = 2 = 3仍然通过,有人可以告诉我我做错了吗?
答案 0 :(得分:3)
您需要设置ComparisonOp
令牌的关联性。任
%nonassoc ComparisonOp NONASSOCIATIVE
如果ComparisonOp
是令牌或类似
%nonassoc '=' '<' '>' NOT_EQUAL GREATOR_OR_EQUAL LESS_OR_EQUAL NONASSOCIATIVE
如果您有多个令牌,ComparisonOp
是一个扩展到其中任何一个的规则
作为一个具体的例子,以下工作与您要求的完全一样:
%{
#include <stdio.h>
#include <ctype.h>
int yylex();
void yyerror(const char *);
%}
%nonassoc '=' '<' '>' CMPOP
%left '+' '-' ADDOP
%left '*' '/' '%' MULOP
%token VALUE
%%
expr: expr cmp_op expr %prec CMPOP
| expr add_op expr %prec ADDOP
| expr mul_op expr %prec MULOP
| VALUE
| '(' expr ')'
;
cmp_op: '=' | '<' | '>' | '<' '=' | '>' '=' | '<' '>' ;
add_op: '+' | '-' ;
mul_op: '*' | '/' | '%' ;
%%
int main() { return yyparse(); }
int yylex() {
int ch;
while(isspace(ch = getchar()));
if (isdigit(ch)) return VALUE;
return ch;
}
void yyerror(const char *err) { fprintf(stderr, "%s\n", err); }
所以,如果您遇到其他问题,请尝试发布显示您遇到的实际问题的MVCE ...