使用Flex和Bison编译时未定义对_yyerror的引用 [英] Undefined reference to `_yyerror' when compiling with Flex and Bison

查看:139
本文介绍了使用Flex和Bison编译时未定义对_yyerror的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为一种类似于Pascal的迷你语言编写编译器.我为此使用了Flex和Bison,但出现了这个错误.

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文件:

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

我的野牛文件:

%{
    #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!

推荐答案

仅仅声明 yyerror 是不够的.您必须提供一个定义.

It's not enough to declare yyerror. You must provide a definition.

野牛手册建议将以下内容作为最低限度的实现:

The bison manual suggests the following as a minimal implementation:

 void yyerror (char const *s) {
   fprintf (stderr, "%s\n", s);
 }

您遇到的另一个问题是在flex文件中拼错了 strcpy .

The other problem you have is that you misspelled strcpy in your flex file.

更准确地说,链接器错误显示的另一个问题是拼写错误的 strcpy ,因为您的复制代码不正确.它不考虑必须终止字符串的 NUL 字节. strcpy 将复制该字节,结果将在未分配的存储中写入 0 .您会发现使用 strdup 更简单.(并且不要忘了在完成字符串处理后需要释放字符串.)

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.)

这篇关于使用Flex和Bison编译时未定义对_yyerror的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