LEX自动生成词法分析器

词法分析器作为编译器的一个重要组成部分,原理很简单,代码也都没什么技术含量,但是如果让你手工写一个词法分析器,哪怕是一个简单的词法分析器,工作量无疑是巨大的。现代的词法分析器一般都是依靠工具自动生成,这里我们选用flex生成词法分析器,下面是用到的flex的下载地址。windows的环境的话,lex.exe文件使我们所需要的工具。里面的帮助文档将教会你如何更好的使用flex。

学习编译原理并非一定要做一个完美的编译器,我们所需要的只是了解编译器的工作原理并能运用这些特性写出更高效合法的程序,因此我们只用lex的一些简单功能写一个简单的词法分析器来印证我们所学的知识。下图是lex的使用步骤简要说明:
这里写图片描述

这里的源文件是符合lex的语句,flex 的输入文件由三段组成,用一行中只有%%来分隔。

定义;definition
%%
规则;rules
%%
用户代码;code

这个源文件输出的就是词法分析器的C语言源程序,编译这个.c的源程序生成的就是你所定义语言的词法分析器。

这里我们用一个简单的例子来做一个简单的词法分析器,词法规则符合《编译原理及实践教程》中描述的sample语言。

下面是Source文件

%{
#include<math.h>
#include<stdlib.h>
#include<stdio.h>
%}

DIGIT [0-9]
ID [a-z][a-z0-9]*
%%
{DIGIT}+                    {printf("整数:   %s(%d)\n",yytext,atoi(yytext));}
{DIGIT}+"."{DIGIT}+             {printf("实数:   %s(%g)\n",yytext,atof(yytext));}
if|then|begin|end|program|while|repeat      {printf("关键字: %s\n",yytext);}
{ID}                        {printf("标识符: %s\n",yytext);}
"+"|"-"|"*"|"/"                 {printf("运算符: %s\n",yytext);}
"{"[^}\n]*"}";
[\t\n\x20]+;
.                       {printf("不能识别的字符:%s\n",yytext);}
%%
int main(int argc,char **argv)
{
    ++argv;
    --argc;
    if(argc>0) yyin=fopen(argv[0],"r");
    else yyin=stdin;
    yylex();
    return 0;
}
int yywrap()
{
    return 1;
}

这里我们把Source源文件保存为lex.l
通过在命令行模式下输出命令 lex lex.l 生成lex.yy.c文件,这就是我们的词法分析器的源代码了,打开看看,吃惊吧,这么简单的语言的词法分析程序竟然需要这么多代码,还好我们不用手工写。编译这个源程序,得到 lex.yy.exe,测试一下
这里写图片描述
OK,简单词法分析器就完成了。

欢迎转载,转载注明出处

  • 10
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实验二 词法分析器 一、实验目的 掌握词法分析器的构造原理,掌握手工编程或LEX编程方法之一。 二、实验内容 编写一个LEX程序,使之生成一个词法分析器,能够输入的源程序转换为单词序列输出。 三、实验环境 Flex+VC6.0 四、实验注意 1.Id正则表达式:{letter}({letter}|{digit})* 2.Num正则表达式:{digit}+(\.{digit}+)?(E[+-]?{digit}+)? 3.注释:(\/\*(.)*\*\/) 4.关键字再加上其他字符就又能编程id,所以在词法分析时,id的判断应该放在关键字前面,这样才不会误判 5.由于本程序知识简单的打印数字,因此没有考虑数字的转换 6.">="比">"多一个字符,它应该放在前面判断,其他类似的也应该如此安排 五、实验代码 ******************************************************************************* 实验文件:lex.l、lex.yy.c 实验结果:lex.exe 运行方式:打开lex.exe,弹出input.txt,在其中输入所要测试的程序,保存并关闭,即可在output.txt中看到所得结果 ******************************************************************************* %{ void Install(char *type); %} %option noyywrap delim [ \t] newline [\n] digit [0-9] num {digit}+(\.{digit}+)?(E[+-]?{digit}+)? letter [A-Za-z] id {letter}({letter}|{digit})* key ("if"|"while"|"do"|"break"|"true") basic ("int"|"float"|"bool"|"char") op (">="|""|"<"|"="|"!="|"+"|"-"|"*"|"/") comment (\/\*(.)*\*\/) %% delim {;} newline {printf("\n");} {num} {Install("Num");} {key} {Install("Key");} {basic} {Install("Basic");} {op} {Install("Op");} ";" {Install("Comma");} {id} {Install("ID");} {comment} {Install("Comment");} "(" | "[" | "{" {Install("lbracket");} ")" | "]" | "}" {Install("rbracket");} %% void Install(char *s) { fprintf(yyout, "%s:%s ", s, yytext); } int main() { printf("please input the test program in input.txt\n"); system("input.txt"); yyin = fopen("input.txt", "r"); yyout = fopen("output.txt", "w" ); yylex(); fclose(yyout); fclose(yyin); printf("analysis result in output.txt\n"); system("output.txt"); return 0; } 六、实验小结 本次的实验由于使用了flex,所以代码较短,麻烦的事flex的正则式表达,由于该使用规则只有简单介绍,而网上找的教程难免有比重就轻之嫌,所以得到上述表达式着实费力,且有的没有成功,例如bracket的(\ ((.)*\ ))或者("("(.)*")")使用时都没有成功,所以便单独写出,有点不伦不类。至于其他的,都较为简单,完。
LEX是一个生成词法分析器的工具,它可以根据用户提供的正则表达式和动作列表,生成一个C语言词法分析器。如果要在Java中使用LEX生成词法分析器,可以通过JNI调用C语言词法分析器,或者使用JFlex这个专门为Java开发的词法分析器生成工具。 下面是使用JFlex生成Java词法分析器的步骤: 1. 安装JFlex 可以在JFlex官网上下载安装包,然后按照说明进行安装。 2. 编写词法规则文件 编写一个包含词法规则的文件,例如: ``` %{ import java.io.*; %} %class Lexer %unicode %public %type String %% "if" { return "IF"; } "else" { return "ELSE"; } "while" { return "WHILE"; } "(" { return "("; } ")" { return ")"; } "{" { return "{"; } "}" { return "}"; } ";" { return ";"; } [ \t\r\n] ; // ignore whitespaces . { throw new IOException("Invalid character: " + yytext()); } %% public static void main(String[] args) throws IOException { Lexer lexer = new Lexer(new FileReader(args[0])); String token; while ((token = lexer.yylex()) != null) { System.out.println(token); } } ``` 上面的规则定义了几个关键字和一些符号,同时忽略了空格和换行符。如果遇到未定义的字符,会抛出异常。 3. 生成词法分析器 使用JFlex生成词法分析器,命令如下: ``` jflex lexer.flex ``` 这会生成一个名为Lexer.java的文件,其中包含了词法分析器的代码。 4. 编译运行 将生成的Java文件编译成class文件,然后运行即可: ``` javac Lexer.java java Lexer test.txt ``` 其中test.txt是包含源代码的文件。运行结果会输出每个识别出的token。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值