编译原理实践10—词法分析程序的自动生成器LEX
- 格式:ppt
- 大小:890.00 KB
- 文档页数:27
编译原理词法分析与语法分析的核心算法编译原理是计算机科学与技术领域中的一门重要课程。
在编程中,我们常常需要将高级语言编写的程序翻译成机器语言,使计算机能够理解并执行我们编写的程序。
而编译原理中的词法分析和语法分析是编译器的两个核心算法。
一、词法分析词法分析是编译器的第一个阶段,它负责将输入的字符序列(源代码)划分为一个个的有意义的词素(Token),并生成相应的词法单元(Lexeme)。
词法分析的核心算法主要包括以下两个步骤:1. 正则表达式到有限自动机的转换:正则表达式是一种描述字符串匹配模式的表达式,它可以用来描述词法分析中各种词素的规则。
而有限自动机则是一种用来识别或匹配正则表达式所描述的模式的计算模型。
将正则表达式转换为有限自动机是词法分析的关键步骤之一。
2. 词法分析器的生成:在将正则表达式转换为有限自动机后,我们可以使用生成器工具(如Lex、Flex等)来生成词法分析器。
词法分析器可以按照预定的规则扫描源代码,并将识别出的词素转换成相应的词法单元,供后续的语法分析使用。
二、语法分析语法分析是编译器的第二个阶段,它负责分析和处理词法分析阶段生成的词法单元序列,并根据预定的语法规则确定语法正确的序列。
语法分析的核心算法主要包括以下两个步骤:1. 上下文无关文法的定义:上下文无关文法(Context-Free Grammar,简称CFG)是一种用于描述形式语言的文法。
它由一组产生式和终结符号组成,可以用于描述语法分析中的语法规则。
在语法分析中,我们需要根据具体编程语言的语法规则,编写相应的上下文无关文法。
2. 语法分析器的生成:通过使用生成器工具(如Yacc、Bison等),我们可以根据上下文无关文法生成语法分析器。
语法分析器可以根据预先定义的文法规则,对词法单元序列进行分析,并构建出语法树(Parse Tree)供后续的语义分析和代码生成使用。
综上所述,词法分析与语法分析是编译原理中的两个重要阶段,也是实现编译器的核心算法。
Lex和Y acc工具介绍――编译原理的实用工具1.词法分词器生成工具lexLex的主要功能是生成一个词法分析器(scanner)的C源码。
描述词法分析器的文件,经过lex编译后,生成一个lex.yy.c的文件,然后由C编译器编译生成一个词法分析器。
词法分析器,简单来说,其任务就是将输入的各种符号,转化成相应的标识符(token),转化后的标识符很容被后续阶段处理。
过程如错误!未找到引用源。
图1现在这个lex 文件可以用来生成一个统计行数、字符个数和单词个数的工具。
规则段是由正则表达式和相应的动作组成的。
p 1 {action 1}p 2 {action 2}……p n {action n }值得注意的是,lex 依次尝试每一个规则,尽可能地匹配最长的输入流。
如果有一些内容根可以看出lex的确按照最长的规则匹配。
程序段部分放一些扫描器的其它模块,比如一些动作执行时需要的模块。
也可以在另一个程序文件中编写,最后再链接到一起。
生成C代码后,需用C的编译器编译。
连接时需要指定链接库。
gcc的连接参数为 -ll。
2.正则表达式正则表达式可以描述有穷状态自动机(Finite Automata)接受的语言,也就是定义一个可以接受的串的集合。
转义字符(也称操作符):" \ [ ] ^ - ? . * + | ( ) $ / { } % < >这些符号有特殊含义,不能用来匹配自身。
如果需要匹配的话,可以通过引号(’’)或者转义符号(\)来指示。
比如C”++”C\+\+都可以匹配C++。
非转义字符:所有除了转义字符之外的字符都是非转义字符。
一个非转义字符可以匹配自身。
比如integer匹配文本中出现的integer。
通配符:通配符就是”.”(dot),可以匹配任何一个字符。
字符集:用一对[]指定的字符构成一个字符集。
比如[abc]表示一个字符集,可以匹配a、b、c中的任意一个字符。
使用–可以指定范围。
Lex工具Lex工具是一种词法分析程序生成器,它可以根据词法规则说明书的要求来生成单词识别程序,由该程序识别出输入文本中的各个单词。
1、lex程序的结构-定义部分-规则部分-用户子程序部分其中规则部分是必须的,定义和用户子程序部分是任选的。
(1) 定义部分定义部分起始于"%{"符号,终止于"%}"符号,其间可以是包括include语句、声明语句在内的C语句。
%{#include "stdio.h"#include "y.tab.h"extern int lineno;%}(2) 规则部分规则部分起始于"%%"符号,终止于"%%"符号,其间则是词法规则。
词法规则由模式和动作两部分组成。
模式部分可以由任意的正则表达式组成,动作部分是由C语言语句组成,这些语句用来对所匹配的模式进行相应处理。
需要注意的是,lex将识别出来的单词存放在yytext[]字符数据中,因此该数组的内容就代表了所识别出来的单词的内容。
%%[\t] {;}[0-9]+\.?|[0-9]*\.[0-9]+{ sscanf(yytext,"%1f", &yylval.val);return NUMBER; }\n { lineno++;return '\n'; }. { return yytex+[0]; }%%(3) 用户子程序部分用户子程序部分可以包含用C语言编写的子程序,而这些子程序可以用在前面的动作中,这样就可以达到简化编程的目的。
下面是带有用户子程序的lex程序片段。
"/*" skipcmnts();. /* rest of rules */%%skipcmnts(){for ( ; ; ){while (input()!='*');if(input()!='/')unput(yytext[yylen-1]);else return;}2、lex工具的使用方法首先编写一个lex程序vi lex.l%{#include "stdio.h"%}%%[\n] ;[0-9]+ printf("Interger: %s \n",yytext);[0-9]*\.[0-9]+ printf("Float: %s\n",yytext);[a-zA-Z][a-zA-Z0-9]* printf("Word:%s\n",yytext);. printf("Other symbol:%c\n",yytext[0]);%%然后使用lex将lex.l转换成C语言程序$lex lex.l使用上述命令产生的C语言程序为lex.yy.c然后使用C编译程序将lex.yy.c编译成可执行程序regn$cc -c lex.yy.c$cc lex.yy.o -ll -o regn下面可以使用regn来识别单词$vi testfilex=355y=113p=x/y# ./regn < testfileWord:xOther symbol:=Interger: 355Word:yOther symbol:=Interger: 113Word:pOther symbol:=Word:xOther symbol:/Word:y#yacc工具--------yacc工具是一种语法分析程序生成器,它可以将有关某种语言的语法说明书转换成相应的语法分析程序,由该程序完成对相应语言中语句的语法分析工作。
基于LEX的C语言词法分析器下面是一个基于LEX的C语言词法分析器的示例代码:```c#include <stdio.h>%}letter [a-zA-Z]digit [0-9]id {letter}({letter},{digit})*number {digit}+(\.{digit}+)?([eE][+-]?{digit}+)?%%{number} { printf("Number: %s\n", yytext); }{if} { printf("If: %s\n", yytext); }{else} { printf("Else: %s\n", yytext); }{while} { printf("While: %s\n", yytext); }{for} { printf("For: %s\n", yytext); }{id} { printf("Identifier: %s\n", yytext); }[ \t\n]+ // ignore white space. { printf("Unrecognized character: %c\n", yytext[0]); }%%int maiyylex(;return 0;```在上述代码中,首先是一些初始化的定义,定义了一些正则表达式模式,例如`letter`表示字母,`digit`表示数字,`id`表示标识符,`number`表示数字。
然后是各个模式的匹配规则和对应的处理逻辑。
其中,`{number}`表示如果匹配到了数字模式,就打印出该数字;`{if}`、`{else}`、`{while}`、`{for}`和`{id}`分别表示匹配到了if、else、while、for关键字和标识符,就打印出对应的信息;`[ \t\n]+`表示忽略空格和换行符;`.`表示匹配到了其他未定义的字符,就打印出异常信息。
编译原理中的词法分析与语法分析原理解析编译原理是计算机科学中的重要课程,它研究的是如何将源程序翻译成目标程序的过程。
而词法分析和语法分析则是编译过程中的两个重要阶段,它们负责将源程序转换成抽象语法树,为接下来的语义分析和代码生成阶段做准备。
本文将从词法分析和语法分析的原理、方法和实现技术角度进行详细解析,以期对读者有所帮助。
一、词法分析的原理1.词法分析的定义词法分析(Lexical Analysis)是编译过程中的第一个阶段,它负责将源程序中的字符流转换成标记流的过程。
源程序中的字符流是没有结构的,而编程语言是有一定结构的,因此需要通过词法分析将源程序中的字符流转换成有意义的标记流,以便之后的语法分析和语义分析的进行。
在词法分析的过程中,会将源程序中的字符划分成一系列的标记(Token),每个标记都包含了一定的语义信息,比如关键字、标识符、常量等等。
2.词法分析的原理词法分析的原理主要是通过有限状态自动机(Finite State Automaton,FSA)来实现的。
有限状态自动机是一个数学模型,它描述了一个自动机可以处于的所有可能的状态以及状态之间的转移关系。
在词法分析过程中,会将源程序中的字符逐个读取,并根据当前的状态和字符的输入来确定下一个状态。
最终,当字符读取完毕时,自动机会处于某一状态,这个状态就代表了当前的标记。
3.词法分析的实现技术词法分析的实现技术主要有两种,一种是手工实现,另一种是使用词法分析器生成工具。
手工实现词法分析器的过程通常需要编写一系列的正则表达式来描述不同类型的标记,并通过有限状态自动机来实现这些正则表达式的匹配过程。
这个过程需要大量的人力和时间,而且容易出错。
而使用词法分析器生成工具则可以自动生成词法分析器的代码,开发者只需要定义好源程序中的各种标记,然后通过这些工具自动生成对应的词法分析器。
常见的词法分析器生成工具有Lex和Flex等。
二、语法分析的原理1.语法分析的定义语法分析(Syntax Analysis)是编译过程中的第二个阶段,它负责将词法分析得到的标记流转换成抽象语法树的过程。
词法分析程序自动工具使用说明1.建立工作文件夹如D:\LEX2.将词法分析工具flex.exe 拷入到该文件夹3.建立LEX源文件如:用文本编辑器建立lextemp.txt源文件%{#include <stdio.h>#define BEGIN 101#define END 202%}digit [0-9]alpha [a-z]alnum [a-z0-9]%%begin {out(BEGIN,"begin");}end {out(END,"end");}"*" {out(303,"*");}"+" {out(404,"+");}{alpha}{alnum}* {out(505,yytext);}"=" {out(606,"=");}%%out(int c,char *val){printf("word:%d, %s\n",c,val);}4.建立简单语言的源程序文件如:用文本编辑器建立data.txt文件beginabcd=100efg=200gh123=300abcd=abcd*efgh+gh123end5.在DOS运行flex 生成目标文件lex.yy.c flex lex源文件名如:d:\lex\flex lextemp.txt6.进入VC,对lex.yy.c进行修改(1)增加或修改main()函数增加打开程序文件的语句int main(void){int c;if ((yyin=fopen("data.txt","r"))==NULL){printf("can’t open the file\n");exit(0);}yylex();return 0;}(2)增加函数int yywrap(){return 0;}(3)尾部这二行屏蔽// #if YY_MAIN// #Endif7.运行得到结果识别出的单词将在屏幕输出,通过修改out 函数可改为输出到一文件中。
编译原理lex和yacc的综合设计python
1、Lex和Yacc是一种强大的词法分析和语法分析技术,它们常用于编译器的开发和编写编译器前端。
它们分别可以分析和解释输入字符流,并产生相应的输出。
Lex是一个词法分析器,它可以将输入字符流分解为令牌(即识别的节点),这些令牌可以用于编写解释器或编译器的前端。
Yacc则是一种用来构建语法分析器的工具,它可以识别输入的令牌序列,并生成相应的程序。
2、编译原理是编译器的最小系统,它涉及源程序的分析和分解,目标程序的生成和优化,以及中间代码的翻译。
Lex和Yacc则是用来处理字符流和语法检查的两个有力工具,在处理中间代码生成和优化方面非常有用,是编译器的核心部分。
3、Lex和Yacc的综合设计一般需要借助某种语言将可执行模块链接起来,最常用的技术是使用C,C是一种高性能语言,可以让开发者实现快速迭代,也可以利用其标准库实现代码复用,因此是完成Lex和Yacc综合设计的最佳语言。
4、Python是一种脚本语言,不适合用于编写Lex和Yacc综合设计,因为Python 并不专业,不能满足低级程序设计的需求,处理过程中往往性能不佳。