为什么我会遇到冲突:1班/减少

时间:2010-11-20 22:10:28

标签: language-design bison flex-lexer

我是野牛新手,我遇到了“冲突:1班/减少”的错误。任何人都可以对此有所了解吗?

这是y文件。

test.y:

%{
#include <stdio.h>
#include <string.h>

#define YYERROR_VERBOSE
#define YYDEBUG 1
void yyerror(const char *str);
int yywrap();
%}

%union
{
    int integer;
    char *string;
}

%token <string>     VAR_LOCAL
%token <integer>    LIT_NUMBER
%token <string>     LIT_STRING
%token WS_LINEBRK

//%token SYMB_EQL
%token SYMB_PLUS
%token SYMB_MINUS
%token SYMB_MUL
%token SYMB_DIV

%%

/*
    // Sample input
    num = 10
    str = "this is a string"
*/

inputs: /* empty token */
        | literal
        | variable
        | inputs stmt WS_LINEBRK
        ;

stmt:   variable "=" exps  
        ;

exps:   variable op literal
        | variable op variable
        | literal op literal
        | literal op variable
        ;


op:     SYMB_PLUS | SYMB_MINUS | SYMB_MUL | SYMB_DIV ;


variable: VAR_LOCAL
        {
            printf("variable: %s\n", $1);
        }
        ;

literal:
        number | string
        ;

string: LIT_STRING
        {
            printf("word: %s\n", $1);
        }
        ;

number: LIT_NUMBER
        {
        printf("number: %d\n", $1);
        }
        ;

%%

void yyerror(const char *str)
{
        fprintf(stderr,"error: %s\n",str);
}

int yywrap()
{
        return 1;
} 

main()
{
    yyparse();
}

这是lex文件 test.l:

%{
#include <stdio.h>
#include <stdlib.h>


#include "y.tab.h"
int line_no = 0;

%}

%%
[a-z][a-zA-Z0-9]*       {
                            // local variable
                            yylval.string=strdup(yytext);
                            return VAR_LOCAL;
                        }

[0-9]+                  {
                            //number literal
                            yylval.integer=atoi(yytext);
                            return LIT_NUMBER;
                        }

=                       return SYMB_EQL;
\+                      return SYMB_PLUS;
\-                      return SYMB_MINUS;
\*                      return SYMB_MUL;
\/                      return SYMB_DIV;


\"[-+\!\.a-zA-Z0-9' ]+\"    {
                            // word literal
                            yylval.string=strdup(yytext);
                            return LIT_STRING;
                        }

\n                      {
                            // line break
                            printf("\n");
                            return WS_LINEBRK;
                        }

[ \t]+                  /* ignore whitespace */;

%%

2 个答案:

答案 0 :(得分:1)

bison -r test.y将写一个文件test.output,其中包含生成的状态机的详细说明,可以让您查看正在发生的情况 - 例如发生转换/减少冲突的状态。

在您的情况下,问题处于开始状态(对应于您的开始非终结,inputs)。假设第一个标记是VAR_LOCAL。解析器可以做两件事:

  • 它可以匹配variable案例。
  • 它也可以匹配inputs stmt WS_LINEBRK案例:inputs匹配空字符串(第一行),stmt匹配variable "=" exps

使用野牛解析器使用的一个前瞻标记,没有办法说出来。你需要改变你的语法来摆脱这种情况。

答案 1 :(得分:0)

要修复语法,正如Fabian所建议的那样,将变量 literal 输入<移动到 exps 的末尾/ em>的

inputs: 
    | variable
    | literal 

exps:
...
    | variable
    | literal

这允许x= yx="aliteral"语法。

要允许空输入行,请将/* empty token */规则更改为WS_LINEBREAK

inputs: WS_LINEBRK
    | stmt WS_LINEBRK
    | inputs stmt WS_LINEBRK
    ;

另一方面,由于扫描仪仍然在寻找 SYMB _ EQUAL ;但是解析器不再定义它(它被注释掉),需要做一些事情来编译。一种选择是取消注释%token定义并使用 SYMB _ EQUAL 而不是解析器.y文件中的文字“=”。