Lex/Yacc Lex结合Yacc

Posted zj510

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

Lex Yacc 入门

lex yacc flex bison

Lex Yacc 实际应用全代码

在 Windows、Visual C++ 2008 上安装 LEX/YACC 或 flex/bison

qmake理解(还可以加入Lex Yacc文件)