Bison 如何解决这个问题;冲突:1移位/减少“;
我写了一个语法来解析velocity,它在“if-elseif-else”处有冲突 flex文件:Bison 如何解决这个问题;冲突:1移位/减少“;,bison,yacc,lex,flex-lexer,Bison,Yacc,Lex,Flex Lexer,我写了一个语法来解析velocity,它在“if-elseif-else”处有冲突 flex文件: %{ #include<stdio.h> #include<string.h> #include "context.h" #include "bool.h" #include "vtl4.tab.h" %} INT ([0-9]*) %% {INT} {return INTEGER;} ">" {return yytext[0];} "(" {return yytex
%{
#include<stdio.h>
#include<string.h>
#include "context.h"
#include "bool.h"
#include "vtl4.tab.h"
%}
INT ([0-9]*)
%%
{INT} {return INTEGER;}
">" {return yytext[0];}
"(" {return yytext[0];}
")" {return yytext[0];}
"in" {return IN;}
"#foreach" {return FOREACH;}
"#end" {return END;}
"#if" {return IF;}
"#else" {return ELSE;}
"#elseif" {return ELSEIF;}
[^ \t] {yylval.string = yytext;return CONTENT;}
[ \t] {}
%%
我查找了一些信息,并为ELSE和ELSEIF添加了优先级,但没有修复它。请帮助我!也许我不太了解优先级机制我不知道您希望解析的语言是如何工作的,所以这只是一个猜测,但您的问题可能在这里:
elseif : ELSEIF '(' cond ')' stmts
| elseif elseif
;
一个elseif可以由两个elseif组成。因此,如果您有三个elseif,那么它们应该分组为((elseif elseif)elseif)还是(elseif(elseif elseif))?野牛不知道,报告了一场冲突
另一件事是,如果只使用语法,而不使用大量其他代码,那么理解和使用语法就会简单得多。Bison文件的最小可编译版本和更易于格式化的版本如下所示(假设我在编辑过程中没有犯任何错误):
我建议使用这种新语法,它不会改变/减少冲突
编辑:我删除了%nonassoc优先级规范,因为它们不需要。您使用的是一种语法,每个IF都有一个结尾,这样就不会有类似于C语法的IF-IF-else冲突,您可以通过指定前导来消除这种冲突
%token IF ELSEIF ELSE END INTEGER FOREACH IN
%%
stmts : stmt
| stmts stmt
;
stmt: directive | INTEGER ;
directive : FOREACH '(' exp ')' stmts END
| if
;
if : IF '(' cond ')' stmts END
| IF '(' cond ')' stmts ELSE stmts END
| IF '(' cond ')' stmts elseifs END
| IF '(' cond ')' stmts elseifs ELSE stmts END
;
elseifs : elseif | elseifs elseif ;
elseif : ELSEIF '(' cond ')' stmts
;
cond : INTEGER '>' INTEGER ;
exp : INTEGER IN INTEGER ;
%%
我不知道您希望解析的语言是如何工作的,因此这只能是猜测,但您的问题可能在这里:
elseif : ELSEIF '(' cond ')' stmts
| elseif elseif
;
一个elseif可以由两个elseif组成。因此,如果您有三个elseif,那么它们应该分组为((elseif elseif)elseif)还是(elseif(elseif elseif))?野牛不知道,报告了一场冲突
另一件事是,如果只使用语法,而不使用大量其他代码,那么理解和使用语法就会简单得多。Bison文件的最小可编译版本和更易于格式化的版本如下所示(假设我在编辑过程中没有犯任何错误):
我建议使用这种新语法,它不会改变/减少冲突
编辑:我删除了%nonassoc优先级规范,因为它们不需要。您使用的是一种语法,每个IF都有一个结尾,这样就不会有类似于C语法的IF-IF-else冲突,您可以通过指定前导来消除这种冲突
%token IF ELSEIF ELSE END INTEGER FOREACH IN
%%
stmts : stmt
| stmts stmt
;
stmt: directive | INTEGER ;
directive : FOREACH '(' exp ')' stmts END
| if
;
if : IF '(' cond ')' stmts END
| IF '(' cond ')' stmts ELSE stmts END
| IF '(' cond ')' stmts elseifs END
| IF '(' cond ')' stmts elseifs ELSE stmts END
;
elseifs : elseif | elseifs elseif ;
elseif : ELSEIF '(' cond ')' stmts
;
cond : INTEGER '>' INTEGER ;
exp : INTEGER IN INTEGER ;
%%
你读过各种文件和其他关于冲突的问题吗?你应该。您将看到您的问题与
ELSE
(您引用的输出部分在冲突中没有提到它!)无关
你的语法
elseifs: "#elseif" | elseifs elseifs
这显然是模棱两可的。试一试
elseifs: "#elseif" | elseifs "#elseif"
或者可能
elseifs: | elseifs "#elseif"
你读过各种文件和其他关于冲突的问题吗?你应该。您将看到您的问题与
ELSE
(您引用的输出部分在冲突中没有提到它!)无关
你的语法
elseifs: "#elseif" | elseifs elseifs
这显然是模棱两可的。试一试
elseifs: "#elseif" | elseifs "#elseif"
或者可能
elseifs: | elseifs "#elseif"
谢谢你详细的回答。它很好。你让我理解了这么多,谢谢。我会更认真地学习它,我为我糟糕的英语感到抱歉。谢谢你详细的回答。它很好。你让我理解了这么多,谢谢。我会更认真地学习它,我为我糟糕的英语感到抱歉。