Ошибка компоновщика Yacc на Mac

Я получаю эту ошибку, когда пытаюсь скомпилировать. Раньше я компилировал файлы 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]
  }

ЛЕКС-код

%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;
 }

person user1184034    schedule 01.12.2014    source источник
comment
Давайте рассмотрим эти сообщения об ошибках. Начните с первого вопроса: почему вы используете g++ для компиляции чего-то, что не является C++?   -  person    schedule 01.12.2014
comment
На самом деле я тестировал g++, но использовал gcc и получил те же ошибки.   -  person user1184034    schedule 01.12.2014


Ответы (2)


Версия bison по умолчанию в OSX — это довольно древняя версия 2.3, которая генерирует код C89 (несовместимый ни с C99, ни с C++, как показывают ошибки/предупреждения, которые вы получаете). Вы можете скомпилировать с помощью -std=c89 или сделать его более совместимым, добавив предварительные объявления в первый раздел файла .y:

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

Это исправит предупреждения/ошибки C++ C99 о неопределенных функциях, но оставит предупреждения о неправильном использовании строковых литералов. Если вы также исправите несоответствие имени файла, обнаруженное Брайаном Томпсеттом, и опечатки (возможно, вызванные вырезанием и вставкой) в определении UnsignedFloatingPoint в файле .l, вы должны получить работоспособный исполняемый файл.

person Chris Dodd    schedule 27.12.2014

Кажется, вы включаете разные версии вывода yacc, что, возможно, дает вам ошибки компиляции?

Вы помещаете вывод yacc project-5.y в строку компиляции:

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

но тогда в project.l у вас есть следующее:

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

что, возможно, является выводом yacc в более раннем файле project.y, который мог измениться и, таким образом, вызвать некоторую несовместимость между версиями кода....

person Brian Tompsett - 汤莱恩    schedule 27.12.2014