lex/flex的语法结构
lex/flex是通过处理其源文件来生词法和语法分析器的,源文件的扩展名为.l,其语法被分为三个部分:
/* 定义段 */
%{
%}
%%
/* 规则段 */
%%
/* 用户子程序段 */
三个段用 %% 进行分离。
1、定义段,这一部分一般是一些声明及选项设置等。C 语言的注释、头文件包含等一般就放在 %{ %} 之间,这一部分的内容会被直接复制到输出文件的开头部分;
2、规则段为一系列匹配模式和动作,模式一般使用正则表达式书写,动作部分为C代码:模式1 {动作1(C代码)}
,在输入和模式 1 匹配的时候,执行动作部分的代码;
注:上图一定要记住,因为写正规式的时候是要使用这些字符来表示对应的含义的。
3、用户子程序段,这里为 C 代码,会被原样复制到输出文件中,一般这里定义一些辅助函数等,如动作代码中使用到的辅助函数。
如何写一条规则
下面通过一个简单的例子来学习如何写一条规则:
/* 这里是定义段 */
%{
/* 这里的部分会被直接拷贝到生成的 .c 文件的开始部分,在这里可以包含需要使用的头文件,如 stdio.h
*/
#include <stdio.h>
%}
/* 下面是规则段 */
%%
/* 这里定义了四条规则,前面的部分是模式,处于一行的开始位置,后面的部分是动作。第一个模式是匹配连续的一个到多个字符,匹配到之后就将其打印出来。注意到 yytext,在输入匹配到该模式的时候,匹配的部分就存储在这个 yytext 里面,这里把它作为字符串直接输出就可以了;第二条规则的模式部分,就是匹配连续的一个或者多个数字,匹配到了之后,也是以字符串的形式输出;第三条规则的模式部分,就是匹配一个换行符了,并且匹配到之后就打印一个新行的信息;第四条规则的模式部分,是一个点。正则表达式里面这个也就是匹配任何除了 \n 之外的字符。因此,下面的规则就是,匹配到字符串,则将该字符串输出,匹配到连续数字,将其输出;匹配到换行符,打印一条信息;匹配到任何其他的字符,则直接忽略*/
[a-zA-Z]+ {
printf("get string:%s\n", yytext);}
[0-9]+ {
printf("get number:%s\n", yytext);}
\n {
printf("get new line\n"); }
. {
}
/* 下面是用户子程序段 */
%%
int yywrap() {
return 1; }
int main(int argc, char** argv) {
if (argc > 1) {
if (!(yyin = fopen(argv[1], "r"))) {
perror(argv[1]);
return 1;
}