LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1329|回复: 4

求助:lex与yacc使用中的连接报错,如何解决?

[复制链接]
发表于 2006-3-14 16:53:53 | 显示全部楼层 |阅读模式
正在学习使用lex和yacc.用lex 和yacc 构建一个计算器。操作流程如下 :
[root@wy myvhdl]# cd code3
[root@wy code3]# ls
calc3a.c  calc3b.c  calc3g.c  calc3.h  calc3.l  calc3.y
[root@wy code3]# lex calc3.l
[root@wy code3]# ls
calc3a.c  calc3b.c  calc3g.c  calc3.h  calc3.l  calc3.y  lex.yy.c
[root@wy code3]# yacc -d calc3.y
[root@wy code3]# ls
calc3a.c  calc3g.c  calc3.l  lex.yy.c  y.tab.h
calc3b.c  calc3.h   calc3.y  y.tab.c
[root@wy code3]# cc -c lex.yy.c y.tab.c
[root@wy code3]# ls
calc3a.c  calc3g.c  calc3.l  lex.yy.c  y.tab.c  y.tab.o
calc3b.c  calc3.h   calc3.y  lex.yy.o  y.tab.h
[root@wy code3]# cc -o calc3 lex.yy.o y.tab.o -ll
y.tab.o(.text+0x61c): In function `yyparse':
: undefined reference to `ex'
collect2: ld returned 1 exit status

不知道这种错误是什么样的错误,如何解决呢?请高手相助。不胜感激!

附程序:
calc3.l:

%{
#include <stdlib.h>
#include "calc3.h"
#include "y.tab.h"
void yyerror(char *);
%}
                                                                                
%%
                                                                                
[a-z]       {
                yylval.sIndex = *yytext - 'a';
                return VARIABLE;
            }
                                                                                
[0-9]+      {
                yylval.iValue = atoi(yytext);
                return INTEGER;
            }
                                                                                
[-()<>=+*/;{}.] {
                return *yytext;
             }
                                                                                
">="            return GE;
"<="            return LE;
"=="            return EQ;
"!="            return NE;
"while"         return WHILE;
"if"            return IF;
"else"          return ELSE;
"print"         return PRINT;
                                                                                
[ \t\n]+        ;       /* ignore whitespace */
                                                                                
.               yyerror("Unknown character");
%%
int yywrap(void) {
    return 1;
}


calc3.y:

%{
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "calc3.h"
                                                                                
/* prototypes */
nodeType *opr(int oper, int nops, ...);
nodeType *id(int i);
nodeType *con(int value);
void freeNode(nodeType *p);
int ex(nodeType *p);
int yylex(void);
                                                                                
void yyerror(char *s);
int sym[26];                    /* symbol table */
%}
                                                                                
%union {
    int iValue;                 /* integer value */
    char sIndex;                /* symbol table index */
    nodeType *nPtr;             /* node pointer */
};
%token <iValue> INTEGER
%token <sIndex> VARIABLE
%token WHILE IF PRINT
%nonassoc IFX
%nonassoc ELSE
                                                                                
%left GE LE EQ NE '>' '<'
%left '+' '-'
%left '*' '/'
%nonassoc UMINUS
                                                                                
%type <nPtr> stmt expr stmt_list
                                                                                
%%
                                                                                
program:
        function                { exit(0); }
        ;
                                                                                
function:
          function stmt         { ex($2); freeNode($2); }
        | /* NULL */
        ;
                                                                                
stmt:
          ';'                            { $$ = opr(';', 2, NULL, NULL); }
        | expr ';'                       { $$ = $1; }
        | PRINT expr ';'                 { $$ = opr(PRINT, 1, $2); }
        | VARIABLE '=' expr ';'          { $$ = opr('=', 2, id($1), $3); }
        | WHILE '(' expr ')' stmt        { $$ = opr(WHILE, 2, $3, $5); }
        | IF '(' expr ')' stmt %prec IFX { $$ = opr(IF, 2, $3, $5); }
        | IF '(' expr ')' stmt ELSE stmt { $$ = opr(IF, 3, $3, $5, $7); }
        | '{' stmt_list '}'              { $$ = $2; }
        ;
                                                                                
stmt_list:
          stmt                  { $$ = $1; }
        | stmt_list stmt        { $$ = opr(';', 2, $1, $2); }
        ;
                                                                                
expr:
          INTEGER               { $$ = con($1); }
        | VARIABLE              { $$ = id($1); }
        | '-' expr %prec UMINUS { $$ = opr(UMINUS, 1, $2); }
        | expr '+' expr         { $$ = opr('+', 2, $1, $3); }
        | expr '-' expr         { $$ = opr('-', 2, $1, $3); }
        | expr '*' expr         { $$ = opr('*', 2, $1, $3); }
        | expr '/' expr         { $$ = opr('/', 2, $1, $3); }
        | expr '<' expr         { $$ = opr('<', 2, $1, $3); }
        | expr '>' expr         { $$ = opr('>', 2, $1, $3); }
        | expr GE expr          { $$ = opr(GE, 2, $1, $3); }
        | expr LE expr          { $$ = opr(LE, 2, $1, $3); }
        | expr NE expr          { $$ = opr(NE, 2, $1, $3); }
        | expr EQ expr          { $$ = opr(EQ, 2, $1, $3); }
        | '(' expr ')'          { $$ = $2; }
        ;
                                                                                
