概述
文章目录
- 1.词法分析器和语法分析器
- 2.flex
- 1.使用
- 2.文件格式
- 3.条件模式(了解)
1.词法分析器和语法分析器
词法分析器:将文本分解成token
语法分析器:判断token是否符合规定的语法规则
- 可以自己实现词法/语法分析器,分离文本,编写语法规则。但是为了方便和规范的词法语法分析,我们使用flex和bison;
- flex是词法分析器的生成工具,bison是语法分析器的生成工具;
- 使用此工具就让我们脱离了繁琐的代码编写上,只需要关注我们需要什么符号,使用什么规则。
2.flex
1.使用
1.编写好词法规则文件,一般以.l为文件格式(flex对文件格式没要求,不是.l也没关系)
2.flex xxx.l 生成lex.yy.c
3.gcc lex.yy.c -lfl (-lfl带不带都没关系) 可以修改lex.yy.c名字
例子:
/*flex-wc.l*/
%option noyywrap //option、noyywrap是flex的关键字,语法部分介绍
%{
int chars = 0;
//声明
int words = 0;
int lines = 0;
%}
%%
[a-zA-z]+ { words++; chars += strlen(yytext); } //规则
n
{ lines++; chars++; }
.
{ chars++; }
%%
//以下部分会在lex.yy.c上原地展开
int main() {
yylex();
//根据以上规则生成的词法分析函数
printf("%8d %8d %8dn", lines, words, chars);
return 0;
}
2.文件格式
%{
C语言声明,一般声明全局变量和函数,会复制进lex.yy.c中
%}
定义正则表达式的名字,可以在规则段中使用
%%
规则段,每一行都是一条规则,每一条规则由匹配模式和事件组成。每当一个模式被匹配到,后面的事件被执行!
%%
用户自定义过程,直接复制到lex.yy.c末尾
flex提供的全局变量:
yytext
:刚刚匹配到的字符串yyleng
:刚刚匹配到的字符串的长度yyin
:FILE*类型yyout
:指向输出的文件,缺省情况下指向标准输入输出yylineno
:当前行数信息yylval
:可由yytext取出数字atoi(yytext)
flex提供的函数:
yylex()
:词法分析器驱动程序,用Lex翻译器生成的lex.yy.c内必然含有这个函数;YY_DECLyywrap()
:词法分析器遇到文件结尾时会调用yywrap()来决定下一步怎么做:这是一个约束函数。若yywrap()返回0,则继续扫描; 当它返回1时,代表扫描结束,此时结束程序;
以下部分作为了解:
yyless(int n)
:用来送回除了前n个字符外的所有读出标记yymore()
:告诉lexer将下一个标记符加到当前标记后yymore()
:将当前识别的词形保留在yytext中,分析器下次扫描时的词形将加追加在yytext中。例模式定义如下
hello {printf(“%s!”,yytext);yymore();}
world {printf(“%s!”,yytext);}
12
当输入串为”helloworld”时,将输出”hello!helloworld!”
- REJECT:放弃当前匹配的字符串和当前的模式,让分析器重新扫描当前的字符串,并选择另一个最佳的模式再次进行匹配。
yyless(int n)
:回退当前识别的词形中n个字符到输入中unput(char c)
:回退字符c到输入,它将作为下一次扫描的开始字符input()
:让分析器从输入缓冲区中读取当前字符,并将yyin指向下一字符yyterminate()
:中断对当前文件的分析,将yyin指向EOF。yyrestart(FILE * file)
:重新设置分析器的扫描文件为file- ECHO:
#define ECHO fwrite(yytext, yyleng, 1, yyout)
将当前识别的字符串拷贝到yyout - BEGIN:激活开始条件对应的模式
规则部分的语法:
遵循正则表达式,如一些比较有用的规则:
[ t]
{ /*ignore white space*/ } //{}中什么都不做,就是将空格删除
.
{ printf("unexpected token: (%s)n", yytext);
return -1; }
//其他情况,一般放在最后,表示意外情况,返回错误
3.条件模式(了解)
LEX提供控制模式在一定状态下使用的功能,称为条件模式。LEX首先在定义部份通过%start来定义条件句。在规则部份可通过宏
BEGIN 条件名 来激活条件。BEGIN INITIAL或BEGIN 0将休眠所有的条件模式,使分析器回到开始状态。
例:将输入文件中的单词”magic” 作如下处理:识别”magic”时,如”magic”所在行行首为字符’a’,则输出”first”;若为’b’,则输出”second”;否则,输出”magic”。如不用条件模式,LEX源文件可这样写:
%{int flag;}%
%%
^a {flag=’a’;ECHO;}
^b {flag=’b’;ECHO;}
/n {flag=0;ECHO;}
magic {
switch(flag)
{
case ‘a’:printf(“first”);break;
case ‘b’:printf(“second”);break;
default :ECHO;break;
}
}
%%
如使用条件模式,则上述源文件可简化为
%start AA BB CC
%%
^a {ECHO;BEGIN AA;}
^b {ECHO;BEGIN BB;}
/n {ECHO;BEGIN 0;}
<AA>magic {printf(“first”);}
<BB>magic {printf(“second”);}
%%
##
参考文章:
https://blog.csdn.net/damontive/article/details/115289890
https://www.cnblogs.com/wanghetao/archive/2011/11/07/2240193.html
https://blog.csdn.net/liwei_cmg/article/details/1530492
最后
以上就是平常服饰为你收集整理的词法分析器的生成器——lex/flex1.词法分析器和语法分析器2.flex的全部内容,希望文章能够帮你解决词法分析器的生成器——lex/flex1.词法分析器和语法分析器2.flex所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复