前面做了一个计算器的经典例子,可是对lex和yacc还是不够了解。
Google一下发现了这个网站:Lex and YACC primer/HOWTO
[url]http://tldp.org/HOWTO/Lex-YACC-HOWTO.html#toc4[/url]
把sample都看一遍的话,或许会有些帮助学习。
首先从lex开始:
[b]Sample1 [/b]一个简单的例子,可以识别输入是否有stop/start 然后输出相应文字。
建立一个example1.l文件:
然后编译:
结果失败了。。。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'!
再来编译:
这次编译成功了,
运行example1
$./example1
stop
Stop command received
start
Start command received
^D // Terminate with a EOF (^D).
[b]Sample2 [/b]可识别输入是word还是number
建立一个example2.l文件:
然后编译: 这次参数不能设错了。
编译成功!
运行example2
$ ./example2
1234
NUMBER
hello
WORD
[b]最后一个例子[/b]比较复杂一点,解析一个类c的文件,把符合翻译成另外一种形式。
解析的目标test.txt:
规则:用前面的单词代替后面的字符串
WORDs, like 'zone' and 'type'
FILENAMEs, like '/etc/bind/db.root'
QUOTEs, like those surrounding the filename
OBRACEs, {
EBRACEs, }
SEMICOLONs, ;
建一个example3.l文件:
然后编译:
编译成功
运行
$ ./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)
Google一下发现了这个网站:Lex and YACC primer/HOWTO
[url]http://tldp.org/HOWTO/Lex-YACC-HOWTO.html#toc4[/url]
把sample都看一遍的话,或许会有些帮助学习。
首先从lex开始:
[b]Sample1 [/b]一个简单的例子,可以识别输入是否有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).
[b]Sample2 [/b]可识别输入是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
[b]最后一个例子[/b]比较复杂一点,解析一个类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)