lex和yacc学习1

Lex(Lexical Analyzar 词法分析生成器),Yacc(Yet Another Compiler Compiler编译器代码生成器)是Unix下十分重要的词法分析,语法分析的工具。经常用于语言分析,公式编译等广泛领域,详细内容可参考http://dinosaur.compilertools.net/.
先来看最简单的例子(xtgxiso.l)

%{
#include "stdio.h"
%}
%%
[/n]                  ;
[0-9]+                printf("Int:%s/n",yytext);
.                     printf("Unknown:%c/n",yytext[0]);
%%

执行如下命令

到此我们会对lex有个直观的用法了解
1.定义Lex描述文件
2.通过lex工具解析成lex.yy.c文件
3.使用cc编译lex.yy.c生成可执行程序

现在我们来写一个相对比较完整的例子

%{
#include "stdio.h"
%}
%%
[/n]                  ;
[0-9]+                printf("Int:%s/n",yytext);
.                     printf("Unknown:%c/n",yytext[0]);
%%

int main()
{
    yylex();
    return 0;
}

int yywrap()
{
    return 1;
}

执行如下命令

这次编译没有加ll选项,那是因为加了main函数.

现在我们来大致了解lex的描述文件结构,
一般可以分为<定义部分><规则部><用户子程序部分>。其中规则部分是必须的,定义和用户子程序部分是任选的

1:定义部分起始于 %{ 符号,终止于 %} 符号,其间可以是包括include语句、声明语句在内的C语句。这部分跟普通C程序开头没什么区别

2:规则部分起始于”%%”符号,终止于”%%”符号,其间则是词法规则。词法规则由模式和动作两部分组成。模式部分可以由任意的正则表达式组成,动作部分是由C语言语句组成,这些语句用来对所匹配的模式进行相应处理。需要注意的是,lex将识别出来的单词存放在yytext[]字符数据中,因此该数组的内容就代表了所识别出来的单词的内容.

3:用户子程序部分,可以包含用C语言编写的子程序,而这些子程序可以用在前面的动作中,这样就可以达到简化编程的目的

Lex内部变量和函数

yytext char * 当前匹配的字符串

yyleng int 当前匹配的字符串长度

yyin FILE * lex当前的解析文件,默认为标准输出

yyout FILE * lex解析后的输出文件,默认为标准输入

yylineno int 当前的行数信息

ECHO #define ECHO fwrite(yytext, yyleng, 1, yyout) 也是未匹配字符的默认动作

int yylex(void) 调用Lex进行词法分析

int yywrap(void) 在文件(或输入)的末尾调用。如果函数的返回值是1,就停止解析

Lex其实就是词法分析器,通过配置文件*.l,依据正则表达式逐字符去顺序解析文件,并动态更新内存的数据解析状态。不过Lex只有状态和状态转换能力。因为它没有堆栈,它不适合用于剖析外壳结构。而yacc增加了一个堆栈,并且能够轻易处理像括号这样的结构。Lex善长于模式匹配,如果有更多的运算要求就需要yacc了.

此条目发表在 好文推荐, 网站架构 分类目录,贴了 , 标签。将固定链接加入收藏夹。

评论功能已关闭。