-
Lex词法分析器
2017-11-14 21:31:11Lex词法分析器一.设计内容 熟悉并实现一个简单的词法分析器 二.设计目的 了解高级语言单词的分类,了解如何识别单词规则,掌握状态图到识别程序的编程。 源程序中,存在许多编辑用的符号,他们对程序逻辑功能无...Lex词法分析器
一.设计内容
熟悉并实现一个简单的词法分析器
二.设计目的
了解高级语言单词的分类,了解如何识别单词规则,掌握状态图到识别程序的编程。
源程序中,存在许多编辑用的符号,他们对程序逻辑功能无任何影响。例如:回车,换行,多余空白符,注释行等。在词法分析之前,首先要先剔除掉这些符号,使得词法分析更为简单。三.实验步骤
Lex输入文件由3个部分组成:
定义集(definition),规则集(rule)和辅助程序集(auxiliary routine)或用户程序集(user routine)。
这三个部分由位于新一行第一列的双百分号分开,因此,Lex输入文件的格式如下 :
{definitions}
%%
{rules}
%%
{auxiliary routines}将每个单词符号进行不同类别的划分。单词符号可以划分成5种:
- 标识符:用户自己定义的名字,常量名,变量名和过程名。
- 常数:各种类型的常数。
- 保留字(关键字):如if、begin、then、while、do等。
- 运算符:如+、-、*、<、>、=等。
- 界符:如逗号、分号、括号等。
将各类单词对应到lex中:
词法分析器所输出单词符号常常表示成单词种别,单词符号的属性值的二元式:
单词种别通常用整数编码。标识符一般统归为一种。常数则宜按类型(整、实、布尔等)分种。关键字可将其全体视为一种。运算符可采用一符一种的方法。界符一般用一符一种的方法。对于每个单词符号,除了给出了种别编码之外,还应给出有关单词符号的属性信息。单词符号的属性是指单词符号的特性或特征。
- 保留字:
定义识别保留字规则
reserved_word [const|var|procedure|begin|end|if|then|while|do|read|call|write|writeln]
由于在lex中不区分大小写,所以将保留字写成:
reserved_word [cC][oO][nN][sS][tT]|[vV][aA][rR]|[pP][rR][oO][cC][eE][dD][uU][rR][eE]|
[bB][eE][gG][iI][nN]|[eE][nN][dD]|[iI][fF]|[tT][hH][eE][nN]|[wW][hH][iI]
[lL][eE]|[dD][oO]|[rR][eE][aA][dD]|[cC][aA][lL][lL]|[wW][rR][iI][tT][eE]
[wW][rR][iI][tT][eE][lL][nN]- 常数:
digit ([0-9])+
- 标识符:
letter [A-Za-z] ([A-Za-z][0-9])*
- 运算符:
operator +|-|*|\/|:=|>=|<=|#|= /在lex中,有特殊意义的运算符要加转义字符\,如+、及*、/
- 分界符:
delimiter [,.;]
词法分析器要求跳过分隔符(如空格,回车,制表符)
delim [“”\n\t]
whitespace{delim}+为lex制定一些规则,统计给出程序的词法分析:
{reserved_word}{line_num++;printf(“\t%d\t(1,‘%s’)\n”,line_num,yytext);}
{operator} {line_num++;printf(“\t%d\t(2,‘%s’)\n”line_num,yytext); }
{delimiter}{line_num++;printf(“\t%d\t(3,‘%s’)\n”,line_num,yytext);}
{digit}{line_num++;printf(“\t%d\t(4,‘%s’)\n”,line_num,yytext);}
{letter}{line_num++;printf(“\t%d\t(5,‘%s’)\n”,line_num,yytext);}
{whitespace} {/* do nothing*/ }子程序:
void main() { printf("THE LEXICAL ANALYSIS GENERATOR LEX:\n"); printf("1:reserved_word\n"); printf("2:oprator\n"); printf("3:delimiter\n"); printf("4:digit\n"); printf("5:leter\n"); printf("\n"); yyin=fopen("example.txt","r"); yylex(); /* start the analysis*/ fclose(yyin); system("PAUSE"); }
example.txt为测试的程序片段
当lex 读完输入文件之后就会调用函数 yywrap 。如果返回1 表示程序的工作已经完成了。
用lex编译工具编译源程序a.l,然后生成了lex.yy.c文件,然后在有程序片的目录下编译运行该.c文件,读取example.txt,查看输出的结果既可看到分析的结果。测试程序example.txt:
def ChangeInt( a ): a = 10 b = 2 ChangeInt(b) print b
源程序a.l:
%{ #include <stdio.h> #include <stdlib.h> int count = 0; %} delim [" "\n\t] whitespace {delim}+ operator \+|-|\*|\/|:=|>=|<=|#|= reserved_word [cC][oO][nN][sS][tT]|[vV][aA][rR]|[pP][rR][oO][cC][eE][dD][uU][rR][eE]|[bB][eE][gG][iI][nN]|[eE][nN][dD]|[iI][fF]|[tT][hH][eE][nN]|[wW][hH][iI][lL][eE]|[dD][oO]|[rR][eE][aA][dD]|[cC][aA][lL][lL]|[wW][rR][iI][tT][eE]|[wW][rR][iI][tT][eE][lL][nN] delimiter [,\.;\(\)] digit ([0-9])+ letter [A-Za-z]([A-Za-z][0-9])* %% /*line_num is line number*/ {reserved_word} {line_num++;printf("%d\t(1,‘%s’)\n",line_num,yytext);} {operator} {line_num++;printf("%d\t(2,‘%s’)\n",line_num,yytext); } {delimiter} {line_num++;printf("%d\t(3,‘%s’)\n",line_num,yytext);} {digit} {line_num++;printf("%d\t(4,‘%s’)\n",line_num,yytext);} {letter} {line_num++;printf("%d\t(5,‘%s’)\n",line_num,yytext);} /*ignore whitespace*/ {whitespace} { /* do nothing*/ } %% void main() { printf("THE LEXICAL ANALYSIS GENERATOR LEX:\n"); printf("1:reserved_word\n"); printf("2:oprator\n"); printf("3:delimiter\n"); printf("4:digit\n"); printf("5:leter\n"); printf("\n"); yyin=fopen("test.txt","r"); yylex(); /* start the analysis*/ fclose(yyin); system("PAUSE"); } int yywrap() { return 1; }
测试结果:
-
Lex词法分析器.rar
2020-07-09 17:28:49LEX实现一个C语言子集的词法分析器,该词法分析器读入一个C语言的源程序,完成有以下功能。 滤掉空格。(其中空白符、制表符和换行符均视为空格,用来分隔单词) 滤掉注释。(其中注释包括两种形式:/*…*/和/... -
一个简单的lex词法分析器
2014-01-17 13:28:39一个简单的词法分析器例子,运用lex编程实现将一段C语言程序转换为词法单元识别。 -
【编译原理】Lex词法分析器
2013-12-20 16:55:36设计并实现一个词法分析器,深刻理解编译原理中词法分析器的原理。 二、实验内容 通过使用自己熟悉的语言设计并实现一个词法分析器,是此法分析器按要求的格式输出经过分析的程序段。 要求分析一下...一、实验目的
设计并实现一个词法分析器,深刻理解编译原理中词法分析器的原理。
二、实验内容
通过使用自己熟悉的语言设计并实现一个词法分析器,是此法分析器按要求的格式输出经过分析的程序段。
要求分析一下程序片段:
- const a=10;
- var b,c;
- procedure p;
- begin
- c:=b+a;
- end;
- begin
- read(b);
- while b#0 do
- begin
- call p;writeln(2*c);read(b);
- end
- end.
该程序片段存放在example.txt中。三、实验步骤
1、对PL\0文法中各类单词分类:
(1)保留字:const、var、procedure、begin、end、if、then、while、do、read、call、write、writeln
(2)常数:由0-----9这几个数字组成
(3)标识符:由字母打头的字母和数字的字符串
(4)运算符:+,-,*,/,:=,>=,<=,#
(5)分界符:,、.、(、)、;
2、将各类单词对应到lex中:
(1)保留字:
reservedWord [const|var|procedure|begin|end|if|then|while|do|read|call|write|writeln],由于在lex中不区分大小写,所以将保留字写成:
reservedWord [cC][oO][nN][sS][tT]|[vV][aA][rR]|[pP][rR][oO][cC][eE][dD][uU][rR][eE]|
[bB][eE][gG][iI][nN]|[eE][nN][dD]|[iI][fF]|[tT][hH][eE][nN]|[wW][hH][iI]
[lL][eE]|[dD][oO]|[rR][eE][aA][dD]|[cC][aA][lL][lL]|[wW][rR][iI][tT][eE]
[wW][rR][iI][tT][eE][lL][nN]
(2)常数:
constant ([0-9])+ /*0---9这几个数字可以重复*/
(3)标识符:
identfier [A-Za-z]([A-Za-z][0-9])*
(4)运算符:
operator \+|-|\*|\/|:=|>=|<=|#|= /*在lex中,有特殊意义的运算符要加转义字符\,如+、*及*、/
(5)分界符:
delimiter [,\.;\(\)]
3、PL/0的语言的词法分析器要求跳过分隔符(如空格,回车,制表符),对应的lex定义为:
delim [""\n\t]
whitespace{delim}+
4、为lex制定一些规则:
{reservedWord}{count++;printf("\t%d\t(1,‘%s’)\n",count,yytext);} /*对保留字定规则,输出设置*/
{operator} {count++;printf("\t%d\t(2,‘%s’)\n",count,yytext); }
{delimiter}{count++;printf("\t%d\t(3,‘%s’)\n",count,yytext);}
{constant}{count++;printf("\t%d\t(4,‘%s’)\n",count,yytext);}
{identfier}{count++;printf("\t%d\t(5,‘%s’)\n",count,yytext);}
{whitespace} {/* do nothing*/ } /*遇到空格,什么都不做*/
5、写子程序:
voidmain()
{
printf("词法分析器输出类型说明:\n");
printf("1:保留字\n");
printf("2:运算符\n");
printf("3:分界符\n");
printf("4:常 数\n");
printf("5:标识符\n");
printf("\n");
yyin=fopen("example.txt","r");
yylex(); /* start the analysis*/
fclose(yyin);
system("PAUSE");/*暂停*/
}
intyywrap()
{
return 1;
}
当lex 读完输入文件之后就会调用函数 yywrap 。如果返回1 表示程序的工作已经完成了,否则,返回 0。
四、实现的源代码
- %{
- #include <stdio.h>
- #include <stdlib.h>
- int count = 0;
- %}
- delim [" "\n\t]
- whitespace {delim}+
- operator \+|-|\*|\/|:=|>=|<=|#|=
- reservedWord [cC][oO][nN][sS][tT]|[vV][aA][rR]|[pP][rR][oO][cC][eE][dD][uU][rR][eE]|[bB][eE][gG][iI][nN]|[eE][nN][dD]|[iI][fF]|[tT][hH][eE][nN]|[wW][hH][iI][lL][eE]|[dD][oO]|[rR][eE][aA][dD]|[cC][aA][lL][lL]|[wW][rR][iI][tT][eE]|[wW][rR][iI][tT][eE][lL][nN]
- delimiter [,\.;\(\)]
- constant ([0-9])+
- identfier [A-Za-z]([A-Za-z][0-9])*
- %%
- {reservedWord} {count++;printf("%d\t(1,‘%s’)\n",count,yytext);}
- {operator} { count++;printf("%d\t(2,‘%s’)\n",count,yytext); }
- {delimiter} {count++;printf("%d\t(3,‘%s’)\n",count,yytext);}
- {constant} {count++;printf("%d\t(4,‘%s’)\n",count,yytext);}
- {identfier} {count++;printf("%d\t(5,‘%s’)\n",count,yytext);}
- {whitespace} { /* do nothing*/ }
- %%
- void main()
- {
- printf("词法分析器输出类型说明:\n");
- printf("1:保留字\n");
- printf("2:运算符\n");
- printf("3:分界符\n");
- printf("4:常 数\n");
- printf("5:标识符\n");
- printf("\n");
- yyin=fopen("example.txt","r");
- yylex(); /* start the analysis*/
- fclose(yyin);
- system("PAUSE");/*暂停停, 使DOS窗口停住*/
- }
- int yywrap()
- {
- return 1;
- }
五、实操作
将源代码存储为a.l,然后用flex(Lex)进行编译,输入flex a.l,编译后生成lex.yy.c文件,用c编译器打开(确保example.txt存储在相同目录下),编译运行即可!
六、运行结果
-
编译原理----Lex词法分析器
2012-12-08 21:27:51设计并实现一个词法分析器,深刻理解编译原理中词法分析器的原理。 二、实验内容 通过使用自己熟悉的语言设计并实现一个词法分析器,是此法分析器按要求的格式输出经过分析的程序段。 要求分析一下程序片段: ...一、实验目的
设计并实现一个词法分析器,深刻理解编译原理中词法分析器的原理。
二、实验内容
通过使用自己熟悉的语言设计并实现一个词法分析器,是此法分析器按要求的格式输出经过分析的程序段。
要求分析一下程序片段:
const a=10; var b,c; procedure p; begin c:=b+a; end; begin read(b); while b#0 do begin call p;writeln(2*c);read(b); end end.
该程序片段存放在example.txt中。三、实验步骤
1、对PL\0文法中各类单词分类:
(1)保留字:const、var、procedure、begin、end、if、then、while、do、read、call、write、writeln
(2)常数:由0-----9这几个数字组成
(3)标识符:由字母打头的字母和数字的字符串
(4)运算符:+,-,*,/,:=,>=,<=,#
(5)分界符:,、.、(、)、;
2、将各类单词对应到lex中:
(1)保留字:
reservedWord [const|var|procedure|begin|end|if|then|while|do|read|call|write|writeln],由于在lex中不区分大小写,所以将保留字写成:
reservedWord [cC][oO][nN][sS][tT]|[vV][aA][rR]|[pP][rR][oO][cC][eE][dD][uU][rR][eE]|
[bB][eE][gG][iI][nN]|[eE][nN][dD]|[iI][fF]|[tT][hH][eE][nN]|[wW][hH][iI]
[lL][eE]|[dD][oO]|[rR][eE][aA][dD]|[cC][aA][lL][lL]|[wW][rR][iI][tT][eE]
[wW][rR][iI][tT][eE][lL][nN]
(2)常数:
constant ([0-9])+ /*0---9这几个数字可以重复*/
(3)标识符:
identfier [A-Za-z]([A-Za-z][0-9])*
(4)运算符:
operator \+|-|\*|\/|:=|>=|<=|#|= /*在lex中,有特殊意义的运算符要加转义字符\,如+、*及*、/
(5)分界符:
delimiter [,\.;\(\)]
3、PL/0的语言的词法分析器要求跳过分隔符(如空格,回车,制表符),对应的lex定义为:
delim [""\n\t]
whitespace{delim}+
4、为lex制定一些规则:
{reservedWord}{count++;printf("\t%d\t(1,‘%s’)\n",count,yytext);} /*对保留字定规则,输出设置*/
{operator} {count++;printf("\t%d\t(2,‘%s’)\n",count,yytext); }
{delimiter}{count++;printf("\t%d\t(3,‘%s’)\n",count,yytext);}
{constant}{count++;printf("\t%d\t(4,‘%s’)\n",count,yytext);}
{identfier}{count++;printf("\t%d\t(5,‘%s’)\n",count,yytext);}
{whitespace} {/* do nothing*/ } /*遇到空格,什么都不做*/
5、写子程序:
voidmain()
{
printf("词法分析器输出类型说明:\n");
printf("1:保留字\n");
printf("2:运算符\n");
printf("3:分界符\n");
printf("4:常 数\n");
printf("5:标识符\n");
printf("\n");
yyin=fopen("example.txt","r");
yylex(); /* start the analysis*/
fclose(yyin);
system("PAUSE");/*暂停*/
}
intyywrap()
{
return 1;
}
当lex 读完输入文件之后就会调用函数 yywrap 。如果返回1 表示程序的工作已经完成了,否则,返回 0。
四、实现的源代码
%{ #include <stdio.h> #include <stdlib.h> int count = 0; %} delim [" "\n\t] whitespace {delim}+ operator \+|-|\*|\/|:=|>=|<=|#|= reservedWord [cC][oO][nN][sS][tT]|[vV][aA][rR]|[pP][rR][oO][cC][eE][dD][uU][rR][eE]|[bB][eE][gG][iI][nN]|[eE][nN][dD]|[iI][fF]|[tT][hH][eE][nN]|[wW][hH][iI][lL][eE]|[dD][oO]|[rR][eE][aA][dD]|[cC][aA][lL][lL]|[wW][rR][iI][tT][eE]|[wW][rR][iI][tT][eE][lL][nN] delimiter [,\.;\(\)] constant ([0-9])+ identfier [A-Za-z]([A-Za-z][0-9])* %% {reservedWord} {count++;printf("%d\t(1,‘%s’)\n",count,yytext);} {operator} { count++;printf("%d\t(2,‘%s’)\n",count,yytext); } {delimiter} {count++;printf("%d\t(3,‘%s’)\n",count,yytext);} {constant} {count++;printf("%d\t(4,‘%s’)\n",count,yytext);} {identfier} {count++;printf("%d\t(5,‘%s’)\n",count,yytext);} {whitespace} { /* do nothing*/ } %% void main() { printf("词法分析器输出类型说明:\n"); printf("1:保留字\n"); printf("2:运算符\n"); printf("3:分界符\n"); printf("4:常 数\n"); printf("5:标识符\n"); printf("\n"); yyin=fopen("example.txt","r"); yylex(); /* start the analysis*/ fclose(yyin); system("PAUSE");/*暂停停, 使DOS窗口停住*/ } int yywrap() { return 1; }
五、实操作
将源代码存储为a.l,然后用flex(Lex)进行编译,输入flex a.l,编译后生成lex.yy.c文件,用c编译器打开(确保example.txt存储在相同目录下),编译运行即可!
六、运行结果
Lex与yacc确实是很不错的工具!如果单用编程语言,如C,C++,Java写的话,代码就多了不少。 -
Fast Lex词法分析工具
2008-08-19 14:20:56Lex是一个基于正则表达式的描述词法分析器的工具,已经广泛用于产生各种语言的词法分析器,也称为Lex编译器。它的输入使用Lex语言编写的源程序,在Lex源程序中,要将基于正则表达式的模式说明与词法分析器要完成的... -
基于lex的词法分析器
2012-07-14 10:25:14编译原理课程设计 运用c语言 外加lex进行词法分析 -
LEX/FLEX词法分析器
2015-09-22 01:14:07LEX/FLEX词法分析器CONTENTS:LEXFLEX词法分析器 LexFlex词法分析器 Flex的安装和使用 Lex语法格式 definitions rules user subroutines FLEX实例这篇文章的内容包括: lex语法格式 linux下flex的安装和使用 flex...LEX/FLEX词法分析器
CONTENTS:
这篇文章的内容包括:
lex语法格式
linux下flex的安装和使用
flex实例
flex源代码的编译和使用
Lex/Flex词法分析器
Lex是LEXical compiler的缩写,是Unix环境下非常著名的工具,主要功能是生成一个词法分析器(scanner)的C源码,描述规则采用正则表达式(regular expression)。描述词法分析器的文件*.l,经过lex编译后,生成一个lex.yy.c 的文件,然后由C编译器编译生成一个词法分析器。词法分析器,简单来说,其任务就是将输入的各种符号,转化成相应的标识符(token),转化后的标识符 很容易被后续阶段处理。 —— [ 百度百科 ]
Flex的安装和使用
在使用apt软件包管理器linux系统上我们可以非常方便地安装并使用flex。在终端中输入以下代码安装flex:(可能需要root权限)
$> sudo apt-get install flex
flex代码的源文件往往是以.l为后缀名的。
.l文件通过以下命令编译(以文件名为scanner.l为例):$> flex scanner.l
编译后在源代码相同目录下会生成一个lex.yy.c,这就是生成的能够执行上述scanner.l功能的c语言代码。使用gcc编译即可生成词法分析程序1:
$> gcc lex.yy.c -o scanner
然后将需要分析的文件(以input.txt为例)作为参数传递给scanner执行分析:
$> ./scanner input.txt
Lex语法格式
flex的语法被分为三个部分:
{definitions} %% {rules} %% {user subroutines}
definitions:
LABEL REGULAR_EXPRESSION
LABEL是这里类字符串的名称,REGULAR_EXPRESSION则是匹配这种字符串的正则表达式。正则表达式的语法主要包括:
符号 含义 | 或 [] 括号中的字符取其一 - a-z表示ascii码中介于a-z包括a.z的字符 \ 转义(flex不能识别除字母外的字符) * 0或多个字符 ? 0或1个字符 + 1或多个字符 ^ 除此之外的其余字符 . 除\n外的所有字符,等价于^\n 示例:
1. INT [1-9][0-9]*|[0] /*整数类型,0或不以0开头的由0-9组成的字符串*/ 2. FLOAT [0-9]*[.][0-9]+([eE][+-]?[0-9]*|[0])?f? /*浮点数格式*/ 3. LP \( /*一个左圆括号*/
注:用%{ %}括起来的语句将被完全写入编译后的c语言文件中。
例如%{
#include <stdio.h>
int num_id = 0;
%}rules:
规则部分的语法如下:
{LABEL1} | {LABLE2} | ... { /*TODO*/ }
TODO部分是告诉编译器在匹配到字符串之后程序需要做些什么。
例如在匹配到整数后打印这个整数:{INT} { printf("Pick up an integer, value is %d", atoi(yytext)); printf("Pick up an integer, value is %s", yytext); }
其中atoi()函数将字符串转换为整数。
user subroutines
此处主要是放置用户需要执行的c语言代码。他们会被原封不动地加入到lex.yy.c文件的末尾。
这里一般用来存放main函数,详细会在后面说明。FLEX实例
下面通过一个实例来具体展示flex的使用方式,主要功能是扫描并匹配文件中的字符串,并回显其类型和内容,代码如下:
/************************ * scanner.l * @author mist * 2015-9-21 23:08 ************************/ %{ #include "stdio.h" #include "stdlib.h" %} INT_DEX [1-9][0-9]*|[0] INT_HEX [0][Xx]([1-9][0-9]*|[0]) INT_OCT [0][0-7] FLOAT [0-9]*[.][0-9]+([eE][+-]?[0-9]*|[0])?f? SEMI [;] COMMA [,] ASSIGNOP [=] RELOP [>]|[<]|[>][=]|[<][=]|[=][=]|[!][=](^[=]) PLUS [+] MINUS [-] STAR [*] DIV [/] AND [&][&] OR [|][|] DOT [.] NOT [!] TYPE int|float LP \( RP \) LB \[ RB \] LC \{ RC \} STRUCT struct RETURN return IF if ELSE else WHILE while SPACE [ \n\t] ID [a-zA-Z_][a-zA-Z_0-9]* /*end of definition*/ %% {SEMI} { printf("get semmi : %s\n", yytext); } {COMMA} { printf("get comma : %s\n", yytext); } {ASSIGNOP} { printf("get assignop : %s\n", yytext); } {INT_DEX} | {INT_HEX} | {INT_OCT} { printf("get an integer: %s\n", yytext); } {FLOAT} { printf("get a float: %s\n", yytext); } {PLUS} | {MINUS} | {DIV} | {STAR} { printf("get an operator: %s\n", yytext); } {RELOP} { printf("get a relop: %s\n", yytext); } {AND} | {OR} | {NOT} { printf("get a logic operator: %s\n", yytext); } {DOT} { printf("get a dot: %s\n", yytext); } {STRUCT} | {RETURN} | {IF} | {ELSE} | {WHILE} { printf("get keyword: %s\n", yytext); } {TYPE} { printf("get type: %s\n", yytext); } {LP} | {RP} | {LB} | {RB} | {LC} | {RC} { printf("get brackets : %s\n", yytext); } {SPACE} | . { /*ABANDON THESE CHARACTORS*/ } {ID} { printf("get an ID: %s\n", yytext); } %% int yywrap() { return 1; } int main(int argc, char** argv) { if (argc > 1) { if (!(yyin = fopen(argv[1], "r"))) { perror(argv[1]); return 1; } } while (yylex()); return 0;
我们需要为生成的分析程序编写main函数。首先需要通过yyin来获取指向被分析文件的文件FILE指针,一般文件的路径通过控制台的第二个参数获得。分析部分的实体在函数yylex()中。
yywrap()用于判断是否已经扫描完了所有的文件。如果它在最后一个文件的末尾被调用,则返回值为1。此时程序将停止分析,可以用来扫描多个文件。输入文本:
int float {}()[] 0
0x0 0x123
123.5
.3e-10f
= >= || && ! ; ,
this_is_an_id
id123
if then else
输出:get type: int get type: float get brackets : { get brackets : } get brackets : ( get brackets : ) get brackets : [ get brackets : ] get an integer: 0 get an integer: 0x0 get an integer: 0x123 get a float: 123.5 get a float: .3e-10f get assignop : = get a relop: >= get a logic operator: || get a logic operator: && get a logic operator: ! get semmi : ; get comma : , get an ID: this_is_an_id get an ID: id123 get keyword: if get an ID: then get keyword: else
另外附上词法要求:
INT /* A sequence of digits without spaces1 */
FLOAT /* A real number consisting of digits and one decimal point. The deci-
mal point must be surrounded by at least one digit2 */
ID /* A character string consisting of 52 upper- or lower-case alphabetic, 10
numeric and one underscore characters. Besides, an identifier must not start
with a digit3 */
SEMI ;
COMMA ,
ASSIGNOP =
RELOP > | < | >= | <= | == | !=
PLUS +
MINUS -
STAR *
DIV /
AND &&
OR ||
DOT .
NOT !
TYPE int | float
LP (
RP )
LB [
RB ]
LC {
RC }
STRUCT struct
RETURN return
IF if
ELSE else
WHILE while1) 词法单元INT表示的是所有(无符号)整型常数。一个十进制整数由0~9十个数字组
成,数字与数字中间没有如空格之类的分隔符。除“0”之外,十进制整数的首位数字
不为0。例如,下面几个串都表示十进制整数:0、234、10000。为方便起见,你可以
假设(或者只接受)输入的整数都在32bits位之内。2) 整型常数还可以以八进制或十六进制的形式出现。八进制整数由0~7八个数字组成并以
数字0开头,十六进制整数由0~9、A~F(或a~f)十六个数字组成并以0x或者0X开头。
例如,0237(表示十进制的159)、0xFF32(表示十进制的65330)。3) 词法单元FLOAT表示的是所有(无符号)浮点型常数。一个浮点数由一串数字与一个
小数点组成,小数点的前后必须有数字出现。例如,下面几个串都是浮点数:0.7、
12.43、9.00。为方便起见,你可以假设(或者只接受)输入的浮点数都符合IEEE754单
精度标准(即都可以转换成C语言中的float类型)。4) 浮点型常数还可以以指数形式(即科学记数法)表示。指数形式的浮点数必须包括基
数、指数符号和指数三个部分,且三部分依次出现。基数部分由一串数字(0~9)和一
个小数点组成,小数点可以出现在数字串的任何位置;指数符号为“E”或“e”;指
数部分由可带“+”或“”(也可不带)的一串数字(0~9)组成,“+”或“”(如
果有)必须出现在数字串之前。例如01.23E12(表示1.23 1012)、43.e-4(表示43.0
10-4)、.5E03(表示0.5 103)。5) 词法单元ID表示的是除去保留字以外的所有标识符。标识符可以由大小写字母、数字
以及下划线组成,但必须以字母或者下划线开头。为方便起见,你可以假设(或者只
接受)标识符的长度小于32个字符。6) 除了INT、FLOAT和ID这三个词法单元以外,其它产生式中箭头右边都表示具体的字
符串。例如,产生式TYPE int | float表示:输入文件中的字符串“int”和“float”都
将被识别为词法单元TYPE。
2.2
High-level Definitions- 生成词法分析程序 可能会发生yywrap未定义的错误。yywrap必须由用户亲自编写,一般按如下形式即可:
void yywrap() { return 1; } ↩
-
编译原理课程设计+报告(用高级语言(c++)实现词法分析器、用lex实现词法分析器、LL1实现语法分析)打包...
2016-06-29 12:22:11编译原理课程设计:用高级语言(c++)实现词法分析器、用lex实现词法分析器、LL1实现语法分析。附加完整实验报告(已排版,可直接打印) -
自制Lex-词法分析器生成器(C++)
2016-10-31 23:03:26前一阵子,编译原理课实验内容是要去做一个词法分析器,实现后,觉得没有把正规表达式和NFA、DFA这些知识用上,所以就产生了想自己去实现一个lex的想法,于是就有了这篇博文。 如果还不知道词法分析器该怎么实现... -
编译原理课程设计(用高级语言(c++)实现词法分析器、用lex实现词法分析器、LL1实现语法分析)打包上传
2016-06-29 12:14:57编译原理课程设计:用高级语言(c++)实现词法分析器、用lex实现词法分析器、LL1实现语法分析。前两个是我自己写的,也测试过,正常;LL1不是我写的,也没经过测试...大家慎重使用LL1 -
Lex:词法分析器的生成器
2014-06-19 08:50:16Lex是一种词法分析器的生成器, -
Lex - 词法分析器生成器
2011-09-26 16:57:01它适合于编辑器脚本类型的变换,和为解析例程做准备工作而分解输入。 Lex 源码是正则表达式和相应的程序片段的表格。Lex 把这个表格变换成读取输入流、复制它到输出流、并把输入划分到匹配给定表达式的字符串中的一... -
基于LEX的语言词法分析器.zip
2019-10-14 20:46:18基于LEX的语言词法分析器,包括LEX环境配置,手写版+LEX版,北邮大三编译原理作业。 -
LEX自动生成词法分析器
2015-11-08 23:34:48词法分析器作为编译器的一个重要组成部分,原理很简单,代码也都没什么技术含量,但是如果让你手工写一个词法分析器,哪怕是一个简单的词法分析器,工作量无疑是巨大的。现代的词法分析器一般都是依靠工具自动生成,... -
编译原理实验三:用lex设计词法分析器2
2020-05-13 08:00:06学会用lex设计一个词法分析器,并考虑其与后续语法分析器的链接问题。 实验内容: 修改上次实验2的词法分析器,使其满足下列要求。 实验要求: 要求每次调用词法分析函数yylex时,只返回一个记号(token); 为记号... -
编译原理实验二:用Lex设计词法分析器1
2020-05-12 09:34:23学会用lex设计一个词法分析器。 实验内容: 使用lex为下述文法语言写一个词法分析器。 语言文法: <程序> --> PROGRAM <标识符> ; <分程序> <分程序> --> <变量说明> BEGIN <... -
Yacc 与 Lex-词法分析器工具
2017-04-24 11:33:361.下载词法分析器工具 http://download.csdn.net/download/pikaxuji/4382949 2.解压后如图所示 先安装flex-2.5.4a-1.exe 再安装第一个文件,安装后会在同一个目录 以我的为例:D:\Mysoft\GnuWin32\GnuWin32 ... -
利用LEX实现词法分析器(vs2010 + Parser Generator版)
2015-07-06 16:15:38利用LEX实现词法分析器(vs2010 + Parser Generator版) 前言 最近在学习编译原理,需要利用LEX自动生成一个词法分析器。下面把我个人的经验与大家分享一下。 关于词法分析器生成工具LEX简介请大家... -
lex一个词法分析器的生成器_翻译版
2013-05-31 18:04:26lex一个词法分析器的生成器_翻译版,编译原理课程的上机题目 -
lex_实验-编译原理词法分析器实现
2018-05-02 23:51:16这是一个编译原理lex工具,具备词法分析器的功能,方便了解编译原理词法分析器的功能 -
词法分析器
2018-04-22 10:41:42lex词法分析器用于消除二义性的两条规则 There are two important disambiguation rules used by Lex and other similar lexical-analyzer generators: Longest match: The longest initial substring of the ... -
词法分析器生成工具lex使用
2019-10-06 00:09:30词法分析器生成工具lex使用 《词法分析器生成工具lex使用》,作者:GOD_YCA,原文链接:http://www.cnblogs.com/GODYCA/archive/2013/01/03/2843096.html 分享自:博客园Android客户端(http:...