编译原理-词法分析器自动生成工具Lex

 

1.词法分析自动生成器概述

         词法分析自动生成器基于正则表达式和有穷自动机理论。正则表达式是一个用数学表达式来描述一个单词集合的构成模式,而有穷自动机从识别的观点来看一个集合中的符号串是否被有穷自动机所识别。

2. Lex

2.1 Lex概述

        Lex是一个基于正则表达式的描述来构造词法分析器的工具。它的输入是用Lex语言编写的源程序。在Lex中,要将基于正则表达式的模式说明与词法分析器要完成的动作组织在一起。输出则是词法分析器的C语言程序。

        下图所示就是Lex的用法:

2.2 Lex源文件格式

         使用Lex产生词法分析器的关键就是设计Lex源程序。Lex源程序包括三个部分:声明、翻译规则和辅助程序,这三个部分用%%分开,如下面所示:

声明
%%
翻译规则
%%
辅助程序

2.3 正则表达式

格式含义
a字符a
"a"即使a是一个元符,它仍是字符a
\a当a时应该元字符时,为字符a
a*a的零次或多次重复
a+a的一次或多次重复
a?一个可选的a
a|ba或b
(a)a本身
[abc]字符a、b或c中的任意一个
[a-d]字符a、b、c或d中的任意一个
[^ab]除了a或b之外的任何一个字符
.除了新行之外的任何一个字符
{xxx}名字xxx表示的正则表达式
<EOF>匹配的文件结束标记

2.4 Lex的翻译规则

      规则如下:

p1    {动作1}
p2    {动作2}
p3    {动作3}
...   ...

 

3.Lex案例

3.1 统计文本文件中的字符数和行数

        Lex源码如下:

%{
/*该Lex程序的功能是统计文本文件中的字符数和行数,并输出结果*/
#include <stdio.h>
int num_chars = 0, num_lines = 0;  /*全局变量定义,初值为0*/
%}
%%         /*从此后是第二部分*/
\n   { ++num_chars; ++num_lines; }  /*\n匹配一行*/
.    { ++num_chars; }  /*.匹配任一符号,注意从第一列开始写*/
%%         /*从此后是第三部分*/
	int main( )	
{ yylex();
printf("This file has %5d chars, %5d lines", num_chars,num_lines);
return 0;
}
int yywrap()/*文件结束处理函数,yylex在读到文件结束标记EOF时,要调用该函数,用户必须提供该函数,否则在编译时会出错*/
{ return 1; }

3.2 输出标识符和整数

%{
#include <stdio.h>
#include <stdlib.h>
%}
DIGIT [0-9]+
ID [a-zA-Z][a-zA-Z0-9]*
%%
{DIGIT} {printf("整数:%s(%d)\n",yytext,atoi(yytext));}
{ID} {printf("标识符:%s\n",yytext);}
%%
void main(){
yyin=fopen("C:/test.txt",r);
yylex();
}
int yywrap(){return 1;}

3.3 将关键字小写,去掉注释

%{
#include <stdio.h>
%}
ID [a-zA-Z][a-zA-Z0-9]*
id auto|double|int|struct|break|else|long|switch|case|
enum|register|typedef|char|extern|return|union|const|
float|short|unsigned|continue|for|signed|void|default|
goto|sizeof|volatile|do|if|while|static
%%
{id} {
 int i;
 printf("关键字小写为:");
 for(i=0;i<yyleng;i++)
 {
   if(yytext[i]>='A'&&yytext[i]<='Z')
       printf("%c",yytext[i]+'a'-'A');
    else
       printf("%c",yytext[i]);  
 }
 printf("\n");
}
{ID} {printf("标识符:%s\n",yytext);}
"/*"([^\*|(\*)*[^\*/])*(\*)*"*/" "";

%%
main()
{
  yylex();
}
int yywrap(void)
{
  return 1;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 12
    点赞
  • 94
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luckyliuqs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值