- 论坛徽章:
- 0
|
最近在研究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 |
|