编译原理 简单样本语言的词法分析器
编译原理中的词法分析与语法分析原理解析
编译原理中的词法分析与语法分析原理解析编译原理中的词法分析和语法分析是编译器中两个基本阶段的解析过程。
词法分析(Lexical Analysis)是将源代码按照语法规则拆解成一个个的词法单元(Token)的过程。
词法单元是代码中的最小语义单位,如标识符、关键字、运算符、常数等。
词法分析器会从源代码中读取字符流,将字符流转换为具有词法单元类型和属性值的Token序列输出。
词法分析过程中可能会遇到不合法的字符序列,此时会产生词法错误。
语法分析(Syntax Analysis)是对词法单元序列进行语法分析的过程。
语法分析器会根据语法规则,将词法单元序列转换为对应的抽象语法树(Abstract Syntax Tree,AST)。
语法规则用于描述代码的结构和组织方式,如变量声明、函数定义、控制流结构等。
语法分析的过程中,语法分析器会检查代码中的语法错误,例如语法不匹配、缺失分号等。
词法分析和语法分析是编译器的前端部分,也是编译器的基础。
词法分析和语法分析的正确性对于后续的优化和代码生成阶段至关重要。
拓展部分:除了词法分析和语法分析,编译原理中还有其他重要的解析过程,例如语义分析、语法制导翻译、中间代码生成等。
语义分析(Semantic Analysis)是对代码进行语义检查的过程。
语义分析器会根据语言的语义规则检查代码中的语义错误,例如类型不匹配、变量声明未使用等。
语义分析还会进行符号表的构建,维护变量和函数的属性信息。
语法制导翻译(Syntax-Directed Translation)是在语法分析的过程中进行语义处理的一种技术。
通过在语法规则中嵌入语义动作(Semantic Action),语法制导翻译可在语法分析的同时进行语义处理,例如求解表达式的值、生成目标代码等。
中间代码生成(Intermediate Code Generation)是将高级语言源代码转换为中间表示形式的过程。
中间代码是一种抽象的表示形式,可以是三地址码、四元式等形式。
词法分析器 编译原理
《编译原理》——词法分析器学院:专业:姓名:学号:一、序言编译,简单的说,就是把源程序转换为可执行程序。
编译程序的工作,从输入源程序开始到输出目标程序为止的整个过程,是非常复杂的。
而此法分析是编译程序工作过程的第一环节。
这篇报告主要讲了词法分析器的原理,最后会给出一个词法分析器的简单实现。
二、实验目的设计一个词法分析程序,理解词法分析器实现的原理,掌握程序设计语言中的各类单词的词法分析方法,加深对词法分析原理的理解。
三、词法分析原理3.1 词法分析的任务是:输入源程序,对构成源程序的字符串进行扫描和分解,识别出一个个的单词(亦称为单词符号或简称符号),如基本字(begin、end、for、if、while等),标识符、常数、算符、和界符(标点符号、左右括号等等)。
例如,对于pascal的循环语句For I:=1 to 100 do词法分析的结果是识别出如下的单词符号:基本字for标识符I赋值号:=整常数 1基本字to整常数100基本字do3.2 输出:词法分析器所输出单词符号常常表示成如下的二元式:(单词种别,单词符号的属性值)单词种别通常用整数编码。
标识符一般统归为一种。
常数则宜按类型(整、实、布尔等)分种。
关键字可将其全体视为一种。
运算符可采用一符一种的方法。
界符一般用一符一种的方法。
对于每个单词符号,除了给出了种别编码之外,还应给出有关单词符号的属性信息。
单词符号的属性是指单词符号的特性或特征。
例子:C++代码段:while(i>=j) i--经词法分析器处理后,它将被转为如下的单词符号序列:<while, _><(, _><id, 指向i的符号表项的指针><>=, _><id, 指向j的符号表项的指针><), _><id, 指向i的符号表项的指针><--, _><;, _>3.3 词法分析分析器作为一个独立子程序词法分析是编译过程中的一个阶段,在语法分析前进行。
编译原理实验报告一 简单样本语言的词法分析器
昆明理工大学信息工程与自动化学院学生实验报告(2012 —2013学年第一学期)一、实验目的及内容编译技术是理论与实践并重的课程,而其实验课要综合运用所学的多门课程的内容,用来完成一个小型编译程序。
从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。
调试并完成一个词法分析程序,加深对词法分析原理的理解。
二、实验原理及基本技术路线图(方框原理图或程序流程图)1、待分析的简单语言的词法(1)关键字:begin if then while do end所有关键字都是小写。
(2)运算符和界符::= + –* / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:ID=letter(letter| digit)*NUM=digit digit *(4)空格由空白、制表符和换行符组成。
空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。
2、各种单词符号对应的种别码3、词法分析程序的功能输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。
二、所用仪器、材料(设备名称、型号、规格等或使用软件)1台PC以及VISUAL C++6.0软件。
三、实验方法、步骤(或:程序代码或操作过程)(1)程序代码:#include<stdio.h>#include<string.h>#include<iostream.h>char prog[80],token[8];char ch;int syn,p,m=0,n,row,sum=0;char *rwtab[6]={"begin","if","then","while","do","end"};void scaner(){for(n=0;n<8;n++) token[n]=NULL;ch=prog[p++];while(ch==' '){ch=prog[p];p++;}if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){m=0;while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){token[m++]=ch;ch=prog[p++];}token[m++]='\0';p--;syn=10;for(n=0;n<6;n++)if(strcmp(token,rwtab[n])==0){syn=n+1;break;}}else if((ch>='0'&&ch<='9')){{sum=0;while((ch>='0'&&ch<='9')){sum=sum*10+ch-'0';ch=prog[p++];}}p--;syn=11;if(sum>32767)syn=-1;}else switch(ch){case'<':m=0;token[m++]=ch;ch=prog[p++];if(ch=='>'){syn=21;token[m++]=ch;}else if(ch=='='){syn=22;token[m++]=ch;}else{syn=23;p--;}break;case'>':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=24;token[m++]=ch;}else{syn=20;p--;}break;case':':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=18;token[m++]=ch;}else{syn=17;p--;}break;case'*':syn=13;token[0]=ch;break;case'/':syn=14;token[0]=ch;break;case'+':syn=15;token[0]=ch;break;case'-':syn=16;token[0]=ch;break;case'=':syn=25;token[0]=ch;break;case';':syn=26;token[0]=ch;break;case'(':syn=27;token[0]=ch;break;case')':syn=28;token[0]=ch;break;case'#':syn=0;token[0]=ch;break;case'\n':syn=-2;break;default: syn=-1;break;}}void main(){p=0;row=1;cout<<"Please input string:"<<endl;do{cin.get(ch);prog[p++]=ch;}while(ch!='#');p=0;do{scaner();switch(syn){case 11: cout<<"("<<syn<<","<<sum<<")"<<endl; break;case -1: cout<<"Error in row "<<row<<"!"<<endl; break;case -2: row=row++;break;default: cout<<"("<<syn<<","<<token<<")"<<endl;break;}}while (syn!=0);}(2)创建编辑程序(3)连接、编译和调试程序(4)运行程序五、实验过程原始记录( 测试数据、图表、计算等)(1)给定源程序begin x:=8; if x>0 then x:=2*x+1/5; end#输出结果(2)源程序(包括上式未有的while、do以及判断错误语句):beginx<=$;whilea<0dob<>9-x;end#六、实验结果、分析和结论(误差分析与数据处理、成果总结等。
编译原理报告—词法分析器
词法分析器的作用词法分析是编译的第一阶段。
词法分析器的主要任务是读入源程序的输入字符,将它们组成词素,生成并输出一个词法单元序列,这个词法单元序列被输出到语法分析器进行语法分析。
另外,由于词法分析器在编译器中负责读取源程序,因此除了识别词素之外,它还会完成一些其他任务,比如过滤掉源程序中的注释和空白,将编译器生成的错误消息与源程序的位置关联起来等。
总而言之,词法分析器的作用如下:1.读入源程序的输入字符,将它们组成词素,生成并输出一个词法单元序列;2.过滤掉源程序中的注释和空白;3.将编译器生成的错误消息与源程序的位置关联起来;4.其它。
词法分析过程首先,对某个正则语言L,构造能够描述其的正则表达式r;然后,需要将r 转换成一个有穷自动机。
这里有三种方法,一是直接转换成NFA,而是直接转换成DFA,三是先转换成NFA,再把NFA 转换成DFA;最后,如果将r 转换成了一个DFA,需要将此DFA 的状态数最小化。
正则表达式正则表达式可以用来描述词素的模式,一个正则表达式可以由较小的正则表达式递归的构建。
对于符号集合∑={a,b},有:-正则表达式a 表示语言{a};-正则表达式a|b 表示语言{a,b};-正则表达式(a|b)(a|b)表示语言{aa,ab,ba,bb};-正则表达式a*表示语言{ε,a,aa,aaa,…};-正则表达式(a|b)*表示语言{ε,a,b,aa,ab,ba,bb,aaa,…};-正则表达式a|a*b 表示语言{a,b,ab,aab,aaab,…}。
上面通过基本的并、连接和闭包运算递归定义了正则表达式有穷自动机一个有穷自动机可以把一个描述词素的模式变成一个词法分析器,从本质上来讲,有穷自动机是与状态转换图相类似的图,它有以下特点:有穷自动机是一个识别器,它只能对每个输入符号串简单的输出“yes”或“no”,表示是否能够识别此符号串;有穷自动机和状态转换图类似,它具有有限个数的结点,每个结点表示一个状态,并且这些状态中有一个初始状态和若干个终止状态。
编译原理词法分析器实验报告
一、实验目的设计一个简单的词法分析器,从而进一步加深对词法分析器工作原理的明白得。
二、实验要求一、该个词法分析器要求至少能够识别以下几类单词:(1)关键字:else if int return void while共6个,所有的关键字都是保留字,而且必需是小写;(2)标识符:识别与C语言词法规定相一致的标识符,通过以下正那么表达式概念:ID = letter (letter | digit)*;(3)常数:NUM = digit digit*(.digit digit* |ε)(e(+ | - |ε) digit digit* |ε),letter = a|..|z|A|..|Z|,digit = 0|..|9,包括整数,如123等;小数,如123.45等;科学计数法表示的常数,如1.23e3,2.3e-9等;(4)专用符号:+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */;二、分析器的输入为由上述几类单词组成的程序,输出为该段程序的机内表示形式,即关键字、运算符、界限符变成其对应的机内符,常数利用二进制形式,标识符利用相应的标识符表指针表示。
3、词法分析器应当能够指出源程序中的词法错误,如不可识别的符号、错误的词法等。
三、实验环境实验环境为win7系统、vs2005。
四、实验内容1、词法分析程序的功能:输入:所给文法的源程序字符串。
输出:二元组(syn,token)或(sum或fsum,对应二进制)组成的序列。
其中:syn为单词类别码;token为寄存的单词自身字符串;sum为整型常数;fsum为浮点型常数。
二、各类单词符号类别码如下表:五、要紧函数说明一、程序全局变量char inputstr[300],token[8];//别离寄存程序段、组成单词符号的字符串char ch;//输入字符int syn;//单词字符的类别码int p;//缓冲区inputstr的指针int sum;//整型常量float fsum;//浮点型常量char *rwtab[6]={"else","if","int","return","void","while"};//关键字数组二、语法分析函数void scaner()该函数完成所有的语法分析,关于输入的程序片段,第一去掉空格和换行,然后逐字符分析,找出各个单词(存入token[8]),判别它们的类型(确信syn 值,若是是整数那么是sum值,若是是浮点数那么是fsum)。
编译原理的分析器
编译原理的分析器编译原理是计算机科学中的重要学科,研究如何将高级程序语言转化为机器语言,实现程序的编译和执行。
而分析器则是编译过程中的重要组成部分,用于将源程序分析成各种语法成分,为后续的语义分析和代码生成做准备。
本文将对编译原理的分析器进行简要介绍和分析。
一、词法分析器词法分析器是编译原理中的第一步,其主要作用是将源程序分解成一个个记号(Token),为语法分析器提供输入。
词法分析器通过有限自动机(DFA)或正则表达式来实现记号的识别。
在编译原理中,一般会使用词法分析器生成器(如Lex、Flex等工具)来自动生成词法分析器的代码。
二、语法分析器语法分析器是编译原理中的第二步,其主要作用是通过文法规则来分析记号流,判断其是否符合语法规则。
常用的语法分析算法有递归下降法、LL(1)分析法、LR(k)分析法等。
在语法分析过程中,可以根据文法规则构建语法树,用于表示程序的语法结构。
三、语义分析器语义分析器是编译原理中的第三步,其主要作用是对语法分析得到的语法树进行语义分析,包括类型检查、符号表管理和中间代码生成等。
语义分析器会对源程序进行语义上的错误检测,并生成中间表示形式(如三地址码、抽象语法树等),为后续的代码优化和代码生成做准备。
四、符号表管理符号表是编译过程中用于存储程序中的标识符和其属性信息的数据结构。
符号表管理器是编译器中的重要模块,用于管理符号表的创建、插入、查询和删除等操作。
符号表管理器还负责处理作用域和命名冲突等问题,确保符号的正确引用和解析。
五、中间代码生成中间代码是一种介于源代码和目标代码之间的表示形式,用于描述程序的抽象语义。
在编译过程中,中间代码生成器将语法树或其他中间表示形式转换成中间代码,以便于后续的代码优化和代码生成。
常见的中间代码形式包括三地址码、四元式、LLVM IR等。
六、错误处理在编译过程中,错误处理是一个重要的环节。
编译器需要能够检测和报告源程序中的错误,并给出准确的错误信息。
编译原理词法分析器
编译原理词法分析器
编译原理词法分析器是编译器中的一个重要组成部分。
它负责将源代码分解成一个个词素(token)。
在进行词法分析过程中,我们需要定义各种词法规则,例如标识符的命名规则、关键字的集合、运算符的定义以及常量的表示方式等。
词法分析器通常使用有限自动机来实现。
有限自动机是一种能接受或拒绝某个输入序列的计算模型。
在词法分析器中,有限自动机可以方便地根据输入字符的不同状态进行相应的转移,直至得到一个完整的词法单元。
在编写词法分析器时,我们通常会先定义各个词法规则,然后将其转化为正则表达式或有限自动机的形式。
接下来,我们会根据这些规则生成一个词法分析器的状态转换图,并使用该图构建词法分析器的代码。
词法分析器的工作过程如下:输入源代码文本,逐个读取字符并根据当前状态进行状态转移。
如果当前字符能够完成一个词法单元的匹配,那么就将当前词法单元输出,并进入下一个状态。
如果当前字符不能完成一个词法单元的匹配,则继续读取下一个字符,直至完成一个词法单元的匹配或遇到非法字符。
通过词法分析器,我们可以将源代码文本转化为一系列的词法单元,例如关键字、标识符、运算符、常量等。
这些词法单元将作为编译器后续阶段的输入,用于进行语法分析和语义分析。
词法分析器是编译器的重要基础工具之一,它能够帮助我们更好地理解和处理源代码。
编译原理词法分析器
编译原理词法分析器编译原理是计算机科学中的重要领域,而词法分析器则是编译器的第一个阶段。
它的主要任务是将源代码转化为一个个词法单元,以便接下来的语法分析和语义分析等阶段进行处理。
在本文中,我们将深入探讨词法分析器的原理和实现。
一、什么是词法分析器词法分析器(Lexical Analyzer)是编译器中实现词法分析的部分。
它负责从源代码中提取出各个合法的词法单元,并进行分类和标记。
词法单元通常包括关键字、标识符、运算符、分隔符和常量等。
二、词法分析器的原理词法分析器的工作原理可以概括为以下几个步骤:1. 预处理:词法分析器首先会对源代码进行预处理,去除注释、替换宏定义等。
2. 分割:将预处理后的源代码分割成一个个字符。
3. 匹配:根据预定义的词法规则,将字符序列匹配到对应的词法单元上。
4. 标记:对每个词法单元都打上相应的标记,以便后续的语法分析。
三、词法分析器的实现1. 正则表达式:词法分析器通常使用正则表达式定义词法规则,用以匹配词法单元。
例如,使用正则表达式"\d+"可以匹配一个或多个数字。
2. 有限自动机:词法分析器可以通过构造有限自动机来进行词法分析。
有限自动机可以根据当前状态和输入字符进行状态转移,最终得到一个词法单元的序列。
3. 符号表:词法分析器使用符号表来存储已经识别出的标识符和关键字,并为每个标识符分配一个唯一的标识符号。
四、应用举例以C语言为例,假设我们要编写一个词法分析器来分析C源代码。
下面是一个简单的示例代码:```c#include <stdio.h>int main() {int a = 10;printf("Hello, World!\n");return 0;}```我们可以使用词法分析器将其分解为以下词法单元序列:1. 关键字:include、stdio、int、main、return2. 标识符:a3. 运算符:=4. 常量:105. 分隔符:()、{}6. 函数名:printf7. 字符串常量:"Hello, World!\n"通过词法分析器的处理,我们可以将源代码转化为一个个词法单元,为后续的语法分析提供准备。
编译原理课程设计报告——词法分析器
精选课程设计任务书引言 (4)第一章概述 (5)1.1设计内容 (5)1.2设计要求 (5)第二章设计的基本原理 (6)2.1 (6)2.2 (6)第三章程序设计 (7)3.1 总体方案设计 (7)3.2 各模块设计 (8)第四章程序测试 (9)4.1一般测试4.2出错处理测试第五章结论 (10)参考文献 (10)附录程序清单 (11)引言《编译原理》是国内外各高等院校计算机科学技术类专业,特别是计算机软件专业的一门重要专业课程。
该课程系统地向学生介绍编译程序的结构、工作流程及编译程序各组成部分的设计原理和实现技术。
由于该课程理论性和实践性都比较强,内容较为抽象复杂,涉及到大量的软件设计算法,因此,一直是一门比较难学的课程。
为了使学生更好地理解和掌握编译技术的基本概念、基本原理和实现方法,实践环节非常重要,只有通过上机进行程序设计,才能使学生对比较抽象的教学内容产生具体的感性认识,增强学生综合分析问题、解决问题的能力,并对提高学生软件设计水平大有益处。
编译原理涉及词法分析,语法分析,语义分析及优化设计等各方面。
词法分析阶段是编译过程的第一个阶段,是编译的基础。
这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。
词法分析程序实现这个任务。
词法分析程序可以使用 Lex 等工具自动生成。
从左到右逐个字符对构成源程序的字符串进行扫描,依据词法规则,识别出一个一个的标记(token ),把源程序变为等价的标记串序列。
执行词法分析的程序称为词法分析器,也称为扫描器。
词法分析是所有分析优化的基础,涉及的知识较少,如状态转换图等,易于实现。
本次课程设计,我的选题是词法分析, C++ 代码实现。
第一章概述1.1 设计内容对 C 语言的一个子集设计并实现一个简单的词法分析器,掌握利用状态转换图设计词法分析器的基本方法。
1.2设计要求利用该词法分析器完成对源程序字符串的词法分析。
编译原理实验——flex语法实现简单词法分析器
flex提供的2个全局变量:
yytext:刚刚匹配到的字符串 yyleng:刚刚匹配到的字符串的长度
代码段如下(注意:规则行务必没有缩进,且对应的动作必须在同一行开始):
%{ #include <stdio.h> #include <string.h>
%}
ALPHA [a-zA-Z] ID {ALPHA}+[a-zA-Z0-9_]* KEY begin|if|then|while|do|end NUM [\-]?[1-9][0-9]*|0
四、实验结果
1. 用管理员身份打开cmd窗口 2. 进入到该代码文本文件所在的文件夹内 3. 然后输入下面两行命令,完成对代码的编译生成。
flex test.l //此后会生成C文件lex.yy.c gcc lex.yy.c //使用gcc编译成可执行文件 4. 我这里生成的是a.exe文件,在窗口中输入a.exe或a回车,运行该文件 即可输入字符串来验证结果。
2.3 词法分析程序的功能: 输入:所给文法的源程序字符串。 输出:二元组(syn,token或num)构成的序列。 其中:syn为单词种别码; token为存放的单词自身字符串; num为整型常数。 例如:对源程序begin x:=9; if x>9 then x:=2*x+1/3; end #的Pascal源文件,经过词法分析后输出如下序列: (1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)…
printf("(4,%s)",yytext);
else if(yytext[0]=='d')
printf("(5,%s)",yytext);
编译原理 简单样本语言的语法分析器2
昆明理工大学信息工程与自动化学院学生实验报告(2012 —2013 学年第 1 学期)课程名称:编译原理开课实验室:信自楼44 年月日一、实验目的及内容实现下述我们定义的语言语法分析器。
这种语言的程序结构很简单,语法相当于c的函数体,即由一对大括号括起来的语句序列,没有过程或函数。
声明语句、表达式语句及控制语句的写法都与c类似,但规定:一条声明语句只能声明一个整型变量,没有数组;控制语句只是if、for和while三个语句,这三个语句本身也可以包含语句序列;表达式仅局限于布尔表达式和整型算术表达式,布尔表达式由对两个算术表达式的比较组成,该比较使用<,>,<=,>=,= =,!=比较运算符;算术表达式可以包括整型常数、变量以及+,-,*,/这四个运算符。
另外,还可以有复合语句。
用read和write语句实现输入输出。
注释用/*和*/括起来,但注释不能嵌套二、实验原理及基本技术路线图(方框原理图或程序流程图)对给定的程序通过语法分析器弄够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。
而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。
流程图:词法分析器产生下述语言的单词序列这个语言的所有的单词符号,以及它们的种别编码和内部值如下表:对于这个小语言,有几点重要的限制:首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。
所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。
例如,下面的写法是绝对禁止的: IF(5)=x其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。
也就是说,对于关键字不专设对应的转换图。
但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。
当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。
再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。
编译原理实验报告词法分析器语法分析器
头验一一、实验名称:词法分析器的设计二、实验目的:1词法分析器能够识别简单语言的单词符号2 ,识别出并输出简单语言的基本字•标示符.无符号整数•运算符.和界符三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
2、程序流程图(1)主程序验报告(2)扫描子程序3、各种单词符号对应的种别码单词符号种别码助记符内码值while 1 while -if 2 if -else 3 else -switch 4 switch -case 5 case -标识符6 id id在符号表中的位置常数7 num num在常数表中的位置+ 8 + -- 9 - -* 10 * -<= 11 relop LE< 11 relop LT== 11 relop EQ= 12 = -J 13J-五、实验内容:1、实验分析编写程序时,先定义几个全局变量a[] 、token[] (均为字符串数组),c,s( char 型),i,j,k (int型),a[]用来存放输入的字符串,token[] 另一个则用来帮助识别单词符号,s 用来表示正在分析的字符。
字符串输入之后,逐个分析输入字符,判断其是否‘#',若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c) 、int letter(char c) 判断其是数字,字符还是算术符, 分别为用以判断数字或字符的情况,算术符的判断可以在switch 语句中进行,还要通过函数int lookup(char token[]) 来判断标识符和保留字。
2 实验词法分析器源程序:#include <stdio.h> #include <math.h> #include <string.h> int i,j,k;char c,s,a[20],token[20]={'0'};int letter(char s){if((s>=97)&&(s<=122)) return(1);else return(0);}int digit(char s){if((s>=48)&&(s<=57)) return(1);else return(0);void get(){s=a[i];i=i+1;}void retract(){i=i-1;}int lookup(char token[20]){ if(strcmp(token,"while")==0) return(1);else if(strcmp(token,"if")==0) return(2);else if(strcmp(token,"else")==0) return(3);else if(strcmp(token,"switch")==0) return(4);else if(strcmp(token,"case")==0) return(5);else return(0);}void main(){printf("please input string :\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!='#');i=1;j=0;get();while(s!='#'){ memset(token,0,20); switch(s){case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'g':case 'h':case 'i':case 'j':case 'k':case 'l':case 'm':case 'n':case 'o':case 'p': case 'q': case 'r':case 's':case 't':case 'u':case 'v':case 'w':case 'x':case 'y':case 'z':while(letter(s)||digit(s)) {token[j]=s;j=j+1;get();}retract();k=lookup(token); if(k==0)printf("(%d,%s)",6,token); else printf("(%d,-)",k); break; case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':while(digit(s)){token[j]=s;j=j+1;get();}retract();printf("%d,%s",7,token); break;case '+':printf("('+',NULL)");break;case '-':printf("('-',null)");break;case '*':printf("('*',null)");break;case '<':get();if(s=='=') printf("(relop,LE)");else{retract();printf("(relop,LT)");}break;case '=':get();if(s=='=')printf("(relop,EQ)");else{retract();printf("('=',null)");}break;case ';':printf("(;,null)");break;case ' ':break; default:printf("!\n");}j=0;get();六:实验结果:实验二一、实验名称:语法分析器的设计二、实验目的:用C语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术。
编译原理名词解释
编译原理名词解释1. 词法分析器(Lexer):也称为扫描器(Scanner),用于将源代码分割成一个个单词(Token)。
2. 语法分析器(Parser):将词法分析器生成的单词序列转换成语法树(Parse Tree)或抽象语法树(Abstract Syntax Tree)。
3. 语法树(Parse Tree):表示源代码的语法结构的树状结构,它由语法分析器根据语法规则生成。
4. 抽象语法树(Abstract Syntax Tree):比语法树更加简化和抽象的树状结构,用于表示源代码的语义结构。
5. 语义分析器(Semantic Analyzer):对抽象语法树进行语义检查,并生成中间代码或目标代码。
6. 中间代码(Intermediate code):一种介于源代码和目标代码之间的中间表示形式,可以被不同的优化器和代码生成器使用。
7. 目标代码生成器(Code Generator):将中间代码转换成特定目标平台的机器代码。
8. 优化器(Optimizer):用于对中间代码进行优化,以提高代码的执行效率和资源利用率。
9. 符号表(Symbol Table):用于存储程序中的标识符(变量、函数等)的信息,包括名称、类型等。
10. 语言文法(Grammar):定义了一种语言的语法规则,常用的形式包括上下文无关文法和正则文法。
11. 上下文无关文法(Context-free Grammar):一种形式化的语法表示方法,由产生式和非终结符组成,描述一种语言的句子结构。
12. 语言解释器(Interpreter):将源代码逐行解释执行的程序,不需要生成目标代码。
13. 回溯法(Backtracking):一种递归式的算法,用于在语法分析过程中根据产生式进行选择。
14. 正则表达式(Regular Expression):用于描述一类字符串的表达式,可以用于词法分析中的模式匹配。
15. 自顶向下分析(Top-down Parsing):从文法的起始符号开始,按照语法规则逐步构建语法树的过程。
编译原理词法分析器实验报告
编译原理词法分析器实验报告1. 引言编译原理是计算机科学中的重要概念,它涉及将高级语言程序转换为计算机可执行的低级指令。
词法分析是编译过程中的第一个阶段,它负责将源代码分解为词法单元,为后续的语法分析做准备。
本实验旨在设计和实现一个基本的词法分析器,以了解词法分析的原理和实际应用。
2. 实验目标本实验的主要目标是实现一个基本的词法分析器,能够识别并提取源代码中的各种词法单元。
具体而言,我们将设计一个针对某种编程语言的词法分析器,能够识别关键字、标识符、算术运算符、括号、常量等。
3. 实验环境为了完成本实验,我们需要使用以下工具和环境:•一种编程语言,例如Python、Java或C++•一个文本编辑器,例如Visual Studio Code或Sublime Text•一个命令行终端4. 实验步骤4.1 定义词法规则首先,我们需要定义词法分析器的词法规则。
这些规则描述了编程语言中各种词法单元的模式。
例如,关键字可以被定义为由特定字符组成的字符串,标识符可以被定义为以字母开头并由字母和数字组成的字符串。
4.2 实现词法分析器接下来,我们将根据定义的词法规则,使用编程语言实现一个词法分析器。
在实现过程中,我们可以使用正则表达式来匹配和提取各种词法单元。
4.3 编写测试用例完成词法分析器的实现后,我们需要编写一些测试用例来验证其正确性。
测试用例应该包含各种可能的输入情况,以确保词法分析器能够正确地识别和提取词法单元。
4.4 运行测试用例最后,我们将使用编写的测试用例来运行词法分析器,并检查输出是否符合预期。
如果测试通过,说明词法分析器能够正常工作;否则,我们需要检查代码并进行调试。
5. 实验结果经过实验,我们成功地设计并实现了一个基本的词法分析器。
该词法分析器能够按照预定义的词法规则,正确地识别和提取源代码中的各种词法单元。
在运行测试用例时,词法分析器能够产生符合预期的输出,表明其具有良好的准确性和可靠性。
编译原理课程设计_词法语法分析器
编译原理课程设计Course Design of Compiling(课程代码3273526)半期题目:词法和语法分析器实验学期:大三第二学期学生班级:2014级软件四班学生学号:2014112218学生姓名:何华均任课教师:丁光耀信息科学与技术学院2017.6课程设计1-C语言词法分析器1.题目C语言词法分析2.内容选一个能正常运行的c语言程序,以该程序出现的字符作为单词符号集,不用处理c语言的所有单词符号。
将解析到的单词符号对应的二元组输出到文件中保存可以将扫描缓冲区与输入缓冲区合成一个缓冲区,一次性输入源程序后就可以进行预处理了3.设计目的掌握词法分析算法,设计、编制并调试一个词法分析程序,加深对词法分析原理的理解4.设计环境(电脑语言环境)语言环境:C语言CPU:i7HQ6700内存:8G5.概要设计(单词符号表,状态转换图)5.1 词法分析器的结构词法分析程序的功能:输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
词法分析程序可以单独为一个程序;也可以作为整个编译程序的一个子程序,当需要一个单词时,就调用此法分析子程序返回一个单词.为便于程序实现,假设每个单词间都有界符或运算符或空格隔开,并引入下面的全局变量及子程序:1) ch 存放最新读进的源程序字符2) strToken 存放构成单词符号的字符串3) Buffer 字符缓冲区4)struct keyType 存放保留字的符号和种别5.3 状态转换图6.详细设计(数据结构,子程序)算法思想:首先设置3个变量:①strToken用来存放构成单词符号的字符串;②ch 用来字符;③struct keyType用来存放单词符号的种别码。
扫描子程序主要部分流程如下图所示。
7.程序清单// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//#include"stdafx.h"#include"stdio.h"#include"stdlib.h"#include"conio.h"#include"string.h"#define N 47char ch;char strToken[20];//存放构成单词符号的字符串char buffer[1024]; //字符缓冲区struct keyType {char keyname[256];int value;}Key[N] = { { "$ID",0 },{ "$INT",1 },{ "auto",2 },{ "break",3 },{ "case",4 }, { "char",5 },{ "const",6 },{ "continue",7 },{ "default",8 },{ "do",9 }, { "double",10 },{ "else",11 },{ "enum",12 },{ "extern",13 },{ "float",14 }, { "for",15 },{ "goto",16 },{ "if",17 },{ "int",18 },{ "long",19 },{ "register",20 }, { "return",21 },{ "short",22 },{ "signed",23 },{ "sizeof",24 },{ "static",25 }, { "struct",26 },{ "switch",27 },{ "typedef",28 },{ "union",29 },{ "unsigned",30 }, { "void",31 },{ "volatile",32 },{ "while",33 },{ "=",34 },{ "+",35 },{ "-",36 },{ "*",37 }, { "/",38 },{ "%",39 },{ ",",40 },{ ";",41 },{ "(",42 },{ ")",43 },{ "?",44 },{ "clear", 45 },{ "#",46 } };void GetChar() //读一个字符到ch中{int i;if (strlen(buffer)>0) {ch = buffer[0];for (i = 0; i<256; i++)buffer[i] = buffer[i + 1];}elsech = '\0';}void GetBC()//读一个非空白字符到ch中{int i;while (strlen(buffer)) {i = 0;ch = buffer[i];for (; i<256; i++) buffer[i] = buffer[i + 1];if (ch != ' '&&ch != '\n'&&ch != '\0') break;}}void ConCat()//把ch连接到strToken之后{char temp[2];temp[0] = ch;temp[1] = '\0';strcat(strToken, temp);}bool Letter()//判断ch是否为字母{if (ch >= 'A'&&ch <= 'Z' || ch >= 'a'&&ch <= 'z')return true;elsereturn false;}bool Digit()//判断ch是否为数字{if (ch >= '0'&&ch <= '9')return true;elsereturn false;}int Reserve()//用strToken中的字符查找保留字表,并返回保留字种别码,若返回0,则非保留字{int i;for (i = 0; i<N; i++)if (strcmp(strToken, Key[i].keyname) == 0)return Key[i].value;return 0;}void Retract()//把ch中的字符回送到缓冲区{int i;if (ch != '\0') {buffer[256] = '\0';for (i = 255; i>0; i--)buffer[i] = buffer[i - 1];buffer[0] = ch;}ch = '\0';}keyType ReturnWord(){strcpy(strToken, "\0");int c;keyType tempkey;GetBC();if (ch >= 'A'&&ch <= 'Z' || ch >= 'a'&&ch <= 'z') { ConCat();GetChar();while (Letter() || Digit()) {ConCat();GetChar();}Retract();c = Reserve();strcpy(tempkey.keyname, strToken);if (c == 0)tempkey.value = 0;elsetempkey.value = Key[c].value;}else if (ch >= '0'&&ch <= '9') {ConCat();GetChar();while (Digit()) {ConCat();GetChar();}Retract();strcpy(tempkey.keyname, strToken);tempkey.value = 1;}else {ConCat();strcpy(tempkey.keyname, strToken);tempkey.value = Reserve();}return tempkey;}/*主函数*/int main() {//文件操作FILE *fp;if ((fp = fopen("E:\\作业\\编译原理\\Ccode.txt", "r")) == NULL) { printf("cannot open file/n"); exit(1);}while (!feof(fp)) {if (fgets(buffer, 250, fp) != NULL){printf("E:\\作业\\编译原理\\Ccode.txt\n");}}keyType temp;printf("单词\t种别号\n");while (strlen(buffer)) {temp = ReturnWord();printf("%s\t %d\n\n", temp.keyname, temp.value);}printf("the end!\n");getch();return 0;}8.运行结果E:/作业/编译原理/Code.txt运行结果九、 实验体会通过本次次法分析设计实验,我加深了对词法分析过程的理解。
编译原理实验-词法分析器
编译原理实验-词法分析器⼀、实验⽬的设计、编制、调试⼀个词法分析程序,对单词进⾏识别和编码,加深对词法分析原理的理解。
⼆、实验内容1.选定语⾔,编辑任意的源程序保存在⽂件中;2.对⽂件中的代码预处理,删除制表符、回车符、换⾏符、注释、多余的空格并将预处理后的代码保存在⽂件中;3.扫描处理后的源程序,分离各个单词符号,显⽰分离的单词类型。
三、实验思路对于实验内容1,选择编写c语⾔的源程序存放在code.txt中,设计⼀个c语⾔的词法分析器,主要包含三部分,⼀部分是预处理函数,第⼆部分是扫描判断单词类型的函数,第三部分是主函数,调⽤其它函数;对于实验内容2,主要实现在预处理函数processor()中,使⽤⽂档操作函数打开源程序⽂件(code.txt),去除两种类型(“//”,“/*…*/”)的注释、多余的空格合并为⼀个、换⾏符、回车符等,然后将处理后的保存在另⼀个新的⽂件(afterdel.txt)中,最后关闭⽂档。
对于实验内容3,打开处理后的⽂件,然后调⽤扫描函数,从⽂件⾥读取⼀个单词调⽤判断单词类型的函数与之前建⽴的符号表进⾏对⽐判断,最后格式化输出。
四、编码设计代码参考了两篇博主的,做了部分改动,添加了预处理函数等1 #include<iostream>2 #include<fstream>3 #include<cstdio>4 #include<cstring>5 #include<string>6 #include<cstdlib>78using namespace std;910int aa;// fseek的时候⽤来接着的11string word="";12string reserved_word[20];//保留13char buffer;//每次读进来的⼀个字符14int num=0;//每个单词中当前字符的位置15int line=1; //⾏数16int row=1; //列数,就是每⾏的第⼏个17bool flag; //⽂件是否结束了18int flag2;//单词的类型192021//预处理函数22int processor(){//预处理函数23 FILE *p;24int falg = 0,len,i=0,j=0;25char str[1000],str1[1000],c;26if((p=fopen("code.txt","rt"))==NULL){27 printf("⽆法打开要编译的源程序");28return0;29 }30else{31//fgets(str,1000,p);32while((c=getc(p))!=EOF){33 str[i++] = c;34 }35 fclose(p);36 str[i] = '\0';37for(i=0;i<strlen(str);i++){38if(str[i]=='/'&&str[i+1]=='/'){39while(str[i++]!='\n'){}40 }//单⾏注释41else if(str[i]=='/'&&str[i+1]=='*'){42while(!(str[i]=='*'&&str[i+1]=='/')){i++;}43 i+=2;44 }//多⾏注释45else if(str[i]==''&&str[i+1]==''){46while(str[i]==''){i++;}47 i--;48if(str1[j-1]!='')49 str1[j++]='';50 }//多个空格,去除空格51else if(str[i]=='\n') {52if(str1[j-1]!='')53 str1[j++]='';54 }//换⾏处理,55else if(str[i]==9){56while(str[i]==9){57 i++;58 }59if(str1[j-1]!='')60 str1[j++]='';61 i--;62 }//tab键处理63else str1[j++] = str[i];//其他字符处理64 }65 str1[j] = '\0';66if((p = fopen("afterdel.txt","w"))==NULL){ 67 printf("can not find it!");68return0;69 }70else{71if(fputs(str1,p)!=0){72 printf("预处理失败!");73 }74else printf("预处理成功!");75 }76 fclose(p);77 }78return0;79 }8081//设置保留字82void set_reserve()83 {84 reserved_word[1]="return";85 reserved_word[2]="def";86 reserved_word[3]="if";87 reserved_word[4]="else";88 reserved_word[5]="while";89 reserved_word[6]="return";90 reserved_word[7]="char";91 reserved_word[8]="for";92 reserved_word[9]="and";93 reserved_word[10]="or";94 reserved_word[11]="int";95 reserved_word[12]="bool";96 }9798//看这个字是不是字母99bool judge_word(char x)100 {101if(x>='a' && x<='z' || x>='A' && x<='Z' ){ 102return true;103 }104else return false;105 }106107//看这个字是不是数字108bool judge_number(char x)109 {110if(x>='0' && x<='9'){111return true;112 }113else return false;114 }115116//看这个字符是不是界符117bool judge_jiefu(char x)118 {119if(x=='('||x==')'||x==','||x==';'||x=='{'||x=='}'){ 120return true;121 }122else return false;123 }124125126//加减乘127bool judge_yunsuanfu1(char x)128 {129if(x=='+'||x=='-'||x=='*')130 {131return true;132 }133else return false;134 }135136//等于赋值,⼤于⼩于⼤于等于,⼩于等于,⼤于⼩于137bool judge_yunsuannfu2(char x)138 {139if(x=='='|| x=='>'||x=='<'||x=='&'||x=='||'){140return true;141 }142else return false;143 }144145146//这个最⼤的函数的总体作⽤是从⽂件⾥读⼀个单词147int scan(FILE *fp)148 {149 buffer=fgetc(fp);//读取⼀个字符150if(feof(fp)){//检测结束符151 flag=0;return0;152 }153else if(buffer=='')154 {155 row++;156return0;157 }158else if(buffer=='\n')159 {160 row=1;161return0;162 }163//如果是字母开头或'_' 看关键字还是普通单词164else if(judge_word(buffer) || buffer=='_')165 {166 word+=buffer;167 row++;168while((buffer=fgetc(fp)) && (judge_word(buffer) || judge_number(buffer) || buffer=='_'))169 {170 word+=buffer;171 row++;172 }173if(feof(fp)){174 flag=0;175return1;176 }177for(int i=1;i<=12;i++){178if(word==reserved_word[i]){179 aa=fseek(fp,-1,SEEK_CUR);//如果执⾏成功,stream将指向以fromwhere为基准,偏移offset(指针偏移量)个字节的位置,函数返回0。
编译原理词法分析器
编译原理词法分析器
编译原理词法分析器是编译器的一个重要组成部分,负责将输入的源代码转换成一系列的词法单元,供后续的语法分析器进行进一步处理。
词法分析器的主要任务是按照预先定义的词法规则,识别出源代码中的各个合法的词法单元,并将其转化为内部表示形式。
在这个过程中,词法分析器需要读取输入字符流,并根据定义的词法规则进行模式匹配和转换。
一个基本的词法分析器通常由以下几个部分组成:
1. 字符扫描器(Scanner):负责从输入流中读取字符,并进行必要的预处理。
例如,过滤掉注释、空白字符等。
2. 词法规则(Lexical Rules):是定义词法单元的正则表达式或者有限自动机。
每个词法单元都有一个对应的识别规则。
3. 标记生成器(Token Generator):根据词法规则和字符扫描器的输出,生成符合内部表示形式的词法单元。
4. 符号表(Symbol Table):维护着程序中出现的所有标识符的符号表,包括标识符的名称和属性信息。
词法分析器的工作流程如下:
1. 初始化字符扫描器,读取第一个字符。
2. 逐个字符进行扫描和匹配,直到获取了一个完整的词法单元。
3. 根据匹配到的词法规则,生成对应的词法单元。
4. 如果需要记录标识符信息,将其添加到符号表中。
5. 返回步骤2,直到扫描完整个输入代码。
通过词法分析器的工作,我们能够将输入的源代码按照词法规则进行分割,将其转换为一系列的词法单元,为后续的语法分析器提供了处理的基础。
计算机编译原理---词法分析器实验报告
编译原理实验报告书词法分析器目录1、摘要: (2)2、实验目的: (2)3、任务概述 (3)4、实验依据的原理 (3)5、程序设计思想 (5)6、实验结果分析 (7)7、总结 (9)1、摘要:本实验用C/C++高级语言编写词法分析程序,通过课堂上对词法分析器相关的背景知识的足够了解,清晰词法分析的过程,在脑海中形成词法分析的一般方案,根据方案一步步所要实现的目的,形成对词法分析器程序的模块划分和整体规划,最终实现一个词法分析器。
具体要求能够通过扫描源程序分析出单词符号,将相应字符流转换成内码。
2、实验目的:通过设计、调试词法分析程序,实现从源程序中分出各种单词的方法;熟悉词法分析程序所用的工具自动机,进一步理解自动机理论。
掌握文法转换成自动机的技术及有穷自动机实现的方法。
确定词法分析器的输出形式及标识符与关键字的区分方法。
加深对课堂教学的理解;提高词法分析方法的时间能力。
通过本实验,掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法以及掌握词法分析的实现方法,并可以成功的上机调试编出词法分析程序。
3、任务概述用C/C++实现对Pascal的子集程序设计语言的词法识别程序。
词法分析程序的主要工作为:(1)从源程序文件中读入字符。
(2)统计行数和列数用于错误单词的定位。
(3)删除空格类字符,包括回车、制表符空格。
(4)按拼写单词,并用(内码,属性)二元式表示。
(5)根据需要是否填写标识符表供以后各阶段使用。
4、实验依据的原理(1)词法分析器工作流程图图1 词法分析器工作流程图实现流程:从左至右逐个字符地对源程序进行扫描,产生一个个的单词符号,把作为字符串的源程序改造成为单词符号串的中间程序。
词法分析的功能是输入源程序,输出单词符号。
所依据的理论基础有有限自动机、正规式、正规文法。
(2)词法分析器的功能是输入源程序,输出单词符号,单词符号是一个程序语言的基本语法符号,一般分为五种:关键字、标识符、常数、运算符、界符五大类。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
昆明理工大学信息工程与自动化学院学生实验报告(2012 —2013 学年第 1 学期)课程名称:编译原理开课实验室:信自楼44 年月日一、实验目的及内容设计、编制、调试一个词法分析子程序-识别单词,加深对词法分析原理的理解。
二、实验原理及基本技术路线图(方框原理图或程序流程图)对给定的程序通过词法分析器弄够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。
而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。
三、所用仪器、材料(设备名称、型号、规格等或使用软件)W INDOWS下的VISUAL C++6.0;四、实验方法、步骤(或:程序代码或操作过程)#include <iostream>#include<string>using namespace std;#define MAX 22char ch =' ';string key[15]={"begin","end","if","then","else","while","write","read", "do", "call","const","char","until","procedure","repeat"};int Iskey(string c){ //关键字判断int i;for(i=0;i<MAX;i++) {if(key[i].compare(c)==0) return 1;}return 0;}int IsLetter(char c) { //判断是否为字母if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))) return 1;else return 0;}int IsDigit(char c){ //判断是否为数字if(c>='0'&&c<='9') return 1;else return 0;}void analyse(FILE *fpin){string arr="";while((ch=fgetc(fpin))!=EOF) {arr="";if(ch==' '||ch=='\t'||ch=='\n'){}else if(IsLetter(ch)){while(IsLetter(ch)||IsDigit(ch)) {if((ch<='Z')&&(ch>='A')) ch=ch+32;arr=arr+ch;ch=fgetc(fpin);}fseek(fpin,-1L,SEEK_CUR);if (Iskey(arr)){cout<<arr<<"\t$关键字"<<endl;}else cout<<arr<<"\t$普通标识符"<<endl;}else if(IsDigit(ch)){while(IsDigit(ch)||ch=='.'&&IsDigit(fgetc(fpin))){arr=arr+ch;ch=fgetc(fpin);}fseek(fpin,-1L,SEEK_CUR);cout<<arr<<"\t$无符号实数"<<endl;}else switch(ch){case'+':case'-' :case'*' :case'=' :case'/' :cout<<ch<<"\t$运算符"<<endl;break;case'(' :case')' :case'[' :case']' :case';' :case'.' :case',' :case'{' :case'}' :cout<<ch<<"\t$界符"<<endl;break;case':' :{ch=fgetc(fpin);if(ch=='=') cout<<":="<<"\t$运算符"<<endl;else {cout<<"="<<"\t$运算符"<<endl;;fseek(fpin,-1L,SEEK_CUR);}}break;case'>' :{ch=fgetc(fpin);if(ch=='=') cout<<">="<<"\t$运算符"<<endl;if(ch=='>')cout<<">>"<<"\t$输入控制符"<<endl;else {cout<<">"<<"\t$运算符"<<endl;fseek(fpin,-1L,SEEK_CUR);}}break;case'<' :{ch=fgetc(fpin);if(ch=='=')cout<<"<="<<"\t$运算符"<<endl;else if(ch=='<')cout<<"<<"<<"\t$输出控制符"<<endl;else if(ch=='>') cout<<"<>"<<"\t$运算符"<<endl;else{cout<<"<"<<"\t$运算符"<<endl;fseek(fpin,-1L,SEEK_CUR);}}break;default : cout<<ch<<"\t$无法识别字符"<<endl;}}}void main(){char in_fn[30];FILE * fpin;cout<<"请输入源文件名(包括路径和后缀名):";for(;;){cin>>in_fn;if((fpin=fopen(in_fn,"r"))!=NULL) break;else cout<<"文件路径错误!请输入源文件名(包括路径和后缀名):"; }cout<<"\n********************分析如下*********************"<<endl; analyse(fpin);fclose(fpin);}五、实验过程原始记录( 测试数据、图表、计算等)源程序为:# include<stdio.h>int main(){double r,s,h,v;printf("r,h=?");scanf("%lf,%lf",&r,&h);s=3.1415926*r*r;v=s*h;printf("r=%.2f,s=%.2f,h=%.2f,v=%.2f\n\n",r,s,h,v);return 0;}六、实验结果、分析和结论(误差分析与数据处理、成果总结等。
其中,绘制曲线图时必须用计算纸或程序运行结果、改进、收获)词法分析器主要特点是不依靠语法,而只依靠词法,即处理一个单词时不依赖于外部单词的信息,因此词法分析器一般都很简单。
语法分析时,调用词法分析器,根据已知文法利用递归向下分析,检查语法错误。
在分析时,一是把词法分析器当成语法分析的一部分,另一种是把词法分析器当成编译程序的独立部分。
在前一种情况下,词法分析器不断地被语法分析器调用,每调用一次词法分析器将从源程序的字符序列拼出一个单词,并将其Token值返回给语法分析器。
后一种情况则不同,词法分析器不是被语法分析器不断地调用,而是一次扫描全部单词完成编译器的独立一遍任务。
这次实验刚开始我的时候我是对照课本先把代码输入,编译的时候只有很少的错误,很快我就把错误修改正确,在连接的时候,有错误,我还没讲要分析的文件名写入,写入后运行正确。
这从实验学到了很多知识,对词法分析器有了很多了解。
注:教师必须按照上述各项内容严格要求,认真批改和评定学生成绩。