免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2446 | 回复: 1
打印 上一主题 下一主题

lex&yacc的奇怪问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-21 10:41 |只看该作者 |倒序浏览
最近在研究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  


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/60705/showart_1905236.html

论坛徽章:
1
寅虎
日期:2014-11-30 21:25:54
2 [报告]
发表于 2011-04-16 01:22 |只看该作者
marks
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP