LinuxSir.cn,穿越时空的Linuxsir!

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

有关于lex和yacc的一个问题,大家看看

[复制链接]
发表于 2006-3-22 17:32:57 | 显示全部楼层 |阅读模式
最近需要学习lex和yacc,尝试着写了一些文件来编译,开始比较简单的还可以,但是后面复杂了一点点就不行了,我现在作的一个练习是这样的,成对的读入 父-子 节点对描述,把他们连接起来,构成一颗树,但是老是失败,希望大家看看,帮我分析一下原因。先谢谢大家了。

思路是:读入节点对,如2 1 1 9 2 3
则构成的树是以2为根,1 3 为其儿子节点,9为2的儿子的一棵树。
使用 lex tree.l
yacc -d tree.y后,需要手工把y.tab.c 中的define YYSTYPE string 拷贝到y.tab.h中,
编译后总是显示错误:

/tmp/ccEDUIuE.o(.bss+0x0): multiple definition of `treeIndex'
/tmp/ccJnHUxB.o(.bss+0x0): first defined here
/tmp/ccpIcrmv.o(.bss+0x30): multiple definition of `treeIndex'
/tmp/ccJnHUxB.o(.bss+0x0): first defined here
collect2: ld returned 1 exit status
希望大家看看我的问题,帮我解答

下面是我的几个文件:
tree.l lex文件
tree.y yacc文件
tree.h 头文件包含和函数声明,
tree.c 头文件实现


/////////////////////
tree.l:

%{

#include "y.tab.h"



void yyerror(char*);



extern YYSTYPE yylval;

%}



char [a-zA-Z\_]

num [0-9]



%%



{char}[{num}|{char}]+ { yylval = yytext;return NAME; }

[ \n\t]+ /*ignore blanks*/;



%%

int yywrap()

{ return 1; }


/////////////////////
tree.y:
%{

#include "tree.h"

#include "y.tab.h"



#define YYSTYPE string


void yyerror(char*);

int yyparse();
int yylex();

void traverseTree(Tree T);

void deleteTree(Tree T);

void addPair(const string P,const string C);



%}



%token NAME



%%

tree  : pairs;

pairs : pairs pair

        | pair;

pair  : NAME NAME

        {

                addPair($1,$2);

        }

%%



extern FILE* yyin;





int main(int args,char* argv[])

{

        if(NULL == (yyin = fopen(argv[1],"rt")))

        {

                exit(1);

        }

        yyparse();

        for(treeMap::iterator p = treeIndex.begin();p != treeIndex.end(); p++)

        {

                if(p->second->root) traverseTree(p->second);

        }

        treeIndex.clear();

        return 1;

}



void yyerror(const char* err)

{

        cout<<err<<endl;

}





/////////////////////
tree.h:

#ifndef TREE_HEADER

        #define TREE_HEADER



#pragma warning(disable:4786)



#include<iostream>

#include<string>

#include<map>



using namespace std;



struct treeNode{

        string name;

        bool root;

        treeNode* son;

        treeNode* sibling;

        treeNode(const string str,bool r): name(str),son(0),sibling(0),root(r){}

};

typedef treeNode* Tree;



typedef map< string, Tree> treeMap;


treeMap treeIndex;



void traverseTree(Tree T);

void deleteTree(Tree T);

void addPair(const string P,const string C);



#endif




/////////////////////
tree.c
/*
采用儿子/兄弟表示法,构造一颗多杈树
*/
#include "tree.h"



void traverseTree(Tree T)

{

        if(!T) return ;

        if(T->son)

        {

                traverseTree(T->son);

        }

        cout<<T->name<<" ";

        if(T->sibling)

        {

                traverseTree(T->sibling);

        }

}

void deleteTree(Tree T)

{

        if(!T) return ;

        if(T->son)

        {

                deleteTree(T->son);

        }

        if(T->sibling)

        {

                deleteTree(T->sibling);

        }

        delete T;

}



void addPair(const string P,const string C)

{/*添加一对连接到树中去,其中P代表父亲节点的名字,C代表子节点的名字,
treeIndex的作用是记录每个名字指向的节点。
*/

        if(NULL == treeIndex[P])

        {

                Tree temp = new treeNode(C,1);

                treeIndex[C] = temp;

        }

        if(NULL == treeIndex[C])

        {

                Tree temp = new treeNode(C,0);

                treeIndex[C] = temp;

        }

        if(treeIndex[C]->root)/*若节点是子树的根,去掉标记*/

        {

                treeIndex[C]->root = false;

        }

        if(treeIndex[P]->son)

        {

                Tree temp = treeIndex[P]->son;

                while(temp->sibling)

                {

                        temp = temp->sibling;

                }

                temp->sibling = treeIndex[C];

                return ;

        }

        else

        {

                treeIndex[P]->son = treeIndex[C];

        }

}
 楼主| 发表于 2006-3-23 10:37:53 | 显示全部楼层
不好意思,出那个错误是头文件包含方面的问题,用
#ifndef宏只能防止一个文件中重复包含,现在该问题已经得到解决.

但是我的词法分析不能正常工作,这个不知道是为什么了,希望各位大虾指点.
回复 支持 反对

使用道具 举报

发表于 2006-3-23 12:38:33 | 显示全部楼层
在另外一帖回复了你词法器的问题。

最好把你的代码用 code 标签整理一下
回复 支持 反对

使用道具 举报

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

本版积分规则

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