Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 旧bison/flex代码无法编译_C_Compiler Errors_Bison - Fatal编程技术网

C 旧bison/flex代码无法编译

C 旧bison/flex代码无法编译,c,compiler-errors,bison,C,Compiler Errors,Bison,我继承了一些非常古老的bison代码,我已经有一段时间没有处理这些代码了,编译失败了,出现了许多警告和错误,我可以解决这些警告,但我不知道如何纠正这些错误。下面是一个例子: 鉴于这组定义: %% pgm: exp { pgm = $1; } exp: list { $$ = dlink(newnode(NULL,NULL),$1); } | exp ';' li

我继承了一些非常古老的bison代码,我已经有一段时间没有处理这些代码了,编译失败了,出现了许多警告和错误,我可以解决这些警告,但我不知道如何纠正这些错误。下面是一个例子:

鉴于这组定义:

    %%
    pgm:    exp                     { pgm = $1; }

    exp:    list                    { $$ = dlink(newnode(NULL,NULL),$1); }
    |       exp ';' list            { $$ = Link($1, dlink(newnode(NULL,NULL),$3)); }

    list:   rec
    |       list ',' rec            { $$ = Link($1, $3); }

    rec:    /* null */              { $$ = newnode(NULL, NULL); }
    |       path
    |       path '@' NAME           { $$ = attribute($1, $3); }
    |       path '(' list ')'       { $$ = dlink($1, $3); }

    path:   NAME                    { $$ = newnode($1, NULL); }
    |       path '.' NAME           { $$ = dlink($1, newnode($3, NULL)); }
    |       path '[' INT ']'        { $$ = dlink($1, newnode($3, $3)); }
    |       path '[' INT '-' INT ']'{ $$ = dlink($1, newnode($3, $5)); }

    %%
这些资料汇编如下:

    bison -d -y gram.y
    gcc -std=c89 -c y.tab.c
我发现以下错误(这只是众多错误之一):


我将回答这个问题,因为它涉及的主题可能会使学习使用bison/yacc的学生和那些正在编译旧代码并对错误来源感到困惑的人(如OP)感到困惑

正如评论中暗示的,这些错误与bison完全无关,而是来自bison文件中包含的C代码,但不是bison的人工制品,也不是由bison或yacc多年来的变化引起的。它们是由多年来C编译器的变化引起的。现代的C编译器比以前的非常旧的编译器宽容(更好),特别是在函数调用和参数检查方面。即使在现代编译器上选择选项以实现向后兼容性时,当以前的编译器可能什么也没说或只是发出警告时,有时仍会产生错误

要证明故障完全在C中,可以执行以下操作:

Prompt> gcc -c -xc -std=c89 -
main () {
#line 49 "gram.y"
int a  = newnode(a,1);
int * b  = newnode(1,1);
}
void *
#line 218 "gram.y"
newnode(name, range)
int name,
range;
{
}
^Z
gram.y: In function 'main':
gram.y:50:12: warning: initialization makes pointer from integer without a cast
[enabled by default]

            ^
gram.y: At top level:
gram.y:218:1: error: conflicting types for 'newnode'
gram.y:49:10: note: previous implicit declaration of 'newnode' was here

          ^
您可以看到,在C的几行代码中,gcc将输出与您看到的相同的错误消息

关于这个问题,以及如何解决这个问题,人们有很多看法:

脚注:可以通过使用或控制错误诊断的级别来关闭某些gcc错误,或将其减少为警告,但在这种情况下是不可能的。这个该行:

#pragma GCC diagnostic warning "-Werror-implicit-function-declaration"
(或类似)也不能消除错误。只是提一下,以防有人想知道

野牛的类型冲突 许多人在bison/yacc中使用类似代码时,确实存在bison检测到的代码类型不匹配问题。为了使答案更加完整,可能需要在这方面添加一些注释。通常情况下,在解析类似于语法的内容时,使用函数
dlink
Link
newnode
属性创建解析树。树将由一些
struct
组成,并通过指向struct
struct*
的指针链接,如下所示:

struct treeNode {
    int  item1,item2;
    struct treeNode *left;
    struct treeNode *right;
  };

typedef  struct treeNode TREE_NODE;
typedef  TREE_NODE        *BINARY_TREE;
BINARY_TREE dlink(BINARY_TREE left, BINARY_TREE right);
BINARY_TREE newnode(int item1, int item2);
BINARY_TREE attribute(BINARY_TREE left, int item);
BINARY_TREE Link(BINARY_TREE left, BINARY_TREE right);
为了避免前面所示的隐式函数类型的问题,我们可以像下面这样声明函数的原型:

