Неопределенная ссылка на 'yyerror' при компиляции с Flex и Bison
Я пытаюсь сделать компилятор для мини-Паскаль-подобного языка. Я использую Flex и Bison для этого, и я придумал эту ошибку.
мой Flex файл:
%{
#include "y.tab.h"
#include <stdlib.h>
#include <string.h>
#include <math.h>
void yyerror(char *);
%}
%%
[1-9][0-9]* {
yylval.i = atoi(yytext);
return INT;
}
program return PROGRAM;
or return OR;
and return AND;
not return NOT;
if return IF;
else return ELSE ;
while return WHILE;
"+" return PLUS;
"-" return MINUS;
"*" return MUL;
"/" return DIV;
"[" return LSB;
"]" return RSB;
"{" return LCB;
"}" return RCB;
"(" return LEFTPAR;
")" return RIGHTPAR;
":=" return ASSIGN;
"==" return ISEQUAL;
"<" return LTHAN;
">" return GTHAN;
"<>" return NOTEQUAL;
"<=" return LESSEQUAL;
">=" return GREATEREQUAL;
[a-zA-z][a-z0-9]* {
yylval.s = (char*)malloc(strlen(yytext)*sizeof(char));
strcopy(yylval.s,yytext);
return ID;
}
[ tn]+ /* eat up whitespace */
. yyerror("Unknown Character");
%%
int yywrap(void) {
return 1;
}
мой файл Bison:
%{
#include <stdio.h>
#include <string.h>
int yylex(void);
void yyerror(char *s);
%}
%union {
int i;
char *s;
};
%token <i> INTEGERNUM
%token PROGRAM;
%token OR;
%token AND;
%token NOT;
%token IF;
%token ELSE;
%token WHILE;
%token PLUS;
%token MINUS;
%token MUL;
%token DIV;
%token LSB;
%token RSB;
%token LCB;
%token RCB;
%token LEFTPAR;
%token RIGHTPAR;
%token ID;
%token INT;
%token ASSIGN;
%token ISEQUAL;
%token LTHAN;
%token GTHAN;
%token NOTEQUAL;
%token LESSEQUAL;
%token GREATEREQUAL;
%%
program:
PROGRAM ID block
;
block:
LCB sequence RCB
;
sequence:
statement ';' sequence
| statement ';'
;
bracketsSeq:
LCB sequence RCB
;
brackOrStat:
bracketsSeq
| statement
;
statement:
assignmentStat
|ifStat
|whileStat
|
;
assignmentStat:
ID ':=' expression
ifStat:
IF LEFTPAR condition RIGHTPAR brackOrStat elsepart
;
elsepart:
ELSE brackOrStat
|
;
whileStat:
WHILE LEFTPAR condition RIGHTPAR brackOrStat
;
expression:
optionalSign expression
|expression addOper expression
|term
;
term:
term mulOper term
|factor
;
factor:
INT
|LEFTPAR expression RIGHTPAR
|ID
;
condition:
condition AND condition
|boolterm
;
boolterm:
boolterm OR boolterm
|boolfactor
;
boolfactor:
NOT LSB condition RSB
|LSB condition RSB
|expression relationalOper expression
;
relationalOper:
ISEQUAL
|LTHAN
|GTHAN
|NOTEQUAL
|LESSEQUAL
|GREATEREQUAL
;
addOper:
PLUS
|MINUS
;
mulOper:
MUL
|DIV
;
optionalSign:
addOper
|
;
%%
int main( int argc, char **argv )
{
printf("TESTn");
}
серия шагов, которые я выполнил, была:
$ ./bison.exe -dy comp.y
$ ./flex.exe comp.l
$ gcc -c -w lex.yy.c
$ gcc -c -w comp.tab.c
$ gcc comp.tab.o lex.yy.o -o ex
comp.tab.o:comp.tab.c:(.text+0x4cd): undefined reference to `_yyerror'
comp.tab.o:comp.tab.c:(.text+0x61c): undefined reference to `_yyerror'
lex.yy.o:lex.yy.c:(.text+0x34a): undefined reference to `_strcopy'
lex.yy.o:lex.yy.c:(.text+0x362): undefined reference to `_yyerror'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: lex.yy.o: bad reloc address 0x828 in section `.rdata'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: final link failed: Invalid operation
collect2: ld returned 1 exit status
$
любой совет относительно того, что объявить и где причина, кажется, что я объявил что-то не так!
1 ответов
недостаточно объявить yyerror
. Необходимо предоставить определение.
на ручной Зубр предлагает следующее в качестве минимальной реализации:
void yyerror (char const *s) {
fprintf (stderr, "%s\n", s);
}
другая проблема у вас есть, что вы неправильно написали strcpy
в вашем файле flex.
точнее, другая проблема, выявленная ошибками компоновщика, - это ошибка strcpy
, потому что ваш код копировать некорректно. Это не учитывает NUL
байт, которые должны прекратить строки. strcpy
скопирует этот байт, в результате чего он напишет 0
в незанятое хранения. Вы найдете его гораздо проще использовать strdup
. (И не забывайте, что вам нужно free
строки, Когда вы закончите с ними.)