浏览 5178 次
锁定老帖子 主题:yacc 和 lex的上手(2)
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-12-17
最后修改:2009-12-17
Google一下发现了这个网站:Lex and YACC primer/HOWTO http://tldp.org/HOWTO/Lex-YACC-HOWTO.html#toc4 把sample都看一遍的话,或许会有些帮助学习。 首先从lex开始: Sample1 一个简单的例子,可以识别输入是否有stop/start 然后输出相应文字。 建立一个example1.l文件: %{ #include <stdio.h> %} %% stop printf("Stop command received\n"); start printf("Start command received\n"); %% 然后编译: flex example1.l cc lex.yy.c -o example1 -ll 结果失败了。。。orz 仔细看一下,原来是编译参数的问题: NOTE: If you are using flex, instead of lex, you may have to change '-ll' to '-lfl' in the compilation scripts. RedHat 6.x and SuSE need this, even when you invoke 'flex' as 'lex'! 再来编译: cc lex.yy.c -o example1 -lfl 这次编译成功了, 运行example1 $./example1 stop Stop command received start Start command received ^D // Terminate with a EOF (^D). Sample2 可识别输入是word还是number 建立一个example2.l文件: %{ #include <stdio.h> %} %% [0123456789]+ printf("NUMBER\n"); [a-zA-Z][a-zA-Z0-9]* printf("WORD\n"); %% 然后编译: 这次参数不能设错了。 flex example2.l cc lex.yy.c -o example2 -lfl 编译成功! 运行example2 $ ./example2 1234 NUMBER hello WORD 最后一个例子比较复杂一点,解析一个类c的文件,把符合翻译成另外一种形式。 解析的目标test.txt: logging { category lame-servers { null; }; category cname { null; }; }; zone "." { type hint; file "/etc/bind/db.root"; }; 规则:用前面的单词代替后面的字符串 WORDs, like 'zone' and 'type' FILENAMEs, like '/etc/bind/db.root' QUOTEs, like those surrounding the filename OBRACEs, { EBRACEs, } SEMICOLONs, ; 建一个example3.l文件: %{ #include <stdio.h> %} %% [a-zA-Z][a-zA-Z0-9]* printf("WORD "); [a-zA-Z0-9\/.-]+ printf("FILENAME "); \" printf("QUOTE "); \{ printf("OBRACE "); \} printf("EBRACE "); ; printf("SEMICOLON "); \n printf("\n"); [ \t]+ /* ignore whitespace */; %% 然后编译: flex example3.l cc lex.yy.c -o example3 -lfl 编译成功 运行 $ ./example3 < test.txt WORD OBRACE WORD FILENAME OBRACE WORD SEMICOLON EBRACE SEMICOLON WORD WORD OBRACE WORD SEMICOLON EBRACE SEMICOLON EBRACE SEMICOLON WORD QUOTE FILENAME QUOTE OBRACE WORD WORD SEMICOLON WORD QUOTE FILENAME QUOTE SEMICOLON EBRACE SEMICOLON OK 预期结果出现! 到这里为止只是使用了lex ,后面继续学习yacc 以及 lex和yac的c配套使用。 明天继续,つづく(To be continued) 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-12-17
除了语法古怪外,有什么特点么?
|
|
返回顶楼 | |
发表时间:2009-12-17
据说,yacc和lex很好很强大,不过暂时个人还未体会到强大之处。
我看这个东东纯粹是因为个人兴趣,呵呵 因为要看RHG,所以才去看yacc的 RHG第八章开始还没翻译完成。。。 |
|
返回顶楼 | |
发表时间:2009-12-17
ray_linn 写道 除了语法古怪外,有什么特点么?
词法分析和文法分析人肉做是非常痛苦的。。。。 |
|
返回顶楼 | |
发表时间:2009-12-17
mikeandmore 写道 ray_linn 写道 除了语法古怪外,有什么特点么?
词法分析和文法分析人肉做是非常痛苦的。。。。 理解的人手写着玩儿。 不理解的人用起来也痛苦。 |
|
返回顶楼 | |
发表时间:2009-12-17
zzsczz 写道 mikeandmore 写道 ray_linn 写道 除了语法古怪外,有什么特点么?
词法分析和文法分析人肉做是非常痛苦的。。。。 理解的人手写着玩儿。 不理解的人用起来也痛苦。 谁都是从不理解开始的,呵呵 或许其实也没想象中那么难,当初听编译的课的时候,好好听还是能听懂的, 不像图论,就算从头到尾认真的听,都不一定能都搞明白 |
|
返回顶楼 | |
发表时间:2009-12-18
个人感觉, yacc+lex 不如 JavaCC 好用; lex 比 yacc 要好用多了, yacc 的语法真叫混乱...
不过单 lex 倒真没啥用~ 欢迎各位同学去我博客, 内含山寨型词法+语法人肉前端分析的实现. |
|
返回顶楼 | |
发表时间:2009-12-18
现在有了antlr这样的工具,就可以替代这两个了,编译原理我才学了,我们当年竟然没有教
|
|
返回顶楼 | |
发表时间:2009-12-20
手动编译感觉比较痛苦,用IDE习惯啦,不过看的正则倒蛮亲切的哈
|
|
返回顶楼 | |
发表时间:2009-12-20
实际上,lz那个词法分析程序定一段可以不包含那个stdio的头文件。
生成的lex.yy.c里包含了。 |
|
返回顶楼 | |