我是靠谱客的博主 自觉板栗,最近开发中收集的这篇文章主要介绍Lex/Yacc Lex结合Yacc,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

这次就来尝试lex结合yacc。
简单lex
先写个简单lex,如下:
%{
#include "name.tab.h"
#include <stdio.h>
#include <string.h>
extern char* yylval;
%}
char [A-Za-z]
num [0-9]
eq [=]
name {char}+
age {num}+
%%
{name} { yylval = strdup(yytext);
return NAME;}
{eq} {return EQ;}
{age} {yylval = strdup(yytext);
return AGE;}
%%
int yywrap()
{
return 1;
}
这个lex的意思是说,
1. 提取符合name规则的内容,也就是A-Za-z组成的单词
2. 提取eq,也就是=
3. 提取age,也就是0-9组成的数字。
然后把提取出来的内容放到一个变量yylval里面。
编译使用名flex name.lex,产生一个.c文件,就是lex.yy.c,如截图所示:

简单yacc例子
接下来先写个yacc文件,如:
%{
typedef char* string;
#define YYSTYPE string
#include "lex.yy.c"
%}
%token NAME EQ AGE
%%
file : record file
| record
;
record : NAME EQ AGE {
printf("%s is %s years old!!!", $1, $3); }
;
%%
int main()
{
yyparse();
return 0;
}
int yyerror(char* msg)
{
printf("Error : %s n", msg);
}
这里有几个东西需要说明一下:
1. #define YYSTYPE string, YYSTYPE是指yylval变量的类型,yylval是用来在lex里面把内容填充进去,然后yyac里面访问的。
2. NAME EQ AGE这3个token也是在yacc里面定义,然后lex里面使用的。
3. record : NAME EQ AGE意思是说,符合NAME EQ AGE这种类型的内容提出来。看lex的定义可以知道,这种内容应该是 “NAME=AGE"的形式,NAME是指A-Za-z组成的单词,AGE是0-9组成的数字。
创建一个yacc文件name.y,把上面的内容丢进去,同样编译一下:
bison -d name.y
看一下截图:

多了两个文件,lex会include ”name.tab.h",因为lex需要使用yacc定义的一些东西。
接下来,编译name.tab.c,如:
gcc name.tab.c
看截图:
多了一个a.out可执行文件。
使用lex+yacc
直接跑一下吧:
./a.out
然后看一下截图:

第一次输入两个符合的内容,被捕获两次,并且打出了log,没问题。
第二次输入一个内容,也没问题。
第三次就有问题了,应输入的name是kevin2016,而我们在lex里面定义的name只能是A-Za-z组成的单词,所以报错。
有关报错,是我们在yacc里面定义的yyerror()。
这个文章里面的例子,只要有一条不符合规则,就报错了。
看如下:
第一次测试一条符合的都没找到,第二条第一个还是符合的,第二个不符合,就报错退出了。

总结:
lex:就是用来提取符合一定规则的内容
yacc:分析lex提取过来的内容,然后做进一步操作。


最后

以上就是自觉板栗为你收集整理的Lex/Yacc Lex结合Yacc的全部内容,希望文章能够帮你解决Lex/Yacc Lex结合Yacc所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部