链接器错误Yacc在Mac上

时间:2014-12-01 02:18:09

标签: bison yacc flex-lexer lex

当我尝试编译时,我收到此错误。我之前编译过lex文件没有问题我似乎无法编译yacc而没有错误。

:~ yacc project-5.y 
:~ lex  project.l 
:~g++ -o $dragon project-5.tab.c lex.yy.c 
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
Undefined symbols for architecture x86_64:
"_main", referenced from:
 implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

使用-c标志编译时。我不明白为什么它似乎编译但有错误。

test-5.tab.c:1246:16: warning: implicit declaration of function 'yylex' is invalid in C99 [-Wimplicit-function-declaration]
  yychar = YYLEX;
           ^
  test-5.tab.c:601:15: note: expanded from macro 'YYLEX'
  #define YYLEX yylex ()
          ^
  test-5.tab.c:1374:7: warning: implicit declaration of function 'yyerror' is invalid in C99 [-     Wimplicit-function-declaration]
  yyerror (YY_("syntax error"));
  ^
  test-5.y:35:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  main(int argc, char **argv)
  ^~~~
  test-5.y:40:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  yyerror(char *s)
  ^~~~~~~
  test-5.y:42:1: warning: control reaches end of non-void function [-Wreturn-type]
  }

LEX代码

%option noyywrap
%{
# include "project.tab.h"
%}

Delimiter               [ \t\n]
WhiteSpace              {Delimiter}+
Letter                  [A-za-z]
Digit                   [0-9]
E_Notation              E("+"|"-")?({Digit})+
Var                     ("_"|{Letter})(({Letter}|{Digit})+("_")?)*
UnsignedInteger         {Digit}*
UnsignedFloatingPoint   (({Digit})+(".")({Digit})*({E_Notation})?|({Digit}*(".")?({Digit})+            {E_Notation}?))
factor                  {UnsignedInteger}|{UnsignedFloatingPoint}|{Var}
term                    {factor}(("*"|"/"|"%"){factor})*
expression              {term}(("+"|"-"){term})*
Op                      ("+"|"-")
Op2                     ("*"|"/"|"%")
RelOp                   ("<"|"<="|"=<"|"=="|"!="|">"|">="|"=>"|".LT."|".LE."|".EL."|".EQ."|".NE."|".GT."|".GE."|".EG.")
LogOp                   ("!"|"||"|"&&"|".NOT."|".OR."|".AND.")
LogCons                 (".TRUE."|".FALSE.")
function                {Var}+"("{factor}*")"
Punct                   (";"|"("|")")
UnaryOp                 ("+"|"-")|[^{factor}]
%%
{Var}                   {return Var;}
{UnsignedInteger}       {return UnsignedInteger;}
{UnsignedFloatingPoint} {return UnsignedFloatingPoint;}
{Op}                    {return Op;}
{RelOp}                 {return RelOp;}
{LogOp}                 {return LogOp;}
{LogCons}               {return LogCons;}
{Punct}                 {return Punct;}
{function}              {return Function;}
\n                      {return EOL;}



%%

YACC代码

 /* simplest version of calculator */
 %{
 #include <stdlib.h>
 #include <stdio.h>

 %}
 /* declare tokens */
 %token Var
 %token UnsignedInteger
 %token UnsignedFloatingPoint
 %token Op
 %token Op2
 %token RelOp
 %token LogOp
 %token LogCons
 %token Punct
 %token Function
 %token EOL
 %%

stmt:   /* empty */
|stmt exp EOL {printf("Ok\n");}
|stmt error EOL {printf("Error\n");}
exp: term
| term Op exp
;
factor: Var
| UnsignedInteger
| UnsignedFloatingPoint
;
term: factor
| factor Op2 term
 ;
%%

int main(int argc, char **argv)
{
yyparse();
return 0;
}
int yyerror(char *s)
{
return 0;
 }

2 个答案:

答案 0 :(得分:3)

OSX上的bison的默认版本是一个相当古老的v2.3,它生成C89代码(与C99或C ++不兼容,因为您显示的错误/警告)。您可以使用-std=c89进行编译,也可以通过向.y文件的第一部分添加前向声明来使其更兼容:

%{
int yylex();
int yyerror(char *);
%}

这将修复有关未定义函数的C99警告/ C ++错误,但会留下关于滥用字符串文字的警告。如果你还修复了由Brian Tompsett识别的文件名不匹配和.l文件中UnsignedFloatingPoint定义中的(可能的剪切粘贴引起的)拼写错误空格,你应该得到一个可运行的可执行文件。

答案 1 :(得分:2)

您似乎包含yacc输出的不同版本,这可能会给您编译错误?

您将yacc project-5.y的输出放在编译行中:

g++ -o $dragon project-5.tab.c lex.yy.c 

然后在project.l中你有以下内容:

%{
# include "project.tab.h"
%}

这可能是早期project.y文件中yacc的输出,该文件可能已更改,从而导致代码版本之间存在某些不兼容性....