struct treeNode {
    int  item1,item2;
    struct treeNode *left;
    struct treeNode *right;
  };

typedef  struct treeNode TREE_NODE;
typedef  TREE_NODE        *BINARY_TREE;
BINARY_TREE dlink(BINARY_TREE left, BINARY_TREE right);
BINARY_TREE newnode(int item1, int item2);
BINARY_TREE attribute(BINARY_TREE left, int item);
BINARY_TREE Link(BINARY_TREE left, BINARY_TREE right);
我们可以将其与您的语法结合起来生成此文件:

%{
#define NULL 0
struct treeNode {
    int  item1,item2;
    struct treeNode *left;
    struct treeNode *right;
  };

typedef  struct treeNode TREE_NODE;
typedef  TREE_NODE        *BINARY_TREE;

BINARY_TREE pgm;
BINARY_TREE dlink(BINARY_TREE left, BINARY_TREE right);
BINARY_TREE newnode(int item1, int item2);
BINARY_TREE attribute(BINARY_TREE left, int item);
BINARY_TREE Link(BINARY_TREE left, BINARY_TREE right);
%}

%token INT NAME

%%
pgm:    exp                     { pgm = $1; }

exp:    list                       {    $$ = dlink(newnode(NULL,NULL),$1); }
    |       exp ';' list            { $$ = Link($1, dlink(newnode(NULL,NULL),$3)); }

list:   rec
    |       list ',' rec            { $$ = Link($1, $3); }

rec:    /* null */              { $$ = newnode(NULL, NULL); }
    |       path
    |       path '@' NAME           { $$ = attribute($1, $3); }
    |       path '(' list ')'       { $$ = dlink($1, $3); }

path:   NAME                    { $$ = newnode($1, NULL); }
    |       path '.' NAME           { $$ = dlink($1, newnode($3, NULL)); }
    |       path '[' INT ']'        { $$ = dlink($1, newnode($3, $3)); }
    |       path '[' INT '-' INT ']'{ $$ = dlink($1, newnode($3, $5)); }

%%
也许你有的是这样的?如果我们把它通过bison和gcc,我们会得到很多警告,但它会生成代码。我注意到你说你有很多警告。也许他们是这样的:

gram.y: In function 'yyparse':
gram.y:23:11: warning: assignment makes pointer from integer without a cast [enabled by default]
 pgm: exp                     { pgm = $1; }
           ^
gram.y:25:5: warning: passing argument 2 of 'dlink' makes pointer from integer without a cast [enabled by default]
 exp:    list                       {    $$ = dlink(newnode(NULL,NULL),$1); }
     ^
gram.y:14:13: note: expected 'BINARY_TREE' but argument is of type 'YYSTYPE'
 BINARY_TREE dlink(BINARY_TREE left, BINARY_TREE right);
             ^
gram.y:25:18: warning: assignment makes integer from pointer without a cast [enabled by default]
 exp:    list                       {    $$ = dlink(newnode(NULL,NULL),$1); }
                  ^
gram.y:26:5: warning: passing argument 2 of 'dlink' makes pointer from integer without a cast [enabled by default]
     |       exp ';' list            { $$ = Link($1, dlink(newnode(NULL,NULL),$3)); }
     ^
gram.y:14:13: note: expected 'BINARY_TREE' but argument is of type 'YYSTYPE'
 BINARY_TREE dlink(BINARY_TREE left, BINARY_TREE right);
gram.y:25:18: warning: assignment makes integer from pointer without a cast [enabled by default]
 exp:    list                       {    $$ = dlink(newnode(NULL,NULL),$1); }
                  ^
gram.y:26:5: warning: passing argument 2 of 'dlink' makes pointer from integer without a cast [enabled by default]
     |       exp ';' list            { $$ = Link($1, dlink(newnode(NULL,NULL),$3
)); }
     ^
gram.y:14:13: note: expected 'BINARY_TREE' but argument is of type 'YYSTYPE'
 BINARY_TREE dlink(BINARY_TREE left, BINARY_TREE right);
             ^
gram.y:26:5: warning: passing argument 1 of 'Link' makes pointer from integer without a cast [enabled by default]
     |       exp ';' list            { $$ = Link($1, dlink(newnode(NULL,NULL),$3
)); }
     ^
gram.y:17:13: note: expected 'BINARY_TREE' but argument is of type 'YYSTYPE'
 BINARY_TREE Link(BINARY_TREE left, BINARY_TREE right);
             ^
