Chinaunix首页 | 论坛 | 博客
  • 博客访问: 61470
  • 博文数量: 15
  • 博客积分: 1425
  • 博客等级: 上尉
  • 技术积分: 185
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-31 00:34
文章分类

全部博文(15)

文章存档

2009年(2)

2008年(13)

我的朋友
最近访客

分类: LINUX

2009-04-21 10:41:02

最近在研究lex和yacc,先是看了manual手册,对其大概有了个了解.然后就依循Oreilly的lex&yacc(第二版)进行深入学习。
 
lex和yacc单独使用都相对简单,倒是没有碰上什么问题,后面学到构建一个支持简单变量的计算器时,自己试着写了一个测试程序,与书上的功能差不多,按照逻辑应该输入1+4后会出现=5.0000的结果,可实际上是输入1+4后没有任何输出,纳闷了,使用Oreilly提供的代码却是可以的,于是一步步修改代码、编译、测试,可始终解决,直至后面代码已经和Oreilly的一模一样却还是完成不了加法计算这一个简单的功能,百思不得其解.
 
最后追查到编译选项,像示例一样使用-g -DYYDEBUG=1,还是不行,最后发现是由于liby.a和libl.a库的顺序不一致导致的。
 
我的链接语句如下:
gcc -g -DYYDEBUG=1 -o calc y.tab.c lex.yy.c -ll -ly
而示例中
gcc -g -DYYDEBUG=1 -o ch3-03.pgm y.tab.c lex.yy.c -ly -ll
这两个分别是lex和yacc的库,为什么会导致输出就不正常了呢?
 
进一步追查结果如下:
libl.a实际指向libfl.a,包含两个obj文件libmain.o和libyywrap.o
nm libfl.a
libmain.o:
00000000 T main
         U yylex
libyywrap.o:
00000000 T yywrap
 
liby.a实际同样包含两个obj文件main.o和yyerror.o
nm liby.a
main.o:
00000000 T main
         U setlocale
         U yyparse
yyerror.o:
         U fprintf
         U stderr
00000000 T yyerror
 
其中main函数在libmain.o和main.o中都存在,因此一定是多重实现导致的,进一步测试可知使用libmain.o进行链接时就会出现无输出的情况,使用objdump对两个包含main的文件进行反汇编如下:
 
libmain.o
00000000
:
main():
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 08                sub    $0x8,%esp
   6:   83 e4 f0                and    $0xfffffff0,%esp
   9:   83 ec 10                sub    $0x10,%esp
   c:   e8 fc ff ff ff          call   d
  11:   85 c0                   test   %eax,%eax
  13:   75 f7                   jne    c
  15:   c9                      leave 
  16:   c3                      ret 
 
main.o
00000000
:
main():
   0:   55                      push   %ebp
   1:   b8 00 00 00 00          mov    $0x0,%eax
   6:   89 e5                   mov    %esp,%ebp
   8:   83 ec 08                sub    $0x8,%esp
   b:   83 e4 f0                and    $0xfffffff0,%esp
   e:   83 ec 10                sub    $0x10,%esp
  11:   89 44 24 04             mov    %eax,0x4(%esp)
  15:   c7 04 24 06 00 00 00    movl   $0x6,(%esp)
  1c:   e8 fc ff ff ff          call   1d
  21:   e8 fc ff ff ff          call   22
  26:   c9                      leave 
  27:   c3                      ret 
 
阅读(601) | 评论(0) | 转发(0) |
0

上一篇:自动挂载/卸载Win共享目录的脚本

下一篇:没有了

给主人留下些什么吧!~~