Как скомпилировать программы, созданные с помощью Yacc и Lex? - PullRequest
1 голос
/ 11 января 2011

Мой источник Yacc находится в pos.yacc, а мой источник Lex в pos1.lex, как показано.

pos1.lex

%{
#include "y.tab.h"

int yylval;
%}
DIGIT [0-9]+
%%
{DIGIT} {yylval=atoi(yytext);return DIGIT;}
[\n ] {}
. {return *yytext;}
%%

pos.yacc

%token DIGIT
%%
s:e {printf("%d\n",$1);}
e:DIGIT {$$=$1;}
|e e "+" {$$=$1+$2;}
|e e "*" {$$=$1*$2;}
|e e "-" {$$=$1-$2;}
|e e "/" {$$=$1/$2;}
;
%%
main() {
  yyparse();
}
yyerror() {
  printf("Error");
}

Ошибки компиляции

При компиляции я получаю сообщения об ошибках типа:

malathy@malathy:~$ cc lex.yy.c  y.tab.c -ly -ll
pos.y: In function ‘yyerror’:
pos.y:16: warning: incompatible implicit declaration of built-in function ‘printf’
pos.y: In function ‘yyparse’:
pos.y:4: warning: incompatible implicit declaration of built-in function ‘printf’

  • Что вызывает эти ошибки?
  • Как мне скомпилировать исходный код Lex и Yacc?

Ответы [ 3 ]

3 голосов
/ 11 января 2011

printf () определено в stdio.h, поэтому просто включите его выше y.tab.h в pos1.lex:

%{
#include <stdio.h>
/* Add  ^^^^^^^^^^^ this line */
#include "y.tab.h"

  int yylval;
%}
DIGIT [0-9]+
%%
{DIGIT} {yylval=atoi(yytext);return DIGIT;}
[\n ] {}
. {return *yytext;}
%%
2 голосов
/ 11 января 2011

У вас есть прямой ответ на ваш вопрос от trojanfoe - вам нужно включить <stdio.h>, чтобы объявить функцию printf(). Это верно в любом исходном коде, представленном компилятору C.

Однако следует также отметить, что условный суффикс для источника Yacc равен .y (вместо .yacc), а для источника Lex - .l (вместо .lex). В частности, использование этих суффиксов означает, что make будет знать, что делать с вашим исходным кодом, вместо необходимости вручную кодировать правила компиляции.


Данные файлы lex.l и yacc.y, make компилируют их в объектный код, используя:

$ make lex.o yacc.o
rm -f lex.c 
lex  -t lex.l > lex.c
cc -O -std=c99 -Wall -Wextra -c -o lex.o lex.c
yacc  yacc.y 
mv -f y.tab.c yacc.c
cc -O -std=c99 -Wall -Wextra -c -o yacc.o yacc.c
rm lex.c yacc.c
$

Это каталог с make-файлом, который устанавливает CFLAGS = -O -std=c99 -Wall -Wextra. (Это было в MacOS X 10.6.6.) Иногда вы увидите другие подобные правила; в частности, lex генерирует файл lex.yy.c по умолчанию (по крайней мере, в MacOS X), и вы часто будете видеть правило, такое как:

lex lex.l
mv lex.yy.c lex.c
cc -O -std=c99 -Wall -Wextra -c -o lex.o lex.c

Или даже:

lex lex.l
cc -O -std=c99 -Wall -Wextra -c -o lex.o lex.yy.c

Альтернативы легион; используйте make, и все правильно.

0 голосов
/ 05 ноября 2017

Включить заголовочный файл stdio.h

для компиляции Откройте терминал, найдите оба файла и введите

lex pos1.l

yacc pos.y

cc lex.yy.c y.tab.h -ll

./a.out

Вы можете выполнить следующие шаги.

...