Bison 非关联优先规则
Bison nonassociative precedence rule
我试图通过定义非关联优先级来强制执行一些解析错误。
这是我的语法文件的一部分:
Comparison :
Value ComparisonOp Value
{
->Left();
->Right();
$$ = ;
}
;
应该解析像 1 = 2 这样的表达式,但是像 1 = 2 = 3 这样的表达式在语法中是不允许的。为了适应这一点,我尝试使我的运算符非关联,如下所示:
%nonassoc NONASSOCIATIVE
.
.(rest of the grammar)
.
Comparison :
Value ComparisonOp Value %prec NONASSOCIATIVE
{
->Left();
->Right();
$$ = ;
}
;
1 = 2 = 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 来显示您遇到的实际问题...
我试图通过定义非关联优先级来强制执行一些解析错误。 这是我的语法文件的一部分:
Comparison :
Value ComparisonOp Value
{
->Left();
->Right();
$$ = ;
}
;
应该解析像 1 = 2 这样的表达式,但是像 1 = 2 = 3 这样的表达式在语法中是不允许的。为了适应这一点,我尝试使我的运算符非关联,如下所示:
%nonassoc NONASSOCIATIVE
.
.(rest of the grammar)
.
Comparison :
Value ComparisonOp Value %prec NONASSOCIATIVE
{
->Left();
->Right();
$$ = ;
}
;
1 = 2 = 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 来显示您遇到的实际问题...