论坛首页 编程语言技术论坛

yacc 和 lex的上手(2)

浏览 5178 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-12-17   最后修改:2009-12-17
C
  前面做了一个计算器的经典例子,可是对lex和yacc还是不够了解。
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)
   发表时间:2009-12-17  
除了语法古怪外,有什么特点么?
0 请登录后投票
   发表时间:2009-12-17  
据说,yacc和lex很好很强大,不过暂时个人还未体会到强大之处。

我看这个东东纯粹是因为个人兴趣,呵呵
因为要看RHG,所以才去看yacc的

RHG第八章开始还没翻译完成。。。
0 请登录后投票
   发表时间:2009-12-17  
ray_linn 写道
除了语法古怪外,有什么特点么?

词法分析和文法分析人肉做是非常痛苦的。。。。
0 请登录后投票
   发表时间:2009-12-17  
mikeandmore 写道
ray_linn 写道
除了语法古怪外,有什么特点么?

词法分析和文法分析人肉做是非常痛苦的。。。。


理解的人手写着玩儿。

不理解的人用起来也痛苦。
0 请登录后投票
   发表时间:2009-12-17  
zzsczz 写道
mikeandmore 写道
ray_linn 写道
除了语法古怪外,有什么特点么?

词法分析和文法分析人肉做是非常痛苦的。。。。


理解的人手写着玩儿。

不理解的人用起来也痛苦。


谁都是从不理解开始的,呵呵

或许其实也没想象中那么难,当初听编译的课的时候,好好听还是能听懂的,
不像图论,就算从头到尾认真的听,都不一定能都搞明白
0 请登录后投票
   发表时间:2009-12-18  
个人感觉, yacc+lex 不如 JavaCC 好用; lex 比 yacc 要好用多了, yacc 的语法真叫混乱...
不过单 lex 倒真没啥用~

欢迎各位同学去我博客, 内含山寨型词法+语法人肉前端分析的实现.
0 请登录后投票
   发表时间:2009-12-18  
现在有了antlr这样的工具,就可以替代这两个了,编译原理我才学了,我们当年竟然没有教
0 请登录后投票
   发表时间:2009-12-20  
手动编译感觉比较痛苦,用IDE习惯啦,不过看的正则倒蛮亲切的哈
0 请登录后投票
   发表时间:2009-12-20  
实际上,lz那个词法分析程序定一段可以不包含那个stdio的头文件。

生成的lex.yy.c里包含了。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics