当我在yacc中引入一个动作时,Shift/减少冲突

Shift/Reduce conflict when I introduce an action in yacc

本文关键字:Shift 冲突 一个 yacc      更新时间:2023-10-16

我正在为我的C编译器编写前端,目前我正在添加类型系统。之前我假设所有内容都是int类型,因此下面的规则工作得很好。

declaration: datatype varList ';' { gTrace<<"declaration ";}
varList: IDENTIFIER { builder.addSymbol($1); }
    | varList',' IDENTIFIER { builder.addSymbol($3); }
    ;

但是现在我还为符号添加了类型,因此修改了我的规则,如下所示:

 declaration: datatype { currentType = $1; } varList ';' { gTrace<<"declaration ";   currentType = -1; }
 varList: IDENTIFIER    { builder.addSymbol($1, getType(currentType)); }
    | varList',' IDENTIFIER { builder.addSymbol($3, getType(currentType)); }
    ;

当我这样做时,我得到一个shift/reduce错误,因为{currentType = $1;}被认为是空规则。我该如何处理这个错误?是否有一种方法可以指定它只是一个动作?

下面是我的y.p output

的一个片段。
32 $@6: /* empty */
33 declaration: datatype $@6 varList ';'
34 varList: IDENTIFIER
35        | varList ',' IDENTIFIER

我没有得到任何错误或警告:

%token   INT
%token   FLOAT
%token   CHAR
%token   IDENTIFIER
%%
declaration: datatype { currentType = $1; } varList ';' { gTrace<<"declaration ";   currentType = -1; }
varList : IDENTIFIER                { builder.addSymbol($1, getType(currentType)); }
        | varList  ',' IDENTIFIER   { builder.addSymbol($3, getType(currentType)); }
        ;
datatype:   INT
        |   FLOAT
        |   CHAR
        ;
%%

命令

% bison p.yacc
%

我想你需要提供更多的信息。

完整的yacc文件和传递给yacc/bison的参数

编辑

我尝试了你的文件(根据评论),我仍然没有得到错误或警告:

> yacc --version
bison (GNU Bison) 2.3
Written by Robert Corbett and Richard Stallman.
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

我修复的问题如下:

declaration: datatype varList ';' { gTrace<<"declaration "; currentType = -1; }
varList: IDENTIFIER { builder.addSymbol($1, getType(currentType)); }
    | varList',' IDENTIFIER { builder.addSymbol($3, getType(currentType)); }
    ;
datatype: INTEGER   { gTrace<<"int "; $$ = currentType = Type::IntegerTy; }
    | FLOAT     { gTrace<<"float "; $$ = currentType = Type::FloatTy; }
    | VOID      { gTrace<<"void "; $$ = currentType = Type::VoidTy; }
    ;

@sarnold,希望这对你有帮助!

我觉得你只能为每条规则定义一个动作块,所以

declaration: datatype { currentType = $1; } varList ';' { gTrace<<"declaration ";   currentType = -1; }

应按

处理
declaration: datatype varList ';' { currentType = $1; gTrace<<"declaration ";   currentType = -1; }
无论如何,您将currentType设置为数据类型的词法值,并在
之后设置为-1