gram.y:26:15: warning: assignment makes integer from pointer without a cast [enabled by default]
     |       exp ';' list            { $$ = Link($1, dlink(newnode(NULL,NULL),$3
)); }
               ^
gram.y:29:5: warning: passing argument 1 of 'Link' makes pointer from integer without a cast [enabled by default]
     |       list ',' rec            { $$ = Link($1, $3); }
     ^
gram.y:17:13: note: expected 'BINARY_TREE' but argument is of type 'YYSTYPE'
 BINARY_TREE Link(BINARY_TREE left, BINARY_TREE right);
             ^
gram.y:29:5: warning: passing argument 2 of 'Link' makes pointer from integer without a cast [enabled by default]
     |       list ',' rec            { $$ = Link($1, $3); }
     ^
gram.y:17:13: note: expected 'BINARY_TREE' but argument is of type 'YYSTYPE'
 BINARY_TREE Link(BINARY_TREE left, BINARY_TREE right);
             ^
gram.y:29:15: warning: assignment makes integer from pointer without a cast [enabled by default]
     |       list ',' rec            { $$ = Link($1, $3); }
               ^
gram.y:31:15: warning: assignment makes integer from pointer without a cast [enabled by default]
 rec:    /* null */              { $$ = newnode(NULL, NULL); }
               ^
gram.y:33:5: warning: passing argument 1 of 'attribute' makes pointer from integer without a cast [enabled by default]
     |       path '@' NAME           { $$ = attribute($1, $3); }
     ^
gram.y:16:13: note: expected 'BINARY_TREE' but argument is of type 'YYSTYPE'
 BINARY_TREE attribute(BINARY_TREE left, int item);
             ^
gram.y:33:15: warning: assignment makes integer from pointer without a cast [enabled by default]
     |       path '@' NAME           { $$ = attribute($1, $3); }
               ^
gram.y:34:5: warning: passing argument 1 of 'dlink' makes pointer from integer without a cast [enabled by default]
     |       path '(' list ')'       { $$ = dlink($1, $3); }
     ^
gram.y:14:13: note: expected 'BINARY_TREE' but argument is of type 'YYSTYPE'
 BINARY_TREE dlink(BINARY_TREE left, BINARY_TREE right);
             ^
gram.y:34:5: warning: passing argument 2 of 'dlink' makes pointer from integer without a cast [enabled by default]
     |       path '(' list ')'       { $$ = dlink($1, $3); }
     ^
gram.y:14:13: note: expected 'BINARY_TREE' but argument is of type 'YYSTYPE'
 BINARY_TREE dlink(BINARY_TREE left, BINARY_TREE right);
             ^
gram.y:34:15: warning: assignment makes integer from pointer without a cast [enabled by default]
     |       path '(' list ')'       { $$ = dlink($1, $3); }
               ^
gram.y:36:15: warning: assignment makes integer from pointer without a cast [enabled by default]
 path:   NAME                    { $$ = newnode($1, NULL); }
               ^
gram.y:37:5: warning: passing argument 1 of 'dlink' makes pointer from integer without a cast [enabled by default]
     |       path '.' NAME           { $$ = dlink($1, newnode($3, NULL)); }
     ^
gram.y:14:13: note: expected 'BINARY_TREE' but argument is of type 'YYSTYPE'
 BINARY_TREE dlink(BINARY_TREE left, BINARY_TREE right);
             ^
gram.y:37:15: warning: assignment makes integer from pointer without a cast [enabled by default]
     |       path '.' NAME           { $$ = dlink($1, newnode($3, NULL)); }
               ^
gram.y:38:5: warning: passing argument 1 of 'dlink' makes pointer from integer without a cast [enabled by default]
     |       path '[' INT ']'        { $$ = dlink($1, newnode($3, $3)); }
     ^
gram.y:14:13: note: expected 'BINARY_TREE' but argument is of type 'YYSTYPE'
 BINARY_TREE dlink(BINARY_TREE left, BINARY_TREE right);
             ^
gram.y:38:15: warning: assignment makes integer from pointer without a cast [enabled by default]
     |       path '[' INT ']'        { $$ = dlink($1, newnode($3, $3)); }
               ^
gram.y:39:5: warning: passing argument 1 of 'dlink' makes pointer from integer without a cast [enabled by default]
     |       path '[' INT '-' INT ']'{ $$ = dlink($1, newnode($3, $5)); }
     ^
gram.y:14:13: note: expected 'BINARY_TREE' but argument is of type 'YYSTYPE'
 BINARY_TREE dlink(BINARY_TREE left, BINARY_TREE right);
             ^
