我是靠谱客的博主 平常服饰,最近开发中收集的这篇文章主要介绍词法分析器的生成器——lex/flex1.词法分析器和语法分析器2.flex,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 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_DECL
  • yywrap():词法分析器遇到文件结尾时会调用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所遇到的程序开发问题。

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

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

评论列表共有 0 条评论

立即
投稿
返回
顶部