I'm trying to make a compiler for a mini Pascal-like language. I'm using Flex and Bison for this and I came up with this error.
我想让编译器变成一种小型的帕斯卡语言。我用Flex和Bison来做这个,我想出了这个错误。
My Flex file:
我的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;
}
[ \t\n]+ /* eat up whitespace */
. yyerror("Unknown Character");
%%
int yywrap(void) {
return 1;
}
My Bison file:
我的野牛文件:
%{
#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("TEST\n");
}
The series of steps I executed was:
我执行的一系列步骤是:
$ ./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
$
Any advice as to what to declare and where cause there seems to be that I have declared something the wrong way!
关于该声明什么,以及在什么地方引起的任何建议,似乎我已经声明了错误的方式!
1 个解决方案
#1
14
It's not enough to declare yyerror
. You must provide a definition.
仅仅声明yyerror是不够的。您必须提供一个定义。
The bison manual suggests the following as a minimal implementation:
bison手册建议将以下内容作为最小的实现:
void yyerror (char const *s) {
fprintf (stderr, "%s\n", s);
}
The other problem you have is that you misspelled strcpy
in your flex file.
另一个问题是在flex文件中拼写错误。
More accurately, the other problem revealed by the linker errors is the misspelled strcpy
, because your copying code is incorrect. It does not account for the NUL
byte which must terminate strings. strcpy
will copy that byte, with the result that it will write a 0
in unallocated storage. You'll find it much simpler to use strdup
. (And don't forget that you need to free
the strings when you're finished with them.)
更准确地说,链接器错误显示的另一个问题是拼写错误的strcpy,因为您的复制代码是错误的。它不考虑必须终止字符串的NUL字节。strcpy将复制该字节,结果将在未分配的存储中写入0。您会发现使用strdup更简单。(别忘了,当你完成这些字符串时,你需要释放它们。)
#1
14
It's not enough to declare yyerror
. You must provide a definition.
仅仅声明yyerror是不够的。您必须提供一个定义。
The bison manual suggests the following as a minimal implementation:
bison手册建议将以下内容作为最小的实现:
void yyerror (char const *s) {
fprintf (stderr, "%s\n", s);
}
The other problem you have is that you misspelled strcpy
in your flex file.
另一个问题是在flex文件中拼写错误。
More accurately, the other problem revealed by the linker errors is the misspelled strcpy
, because your copying code is incorrect. It does not account for the NUL
byte which must terminate strings. strcpy
will copy that byte, with the result that it will write a 0
in unallocated storage. You'll find it much simpler to use strdup
. (And don't forget that you need to free
the strings when you're finished with them.)
更准确地说,链接器错误显示的另一个问题是拼写错误的strcpy,因为您的复制代码是错误的。它不考虑必须终止字符串的NUL字节。strcpy将复制该字节,结果将在未分配的存储中写入0。您会发现使用strdup更简单。(别忘了,当你完成这些字符串时,你需要释放它们。)