gram.y:39:15: warning: assignment makes integer from pointer without a cast [enabled by default]
     |       path '[' INT '-' INT ']'{ $$ = dlink($1, newnode($3, $5)); }
               ^
对于野牛的新用户来说,这可能非常常见。为了消除这些警告,有必要通知bison如何使用这些类型来生成类型正确的代码。这是通过在bison代码中添加两行代码来完成的。首先,我们必须告诉它语法规则操作可以返回的类型:

%union {
  BINARY_TREE tVal;
  int iVal;
  }
%token <iVal> NAME INT
%type <tVal> exp list rec path
然后我们必须告诉它为单个令牌和规则操作返回的类型:

%union {
  BINARY_TREE tVal;
  int iVal;
  }
%token <iVal> NAME INT
%type <tVal> exp list rec path
%token NAME INT
%类型exp list rec path
如果我们将其插入语法文件中,所有错误和警告都将被消除,我们得到:

%{
#define NULL 0
struct treeNode {
    int  item1,item2;
    struct treeNode *left;
    struct treeNode *right;
  };

typedef  struct treeNode TREE_NODE;
typedef  TREE_NODE        *BINARY_TREE;

BINARY_TREE pgm;
BINARY_TREE dlink(BINARY_TREE left, BINARY_TREE right);
BINARY_TREE newnode(int item1, int item2);
BINARY_TREE attribute(BINARY_TREE left, int item);
BINARY_TREE Link(BINARY_TREE left, BINARY_TREE right);
%}
%union {
  BINARY_TREE tVal;
  int iVal;
  }

%token <iVal> NAME INT
%type <tVal> exp list rec path 

%%
pgm:    exp                     { pgm = $1; }

exp:    list                       {    $$ = dlink(newnode(NULL,NULL),$1); }
    |       exp ';' list            { $$ = Link($1, dlink(newnode(NULL,NULL),$3)); }

list:   rec
    |       list ',' rec            { $$ = Link($1, $3); }

rec:    /* null */              { $$ = newnode(NULL, NULL); }
    |       path
    |       path '@' NAME           { $$ = attribute($1, $3); }
    |       path '(' list ')'       { $$ = dlink($1, $3); }

path:   NAME                    { $$ = newnode($1, NULL); }
    |       path '.' NAME           { $$ = dlink($1, newnode($3, NULL)); }
    |       path '[' INT ']'        { $$ = dlink($1, newnode($3, $3)); }
    |       path '[' INT '-' INT ']'{ $$ = dlink($1, newnode($3, $5)); }

%%
%{
#定义空0
树状结构{
int第1项、第2项;
结构树节点*左;
结构树节点*右侧;
};
类型定义结构树节点树节点;
typedef树节点*二叉树;
二叉树pgm;
二叉树链接(左二叉树,右二叉树);
二叉树newnode(int item1,int item2);
二叉树属性(左二叉树,int项);
二叉树链接(左二叉树,右二叉树);
%}
%联合{
二叉树tVal;
国际竞争力;
}
%令牌名称INT
%类型exp list rec path
%%
pgm:exp{pgm=$1;}
exp:list{$$=dlink(newnode(NULL,NULL),$1);}
|exp';'列表{$$=Link($1,dlink(newnode(NULL,NULL),$3));}
名单:rec
|列表“,”rec{$$=Link($1,$3);}
rec://*null*/{$$=newnode(null,null);}
|路径
|路径“@”名称{$$=属性($1,$3);}
|路径“('list')”{$$=dlink($1,$3);}
路径:名称{$$=newnode($1,NULL);}
|路径“.”名称{$$=dlink($1,newnode($3,NULL));}
|路径“['INT']”{$$=dlink($1,newnode($3,$3));}
|路径“['INT'-'INT']”{$$=dlink($1,newnode($3,$5));}
%%

我希望我在C代码中发现了一些类型冲突的方面,这些方面可能会影响bison的新用户或采用其他代码库的用户。

显示gram.y声明newnode的部分。它在哪里,在规则之前还是之后?“newnode的先前隐式声明在这里”。看到了吗?这意味着,
newnode
从未明确声明过,也就是说,
y.lex.c
或其包含的任何标题中没有它的原型。在这样小的背景下回答是不可能的,例如,
NAME
的语义类型是什么?对答案的元评论:我确实将原始问题标记为无法回答,因为我们无法重现该问题。这意味着社区认为它应该得到一个答案,所以我做了一个。这并不是说社区认为它应该得到一个答案,而是社区没有足够快地审查国旗(或者版主没有足够快地处理队列)。