%%
                                                                                
#define SIZEOF_NODETYPE ((char *)&p->con - (char *)p)
                                                                                
nodeType *con(int value) {
    nodeType *p;
    size_t nodeSize;
                                                                                
    /* allocate node */
    nodeSize = SIZEOF_NODETYPE + sizeof(conNodeType);
    if ((p = malloc(nodeSize)) == NULL)
        yyerror("out of memory");
                                                                                
    /* copy information */
    p->type = typeCon;
    p->con.value = value;
                                                                                
    return p;
}
                                                                                
nodeType *id(int i) {
    nodeType *p;
    size_t nodeSize;
                                                                                
    /* allocate node */
    nodeSize = SIZEOF_NODETYPE + sizeof(idNodeType);
    if ((p = malloc(nodeSize)) == NULL)
        yyerror("out of memory");
                                                                                
    /* copy information */
    p->type = typeId;
    p->id.i = i;
                                                                                
    return p;
}
                                                                                
nodeType *opr(int oper, int nops, ...) {
    va_list ap;
    nodeType *p;
    size_t nodeSize;
    int i;
                                                                                
    /* allocate node */
    nodeSize = SIZEOF_NODETYPE + sizeof(oprNodeType) +
        (nops - 1) * sizeof(nodeType*);
    if ((p = malloc(nodeSize)) == NULL)
        yyerror("out of memory");
                                                                                
    /* copy information */
    p->type = typeOpr;
    p->opr.oper = oper;
    p->opr.nops = nops;
    va_start(ap, nops);
    for (i = 0; i < nops; i++)
        p->opr.op = va_arg(ap, nodeType*);
    va_end(ap);
    return p;
}
                                                                                
void freeNode(nodeType *p) {
    int i;
                                                                                
    if (!p) return;
    if (p->type == typeOpr) {
        for (i = 0; i < p->opr.nops; i++)
            freeNode(p->opr.op);
    }
    free (p);
}
                                                                                
void yyerror(char *s) {
    fprintf(stdout, "%s\n", s);
}
                                                                                
int main(void) {
    yyparse();
    return 0;
}


calc3.h:

typedef enum { typeCon, typeId, typeOpr } nodeEnum;
                                                                                
/* constants */
typedef struct {
    int value;                  /* value of constant */
} conNodeType;
                                                                                
/* identifiers */
typedef struct {
    int i;                      /* subscript to sym array */
} idNodeType;
                                                                                
/* operators */
typedef struct {
    int oper;                   /* operator */
    int nops;                   /* number of operands */
    struct nodeTypeTag *op[1];  /* operands (expandable) */
} oprNodeType;
                                                                                
typedef struct nodeTypeTag {
    nodeEnum type;              /* type of node */
                                                                                
    /* union must be last entry in nodeType */
    /* because operNodeType may dynamically increase */
    union {
        conNodeType con;        /* constants */
        idNodeType id;          /* identifiers */
        oprNodeType opr;        /* operators */
    };
} nodeType;
                                                                                
extern int sym[26];
发表于 2006-3-14 19:07:38 | 显示全部楼层
在.l文件的头部声明extern int(NodeTyep *);试试?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-3-14 21:51:14 | 显示全部楼层

非常感谢!已经试了,在对两个C文件编译时报错。

Post by gnap
在.l文件的头部声明extern int(NodeTyep *);试试?




加处后执行:
[root@wy code3]# lex calc3.l
[root@wy code3]# yacc -d calc3.y
[root@wy code3]# cc -c lex.yy.c y.tab.c
calc3.l:6: parse error before '*' token


小弟初学这些东西,比较晕。谢谢老兄的帮助,更希望老兄能够做出进一步的指导。
真的非常感谢!
回复 支持 反对

使用道具 举报

发表于 2006-3-15 02:58:21 | 显示全部楼层
function:
function stmt { ex($2); freeNode($2); }


你压根儿就没有定义ex. link当然会出错了。
其他的建议:

1. 不要用root 工作。
2. 写一个Makefile吧,节省很多时间的。——比如:http://cs.gmu.edu/~white/CS540/Examples/Makefile_gram
3. 下次提问,把所有的代码顺便打个tarball放上来好吗?
4. 用flex吧,更多的支持。
5. 编译flex, bison(aka yacc alternative)用的link选项应该是 -ly -fl
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-3-16 20:30:32 | 显示全部楼层

问题已解决,谢谢各位了!

Post by bookstack
你压根儿就没有定义ex. link当然会出错了。
其他的建议:

1. 不要用root 工作。
2. 写一个Makefile吧,节省很多时间的。——比如:http://cs.gmu.edu/~white/CS540/Examples/Makefile_gram
3. 下次提问,把所有的代码顺便打个tarball放上来好吗?
4. 用flex吧,更多的支持。
5. 编译flex, bison(aka yacc alternative)用的link选项应该是 -ly -fl



加入了含有ex函数的C程序,可以正常运行了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表