LinuxSir.cn,穿越时空的Linuxsir!

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

请教编译方面的问题,比较有趣的,大家看看吧.在线等候大家的回音

[复制链接]
发表于 2006-3-24 09:44:15 | 显示全部楼层 |阅读模式
--开始以为是头文件的问题,用的是STL,但是后来在什么地方看到了说只要YYSTYPE中没有类成员的话,都是没有问题的

在单个的文件中,这个lex文件可以解析出单词来:
  1. %{
  2. #include "y.tab.h"

  3. void yyerror(char*);

  4. extern YYSTYPE yylval;
  5. %}
  6. char [a-zA-Z\_]
  7. num [0-9]
  8. name {char}({num}|{char})*

  9. %%
  10. {name}        {
  11.                         cout<<"get name:"<<yytext<<endl;
  12.                         yylval = yytext;
  13.                         return NAME;
  14.                 }
  15. [" "\n\t]* {
  16.                          /*ignore blanks*/;
  17.                         }
  18. .        {
  19.                 cout<<"unknown character:"<<*yytext<<endl;
  20.         }

  21. %%

  22. int yywrap()
  23. { return 1; }
复制代码

但是在和几个文件合起来的时候就不行了,读入一个单词就显示错误提示如下:

  1. unknown character:a
  2. unknown character:e
  3. unknown character:a
  4. unknown character:a
  5. unknown character:a
  6. unknown character:f
  7. unknown character:a
  8. syntax error
复制代码

我的目的是要读入 父 - 子  节点描述,然后在内存中构造一颗树,但是现在连词法分析都不行.........希望大家指点指点.
我的几个文件的代码如下:
头文件 tree.h:
  1. #ifndef TREE_HEADER
  2.         #define TREE_HEADER

  3. #pragma warning(disable:4786)

  4. #include<iostream>
  5. #include<string>
  6. #include<map>

  7. using namespace std;

  8. struct treeNode{
  9.         string name;
  10.         bool root;
  11.         treeNode* son;//left son right sibling
  12.         treeNode* sibling;
  13.         treeNode(const string str,bool r): name(str),son(0),sibling(0),root(r){}
  14. };
  15. typedef treeNode* Tree;

  16. typedef map< string, Tree> treeMap;

  17. void traverseTree(Tree T);
  18. void deleteTree(Tree T);
  19. void addPair(const string P,const string C);

  20. #endif

复制代码


几个函数的实现的文件
tree.c
  1. /*
  2. 采用儿子/兄弟表示法,构造一颗多杈树
  3. */
  4. #include "tree.h"

  5. treeMap treeIndex;

  6. void traverseTree(Tree T)
  7. {
  8.         if(!T) return ;
  9.         if(T->son)
  10.         {
  11.                 traverseTree(T->son);
  12.         }
  13.         cout<<T->name<<" ";
  14.         if(T->sibling)
  15.         {
  16.                 traverseTree(T->sibling);
  17.         }
  18. }
  19. void deleteTree(Tree T)
  20. {
  21.         if(!T) return ;
  22.         if(T->son)
  23.         {
  24.                 deleteTree(T->son);
  25.         }
  26.         if(T->sibling)
  27.         {
  28.                 deleteTree(T->sibling);
  29.         }
  30.         delete T;
  31. }

  32. void addPair(const string P,const string C)
  33. {/*添加一对连接到树中去,其中P代表父亲节点的名字,C代表子节点的名字,
  34. treeIndex的作用是记录每个名字指向的节点。
  35. */
  36.         if(NULL == treeIndex[P])
  37.         {
  38.                 Tree temp = new treeNode(C,1);
  39.                 treeIndex[C] = temp;
  40.         }
  41.         if(NULL == treeIndex[C])
  42.         {
  43.                 Tree temp = new treeNode(C,0);
  44.                 treeIndex[C] = temp;
  45.         }
  46.         if(treeIndex[C]->root)/*若节点是子树的根,去掉标记*/
  47.         {
  48.                 treeIndex[C]->root = false;
  49.         }
  50.         if(treeIndex[P]->son)
  51.         {
  52.                 Tree temp = treeIndex[P]->son;
  53.                 while(temp->sibling)
  54.                 {
  55.                         temp = temp->sibling;
  56.                 }
  57.                 temp->sibling = treeIndex[C];
  58.                 return ;
  59.         }
  60.         else
  61.         {
  62.                 treeIndex[P]->son = treeIndex[C];
  63.         }
  64. }
复制代码


