野牛输出文件编译时对“ main”的多重定义

时间:2019-06-07 13:11:30

标签: c parsing bison

所以我正在编写一个野牛(没有lex)解析器,现在我想从文件中读取输入代码,并将输出写入另一个文件。

搜索stackoverflow一段时间后,我发现这种方式应该不错。 bison.y:

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

    extern FILE *yyin;

    int yylex() { return getc(stdin); }
    void yyerror(char *s) {
      fprintf (stderr, "%s\n", s);
    }
    int counter = 1;
    char filename2[10] = "dest.ll";
    FILE *f2;
%}
%name parse

%%

//grammars

%%

int main(int argc, char *argv[]) {
    yyin = fopen(argv[1], "r");
    if (argc > 2)
      f2 = fopen(argv[2], "w");
    else
      f2 = fopen(filename2, "w");
    yyparse();

    return 0;
} 

然后我这样编译:

bison bison.y
cc -ly bison.tab.c

这里是cc编译的结果:

/tmp/ccNqiuhW.o: In function `main':
bison.tab.c:(.text+0x960): multiple definition of `main'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/liby.a(main.o):(.text.startup+0x0): first defined here
/tmp/ccNqiuhW.o: In function `main':
bison.tab.c:(.text+0x98c): undefined reference to `yyin'
collect2: error: ld returned 1 exit status

输出bison.tab.c文件只有1个主要文件。 Ofc int / void main无关紧要。你能教我正确的方法吗?

P.S。顺便说一句,我不想​​向其他帖子发送垃圾邮件,在这里有一个小问题。如何在野牛的$$中存储字符串(char *)?例如,我想在遇到int语法后生成一个代码字符串。我遇到此错误,找不到答案:

bison.y:94:8: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
 INTNUM: NUMBER | DIGIT INTNUM {$$ = "string"};

bison.y: In function ‘yyparse’:
bison.y:28:15: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=]
 PROGRAM: EXPRS { fprintf(f2, "%s: string here %d.\n", $$, counter++) };
如果找到帮助,

将非常好。

1 个答案:

答案 0 :(得分:2)

您正在链接库liby(链接器选项-ly)。 The Bison manual对此有话要说:

  

Yacc库包含yyerror和   main个功能。

这就是为什么您有main的多个定义的原因。您提供一个,自由中就有一个。

此外,文档继续说

  

这些默认实现通常没有用,但是POSIX需要它们。

(添加了强调)

您不需要链接liby 即可构建包含由野牛生成的解析器的程序,通常您不应该这样做。而是提供您自己的main()和自己的yyerror(),两者都已完成。

此外,无论是否链接liby,都应提供yyin定义,而不仅仅是声明。为此,请从语法文件中的extern声明中删除yyin关键字。

您的语法不完整(根本没有规则),%name指令未记录下来,Bison也无法识别,但是如果我添加了虚拟规则并注释掉{{1} },并结合讨论的其他更改,然后%name为我生成一个C源文件,该文件可以成功编译为可执行文件(没有liby)。