词法分析的lex文件:
  1. %{
  2. #include "y.tab.h"

  3. void yyerror(char*);

  4. extern YYSTYPE yylval;
  5. %}
  6. char [a-zA-Z\_]
  7. num [0-9]
  8. name {char}({num}|{char})*

  9. %%
  10. {name}        {
  11.                         cout<<"get name:"<<yytext<<endl;
  12.                         yylval = yytext;
  13.                         return NAME;
  14.                 }
  15. [" "\n\t]* {
  16.                          /*ignore blanks*/;
  17.                         }
  18. .        {
  19.                 cout<<"unknown character:"<<*yytext<<endl;
  20.         }

  21. %%

  22. int yywrap()
  23. { return 1; }
复制代码

语法分析的yacc文件:
  1. %{
  2. #include "tree.h"
  3. #include "y.tab.h"

  4. #define YYSTYPE string

  5. void yyerror(char*);
  6. int yyparse();
  7. int yylex();
  8. void traverseTree(Tree T);
  9. void deleteTree(Tree T);
  10. void addPair(const string P,const string C);

  11. %}

  12. %token NAME

  13. %%
  14. tree  : pairs;
  15. pairs : pairs pair
  16.         | pair;
  17. pair  : NAME NAME
  18.         {
  19.                 cout<<$1<<"-->"<<$2<<endl;
  20.                 addPair($1,$2);
  21.         }
  22. %%

  23. extern FILE* yyin;
  24. extern treeMap treeIndex;

  25. int main(int args,char* argv[])
  26. {
  27.         if(NULL == (yyin = fopen(argv[1],"rt")))
  28.         {
  29.                 exit(1);
  30.         }
  31.         yyparse();
  32.         for(treeMap::iterator p = treeIndex.begin();p != treeIndex.end(); p++)
  33.         {
  34.                 if(p->second->root) traverseTree(p->second);
  35.         }
  36.         treeIndex.clear();
  37.         return 1;
  38. }

  39. void yyerror(const char* err)
  40. {
  41.         cout<<err<<endl;
  42. }

复制代码


我用的是FC4中的lex和yacc,需要动手把y.tab.c中的yystype的定义拷贝到y.tab.h中去,还要在y.tab.h中添加对string头文件的包含.

希望大家看看有问题,给我指出来.谢谢了
 楼主| 发表于 2006-3-24 10:04:13 | 显示全部楼层
我的输入文件如下:[PHP]
aa ba
ba ca
ca da
aa ea
aa fa
[/PHP]
想构造的是一颗以aa为根的树,ba ea fa是它的儿子,ca是ba儿子,da是ca儿子.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-3-24 14:29:23 | 显示全部楼层
大家可以实验一下,不知道是不是我的lex和yacc有问题,我在线等候大家的答复!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-3-24 14:29:38 | 显示全部楼层
大家可以实验一下,不知道是不是我的lex和yacc有问题,我在线等候大家的答复!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-3-24 20:10:35 | 显示全部楼层
大虾给个回复吧,我饿着等了一天了啊。
回复 支持 反对

使用道具 举报

发表于 2006-3-24 21:27:50 | 显示全部楼层
Post by mousse
我用的是FC4中的lex和yacc,需要动手把y.tab.c中的yystype的定义拷贝到y.tab.h中去,还要在y.tab.h中添加对string头文件的包含.

希望大家看看有问题,给我指出来.谢谢了


yystype的定义可以在.y文件的第一部分定义,如:

  1. %{
  2. #include xxx
  3. %}

  4. /* 可以在此处定义yystype , 就不用手工拷贝了。*/
  5. %union {
  6. int value
  7. char * string
  8. }

  9. %%
  10. ...
  11. %%
  12. ...

复制代码
回复 支持 反对

使用道具 举报

发表于 2006-3-24 21:33:09 | 显示全部楼层
你的错误在于 yylval返回的东西根本不是 token的值。
比如我上面定义的 yystype 为:
%union {
int value
char * name}

那么你在 .l 文件中应该这样:
{ name }   { yylval.name=yytext; return NAME; }



补充:没看清。楼主的yystype可以这样
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-3-24 22:23:16 | 显示全部楼层
那个赋值不是可以转换的吗?从c字符串到string
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-3-25 10:41:04 | 显示全部楼层
好了,现在是通过编译了(什么都没有改),但是有segmentation error了......段错误.....我在linux下很少编程,这个问题是由什么引起的,能讲讲吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-3-25 16:57:25 | 显示全部楼层
怪异啊,我什么都没有改动,一样的环境下现在编译没有错误了,执行的时候提示segmentation error,段地址错误,这个是什么意思啊?以前一直是在WINDOWS下,没见过这样的错误.
回复 支持 反对

使用道具 举报

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

本版积分规则

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