编译原理实验1
编译原理 实验1 有穷自动机的构造与实现
}
char digitprocess(char buffer, FILE* fp)
{
int i=-1;
while((IsDigit(buffer)))
{
digittp[++i]=buffer;
buffer=fgetc(fp);
}
digittp[i+1]=\0';
return(buffer);
buffer=fgetc(fp);
}
alphatp[i+1]='\0';
return(buffer);
}
int main(int argc, char* argv[])
{
FILE *fp;//文件指针,指向要分析的源程序
char cbuffer;//保存最新读入的字符
if((fp=fopen(sourceFile,"r"))==NULL)//判断源文件是否存在
}
int main(int argc, char* argv[])
{
FILE *fp;//文件指针,指向要分析的源程序
char cbuffer;//保存最新读入的字符
if((fp=fopen(sourceFile,"r"))==NULL)//判断源文件是否存在
printf("文件%s不存在", sourceFile);
(2)无符号整型数,要求长度不超过20。
四、实验结果
1.识别标识符(以字母开始由字母和数字构成的字符串,要求长度不超过10)。
#include <stdio.h>
#include <string.h>
编译原理上机实验
实验1简单的词法分析子程序【实验目的】●理解词法分析在编译程序中的作用●初步了解和掌握词法分析程序的实现方法和技术【实验内容】1. 编写程序,输入一串字符,判断该字符串是否为合法标识符或合法整型常量。
2. 无符号数的算术四则运算中的各类单词的识别。
输入:由无符号数、+、-、*、/、(、)构成的算术表达式。
输出:对识别出的每一单词均单行输出。
如,输入:8*2.5-1.0e2则,输出:8*2.5-1.0e2描述无符号数的确定的、最小化的状态转换图如图1所示。
其中编号1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。
图1 文法G[<无符号数>]的状态转换图实验2词法分析程序设计【实验目的】●理解词法分析中的正规式和自动机●掌握词法分析程序的实现方法和技术【实验内容】某一高级程序设计语言的部分语言子集定义如下:(1)关键字:for if then else while do(所有关键字都是小写)(2)运算符和分隔符:+ - * / : = <><= <>>= == ; ( ) #(3)其他标识符(ID)和整型常数(NUM),通过以下正规式定义:ID=letter(letter|digit)*NUM=digit·digit*(4)空格由空白、制表符和换行符组成。
空格一般用来分隔ID、NUM、运算符、分隔符和关键字,词法分析阶段通常被忽略。
各种词法单元对应的词法记号如下:编写程序,实现词法分析功能。
输入:源程序输出:二元组(词法记号,属性值/其在符号表中的位置)构成的序列。
例如:输入源程序x=5;if (x>0)thenx=2*x+1/3;elsex=2/x;#(# 表示输入结束)经词法分析后输出如下序列:(10,x)(18,=)(11,5)(26,;)(2,if)(27,()…说明:关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符,查关键字表。
编译原理实验指导书
编译原理实验指导书计算机学院实验1 词法分析程序一、实验目的构造simple语言的词法分析程序,程序要求能对输入的字符串流进行词法分析。
在实验的过程中,学会应用单词分析的方法——NFA(非确定有穷自动机)和DFA(确定有穷自动机),加深对词法分析原理的理解。
二、实验内容编写为任一正则文法(见实验参考(一)simple惯用的词法)构造非确定有穷自动机NFA并转换成确定有穷自动机DFA,并对任给的一个输入串(见实验参考(二)测试用输入串)进行词法分析的程序,程序的输出为单词的序列(见实验参考(三)程序输出形式)。
三、实验参考(一)simple 惯用的词法1. 下面是语言的关键字:Begin if then while do end所有的关键字都是保留字,并且必须是小写。
2. 下面是专用符号::= + * / < <= <> > >= = ; ( ) #3. 其他单词是标识符(ID)和整型常数(NUM),通过下列正规式定义:ID = letter(letter| digit)*NUM = digit digit*letter = a |…| z | A |…| Zdigit = 0 |…| 9小写和大写字母是有区别的。
思考:构造实数的正规表达式,力争实现对实数的识别及表示。
4. 空格由空白、换行符和制表符组成。
空格一般用来分隔ID、NUM、运算符和关键字,词法分析阶段通常被忽略。
5. 各种单词符号对应的种别码如下表所示:(二)词法分析程序的功能1. 输入为所给文法的源程序字符串。
2. 程序的输出形式为单词串的输出形式。
所输出的每一单词,均按形如(syn,token和sum)的二元式编码。
其中,syn 为单词种别码;token为存放的单词自身字符串;sum为整型常数。
3.测试源程序片断:begin x:=9; if x>0 then x:=2*x+1/3;end #。
编译原理-实验1
实验1《词法分析程序设计与实现》实验学时: 2 实验地点:实验日期:一、实验目的加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。
二、实验内容自定义一种程序设计语言,或者选择已有的一种高级语言,编制它的词法分析程序。
词法分析程序的实现可以采用任何一种编程语言和编程工具。
从输入的源程序中,识别出各个具有独立意义的单词,即关键字、标识符、常数、运算符、界符。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)三、实验方法算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
主程序初始包括以下两个方面:⑴关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,};图3-1(2)程序中需要用到的主要变量为syn,token和sum扫描子程序的算法思想:首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。
四、实验步骤1.定义目标语言的可用符号表和构词规则;2.依次读入源程序符号,对源程序进行单词切分和识别,直到源程序结束;3.对正确的单词,按照它的种别以<种别码,值>的形式保存在符号表中;4.对不正确的单词,做出错误处理。
五、实验结果输入begin x:=9: if x>9 then x:=2*x+1/3; end #显示结果如下:六、实验结论该词法分析器可以进行输入、预处理;关键字的识别;标识符的识别、常数的识别、算符和界符的识别等。
编译原理—实验指导书-1
4.词法分析器的功能和输出格式
词法分析器的功能是输入以字符串表示的源程序,从左向右扫描每行源程序的符号,拼成单词,换成统一的二元式(单词种别码,单词符号的属性值)表示。对给定的程序通过词法分析器识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示,本程序是通过对给定路径的文件的分析后以单词符号和文字提示显示),本实验中,采用单词种别码是一符一种种别码的方式。
(4)var
(5)a,b,c:integer;
(6)x:char;
(7)begin
(8)if(a+c*3>b)and(b>3)thenc:=3;
(9)x:=2+(3*a)-b*c*8;
(10)forx:=1+2to3dob:=100;
(11)whilea>bdoc:=5;
(12)repeata:=10;untila>b;
(124){
(125)printf("%s\t$运算符\n\n",Word);
(126)}
(127)else if(ch=='-')
(128){
(129)printf("%s\t$运算符\n\n",Word); //判断结果为“--”
(2)设计描述Sample语言各类单词结构的状态转换图(即有限自动机FA);
如标识符的状态转换图可以用下图表示
其相应代码科为
(1)recog_id(char ch)
(2){
(3)char state='0';
(4)while(state!='2')
(5){
(6)switch(state)
《编译原理(实验部分)》实验1_程序预处理
《编译原理》(实验部分)实验1_程序预处理一、实验目的明确预处理子程序的任务,构造一个简单的预处理子程序,对源程序进行相应的预处理。
二、实验设备1、PC 兼容机一台;操作系统为WindowsWindowsXP。
2、Visual C++ 6.0 或以上版本, Windows 2000 或以上版本,汇编工具(在Software 子目录下)。
三、实验原理定义模拟的简单语言的词法构成,编制读入源程序和进行预处理的程序,要求将源程序读入到文件或存入数组中,再从文件或数组中逐个读取字符进行预处理,包括去掉注释、Tab、Enter和续行符等操作,并显示预处理后的程序。
四、实验步骤1、从键盘读入源程序存放到输入缓冲区中。
2、对源程序进行预处理,预处理后的程序存放到扫描缓冲区中。
3、显示预处理后的程序。
参考源程序(C++语言编写)//源程序的输入及预处理#include <fstream.h>#include <iostream.h>void pro_process(char *);void main( ) //测试驱动程序{//定义扫描缓冲区char buf[4048]={'\0'}; //缓冲区清0//调用预处理程序pro_process(buf); //在屏幕上显示扫描缓冲区的内容cout<<buf<<endl;}void pro_process(char *buf) //预处理程序{ifstream cinf("source.txt",ios::in);int i=0; //计数器char old_c='\0',cur_c; //前一个字符,当前字符。
bool in_comment=false; //false表示当前字符未处于注释中。
while(cinf.read(&cur_c,sizeof(char))){ //从文件读一个字符switch(in_comment){case false:if(old_c=='/' && cur_c=='*'){ //进入注释i--; //去除已存入扫描缓冲区的字符'/'in_comment=true;}else {if(old_c=='\\' && cur_c=='\n') //发现续行i--; //去除已存入扫描缓冲区的字符'\'else {if(cur_c>='A' && cur_c<='Z') //大写变小写cur_c+=32;if(cur_c =='\t' || cur_c =='\n')//空格取代TAB换行cur_c=' ';buf[i++]=cur_c ;}}break;case true:if(old_c=='*' && cur_c=='/') //离开注释in_comment=false;}//end of switchold_c= cur_c; //保留前一个字符}//end of whilebuf[i++]='#'; //在源程序尾部添加字符'#' }。
编译原理实验报告——词法分析器(内含源代码)
编译原理实验(一)——词法分析器一.实验描述运行环境:vc++2008对某特定语言A ,构造其词法规则。
该语言的单词符号包括:12状态转换图3程序流程:词法分析作成一个子程序,由另一个主程序调用,每次调用返回一个单词对应的二元组,输出标识符表、常数表由主程序来完成。
二.实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。
同时增强编写和调试程序的能力。
三.实验任务编制程序实现要求的功能,并能完成对测试样例程序的分析。
四.实验原理char set[1000],str[500],strtaken[20];//set[]存储代码,strtaken[]存储当前字符char sign[50][10],constant[50][10];//存储标识符和常量定义了一个Analyzer类class Analyzer{public:Analyzer(); //构造函数 ~Analyzer(); //析构函数int IsLetter(char ch); //判断是否是字母,是则返回 1,否则返回 0。
int IsDigit(char ch); //判断是否为数字,是则返回 1,否则返回 0。
void GetChar(char *ch); //将下一个输入字符读到ch中。
void GetBC(char *ch); //检查ch中的字符是否为空白,若是,则调用GetChar直至ch进入一个非空白字符。
void Concat(char *strTaken, char *ch); //将ch中的字符连接到strToken之后。
int Reserve(char *strTaken); //对strTaken中的字符串查找保留字表,若是一个保留字返回它的数码,否则返回0。
void Retract(char *ch) ; //将搜索指针器回调一个字符位置,将ch置为空白字符。
计算机编译原理实验报告
编译原理实验报告实验一词法分析设计一、实验功能:1、对输入的txt文件内的内容进行词法分析:2、由文件流输入test.txt中的内容,对文件中的各类字符进行词法分析3、打印出分析后的结果;二、程序结构描述:(源代码见附录)1、分别利用k[],s1[],s2[],s3[]构造关键字表,分界符表,算术运算符表和关系运算符表。
2、bool isletter(){} 用来判断其是否为字母,是则返回true,否则返回false;bool isdigit(){} 用来判断其是否为数字,是则返回true,否则返回false;bool iscalcu(){} 用来判断是否为算术运算符,是则返回true,否则返回false;bool reserve(string a[]){} 用来判断某字符是否在上述四个表中,是则返回true,否则返回false;void concat(){} 用来连接字符串;void getn(){} 用来读取字符;void getb(){} 用来对空格进行处理;void retract(){}某些必要的退格处理;int analysis(){} 对一个单词的单词种别进行具体判断;在主函数中用switch决定输出。
三、实验结果四、实验总结词法分析器一眼看上去很复杂,但深入的去做就会发现并没有一开始想象的那么困难。
对于一个字符的种别和类型可以用bool函数来判断,对于关键字和标示符的识别(尤其是3b)则费了一番功夫,最后对于常数的小数点问题处理更是麻烦。
另外,这个实验要设定好时候退格,否则将会导致字符漏读甚至造成字符重复读取。
我认为,这个实验在程序实现上大体不算困难,但在细节的处理上则需要好好地下功夫去想,否则最后的程序很可能会出现看上去没有问题,但实际上漏洞百出的状况。
将学过的知识应用到实际中并不简单,只有自己不断尝试将知识转化成程序才能避免眼高手低,对于知识的理解也必将更加深刻。
实验二LL(1)分析法一、实验原理:1、写出LL(1)分析法的思想:当一个文法满足LL(1)条件时,我们就可以为它构造一个不带回溯的自上而下的分析程序,这个分析程序是有一组递归过程组成的,每个过程对应文法的一个非终结符。
编译原理实验报告1
编译原理实验报告某某:班级:学号:自评:中实验一词法分析程序实现一、实验目的与要求通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。
二、实验内容根据教学要求并结合学生自己的兴趣和具体情况,从具有代表性的高级程序设计语言的各类典型单词中,选取一个适当大小的子集。
例如,可以完成无符号常数这一类典型单词的识别后,再完成一个尽可能兼顾到各种常数、关键字、标识符和各种运算符的扫描器的设计和实现。
输入:由符合或不符合所规定的单词类别结构的各类单词组成的源程序。
输出:把单词的字符形式的表示翻译成编译器的内部表示,即确定单词串的输出形式。
例如,所输出的每一单词均按形如(CLASS,V ALUE)的二元式编码。
对于变量和常数,CLASS字段为相应的类别码;V ALUE字段则是该标识符、常数的具体值或在其符号表中登记项的序号(要求在变量名表登记项中存放该标识符的字符串;常数表登记项中则存放该常数的二进制形式)。
对于关键字和运算符,采用一词一类的编码形式;由于采用一词一类的编码方式,所以仅需在二元式的CLASS字段上放置相应的单词的类别码,V ALUE字段则为“空”。
另外,为便于查看由词法分析程序所输出的单词串,要求在CLASS字段上放置单词类别的助记符。
三、实现方法与环境词法分析是编译程序的第一个处理阶段,本次试验用手工的方式(C语言)构造词法分析程序。
根据文法和状态转换图直接编写词法分析程序。
四、基本实验题目1)题目1:试用手工编码方式构造识别以下给定单词的某一语言的词法分析程序。
语言中具有的单词包括五个有代表性的关键字begin、end、if、then、else;标识符;整型常数;六种关系运算符;一个赋值符和四个算术运算符。
参考实现方法简述如下。
单词的分类:构造上述语言中的各类单词符号及其分类码表。
表I 语言中的各类单词符号及其分类码表+ 15 PL- 16 MI* 17 MU/ 18 DI处理过程:在一个程序设计语言中,一般都含有若干类单词符号,为此首先为每类单词建立一X状态转换图,然后将这些状态转换图合并成一X统一的状态图,即得到了一个有限自动机,再进行必要的确定化和状态数最小化处理,最后据此构造词法分析程序。
编译原理实验报告1
03091337 李璐 03091339 宗婷婷一、上机题目:实现一个简单语言(CPL)的编译器(解释器)二、功能要求:接收以CPL编写的程序,对其进行词法分析、语法分析、语法制导翻译等,然后能够正确的执行程序。
三、试验目的1.加深编译原理基础知识的理解:词法分析、语法分析、语法制导翻译等2.加深相关基础知识的理解:数据结构、操作系统等3.提高编程能力4.锻炼独立思考和解决问题的能力四、题目说明1.数据类型:整型变量(常量),布尔变量(常量)取值范围{…, -2, -1, 0, 1, 2, …}, {true, false}2、运算表达式:简单的代数运算,布尔运算3、程序语句:赋值表达式,顺序语句,if-else语句,while语句五、环境配置1.安装Parser Generator、Visual C++;2.分别配置Parser Generator、Visual C++;3.使用Parser Generator创建一个工程编写l文件mylexer.l;编译mylexer.l,生成mylexer.h与mylexer.c;4.使用VC++创建Win32 Console Application工程并配置该项目;加入mylexer.h与mylexer.c,编译工程;执行标识符数字识别器;注意:每次修改l文件后,需要重新编译l文件,再重新编译VC工程六、设计思路及过程设计流程:词法分析LEX的此法分析部分主要利用有限状态机进行单词的识别,在分析该部分之前,首先应该对YACC的预定义文法进行解释。
在YACC中用%union扩充了yystype的内容,使其可以处理char型,int型,node型,其中Node即为定义的树形结点,其定义如下:typedef enum { TYPE_CONTENT, TYPE_INDEX, TYPE_OP } NodeEnum;/* 操作符 */typedef struct {int name; /* 操作符名称 */int num; /* 操作元个数 */struct NodeTag * node[1]; /* 操作元地址可扩展 */} OpNode;typedef struct NodeTag {NodeEnum type; /* 树结点类型 *//* Union 必须是最后一个成员 */union {int content; /* 内容 */int index; /* 索引 */OpNode op; /* 操作符对象 */};} Node;extern int Var[26];结点可以是三种类型(CONTENT,INDEX,OP)。
编译原理实验报告
编译方法实验报告实验1:扫描器的设计一、实验目的熟悉并实现一个扫描器(词法分析程序)。
二、实验要求(1) 设计扫描器的有限自动机(识别器);(2) 设计翻译、生成Token的算法(翻译器);(3) 编写代码并上机调试运行通过。
·输入——源程序文件或源程序字符串;·输出——相应的Token序列;关键字表和界符表;符号表和常数表;三、实验步骤流程:初始化;打开用户源程序文件;while (文件未结束){ 读入一行到w[i],i=0;do //处理一行,每次处理一个单词{ 滤空格,直到第一个非空的w[i];i--;s=1; //处理一个单词开始while (s!=0)//拼单词并生成相应Token{act(s); //执行q sif (s>=11 && s<=14)//一个单词处理结束break;i++; //getchar()s=find(s, w[i]);}if (s==0)词法错误;}while (w[i]!=换行符);}关闭用户源程序文件;生成Token文件;输出关键字表;输出Token序列;输出符号表;输出常数表;有限自动机的状态转换图: ed d d+|- -1/+/-+① d ② . ③ d ④ e ⑤ ⑥ d ⑦ d --1/+/-l/d -1/+/--1l ⑧ --1b ⑨ b ⑩ --1--1-其中:d 为数字,l 为字母,b 为界符,-1代表其它符号(如在状态8处遇到了非字母或数字的其它符号,会变换到状态12)。
关键字表和界符表:Program; Begin: End( Var) While, Do:= Repeat+ Until- For* To/ If> Then>= Else==< <=四、 主要数据结构①状态转换矩阵:int aut[10][7]={ 2, 0, 0, 0, 8, 9, 15,2, 3, 5,11, 0, 0, 11,4, 0, 0, 0, 0, 0, 0,4, 0, 5,11, 0, 0, 11,7, 0, 0, 6, 0, 0, 0,7, 0, 0, 0, 0, 0, 0,7, 0, 0,11, 0, 0, 11,8, 0, 0, 0, 8, 0, 12,0, 0, 0, 0, 0, 10, 14,0, 0, 0, 0, 0, 0, 13};12 11 13 14 15②关键字表:char keywords[30][12]={“program”,”begin”,”end”,”var”,”while”,”do”,”repeat”,”until”,”for”,”to”,”if”,”then”,”else”,“;”, ”:”, ”(“, ”)”, ”,”, ”:=”, ”+”, ”-“, ”*”, ”/”,”>”, ”>=”, ”==”, “<”, “<=”};③符号表:char ID[50][12]; //表中存有源程序中的标识符④常数表:float C[20];⑤其它变量:struct token{ int code;int value}; //Token结构struct token tok[100]; //Token数组int s; //当前状态int n,p,m,e,t; //尾数值,指数值,小数位数,指数符号,类型float num; //常数值char w[50]; //源程序缓冲区int i; //源程序指针,当前字符为w[i]char strTOKEN[12]; //当前已经识别出的单词五、实验核心代码int main(int argc, char* argv[]){FILE *fp;int s; //当前状态 *有限自动机中的状态fp=fopen("exa.txt","r");while (!feof(fp)){fgets(w,50,fp);i=0;//*处理一行do{printf("%c ",w[i]); //测试显示每个token的首字母//*处理一个tokenwhile (w[i]==' ') //滤空格i++;if (w[i]>='a' && w[i]<='z') //判定单词类别*是字母(关键字或标识符){ptr=col2; num_map=2;}else if (w[i]>='0' && w[i]<='9') //*是数字(常量的开头){ptr=col1; num_map=4;}else if (strchr(col3[0].str,w[i])==NULL) //*其他字符算为非法字符{printf("非法字符%c\n",w[i]);i++;continue;}else //界符{ptr=col3; num_map=1;}i--; //*向后退一个字符s=1; //开始处理一个单词while (s!=0){act(s);if (s>=11 && s<=14) //*判断是否是终止状态 *是终止状态,则形成一个tokenbreak;i++; //getchar() *读取下一个字符s=find(s,w[i]); //状态转换}if (s==0){strTOKEN[i_str]='\0';printf("词法错误:%s\n",strTOKEN);}}while (w[i]!=10);}printf("关键字表:"); //输出结果for (i=0;i<30;i++)printf("%s ",keywords[i]);printf("\n");printf("Token序列:");for (i=0;i<num_token;i++)printf("(%d,%d)",tok[i].code,tok[i].value);printf("\n");printf("符号表:");for (i=0;i<num_ID;i++)printf("%s ",ID[i]);printf("\n");printf("常数表:");for (i=0;i<num_C;i++)printf("%d ",C[i]);printf("\n");fclose(fp);printf("Hello World!\n");return 0;}//*状态转换后,达到新的状态之后,记录的变化void act(int s){int code;switch (s){case 1:n=0;m=0;p=0;t=0;e=1;num=0;i_str=0;strTOKEN[i_str]='\0'; //其它变量初始化break;case 2:n=10*n+w[i]-48;break;case 3:t=1;break;case 4:n=10*n+w[i]-48; m++;break;case 5:t=1;break;case 6:if (w[i]=='-') e=-1;break;case 7:p=10*p+w[i]-48;break;case 8:strTOKEN[i_str++]=w[i]; //将ch中的符号拼接到strTOKEN的尾部;break;case 9:strTOKEN[i_str++]=w[i]; //将ch中的符号拼接到strTOKEN的尾部;break;case 10:strTOKEN[i_str++]=w[i]; //将ch中的符号拼接到strTOKEN的尾部;break;case 11:num=n*pow(10,e*p-m); //计算常数值tok[i_token].code=2; tok[i_token++].value=InsertConst(num); //生成常数Tokennum_token++;break;case 12:strTOKEN[i_str]='\0';code=Reserve(strTOKEN); //查关键字表if (code){ tok[i_token].code=code; tok[i_token++].value=0; } //生成关键字Token else{ tok[i_token].code=1;tok[i_token++].value=InsertID(strTOKEN); } //生成标识符Token num_token++;break;case 13:strTOKEN[i_str]='\0';code=Reserve(strTOKEN); //查界符表if (code){ tok[i_token].code=code; tok[i_token++].value=0; } //生成界符Token else{strTOKEN[strlen(strTOKEN)-1]='\0'; //单界符i--;code=Reserve(strTOKEN); //查界符表tok[i_token].code=code; tok[i_token++].value=0; //生成界符Token }num_token++;break;case 14:strTOKEN[i_str]='\0';code=Reserve(strTOKEN); //查界符表tok[i_token].code=code; tok[i_token++].value=0; //生成界符Token num_token++;break;}}//*状态转换int find(int s,char ch){int i,col=7;struct map *p;p=ptr;for (i=0;i<num_map;i++)if (strchr((p+i)->str,ch)){col=(p+i)->col;break;}return aut[s][col];}//*向常量表中插入常量int InsertConst(double num){int i;for (i=0;i<num_C;i++)if (num==C[i])return i;C[i]= (int)num;num_C++;return i;}int Reserve(char *str){int i;for (i=0;i<num_key;i++)if (!strcmp(keywords[i],str))return (i+3);return 0;}//*向符号表中插入新的符号int InsertID(char *str){int i;for (i=0;i<num_ID;i++)if (!strcmp(ID[i],str)) //*符号已经存在,则返回地址return i;strcpy(ID[i],str);num_ID++;return i;}六、实验结果实验思考题:1.扫描器的任务是什么?答:词法分析程序又称扫描器,任务有:(1) 识别单词——从用户的源程序中把单词分离出来;(2) 翻译单词——把单词转换成机内表示,便于后续处理。
编译原理实验一1
实验2:语法分析程序班级:计算机1103 姓名:王静 学号:1101308336一、 实验目的与实验1.复习上下文无关文法的基本结构、判断方法;2.理解文法存在左递归、回溯现象的害处及消除方法,掌握FIRST 集、FOLLOW 集的含义、求解方法与用途,掌握LL (1)文法的判断方法及构造技术;3.掌握预测分析法的理论精髓,理解下推自动机的基本概念及运行原理;4.学会基于上下文无关文法构造LL (1)预测表,并使用Visual C++编写LL(1)分析器;5.能利用预测分析法,在给定的文法基础上,分析特定输入串的语法结构, 能判断其是否合法,并能提取大部分中间信息,以备后续分析时使用。
二、 实验仪器与设备1. 微型电子计算机(PC 机)。
2. 配置Windows 2000及以上版本操作系统。
3. 安装Visual C++6.0或Visual C#2003或Delphi6.0等以上版本的 开发环境。
三、实验内容与步骤1.实验内容已知文法G[E]:E →E+T|E-T|TT →T*F|T/F|FF →(E)|I编写该文法的LL(1)语法分析程序,用以识别下面的符号串: #((i+i)*i-i)/i#1 2 0 0 1-90-9 其它 无符号整数 4 5 3 6 7 9 1其他 ( ) + - * #8/2.实验步骤(一)准备工作回答下面问题,并将分析过程与结果写在实验报告册上。
上述文法G[E]存在左递归吗?若存在,首先消除左递归,得到对应的文法G ’[E];构造文法G ’[E]的预测分析表(需要先求FIRST 、FOLLOW 集),并根据定义, 逐步判断该文法是否为LL(1)文法;基于上述分析表,仿照教材,写出符号串#((i+i)*i-i)/i#的详细的分析过程。
2. 状态转换图1 2 0 01-0-9|其它 无符号整数 4 5 3 6 7 8 9 其他 ()+-*/3. 实验步骤1. 判断所给出的转换图能否实现预期目的?若有错误,请加以修正;2. 尝试将状态图转换为正则文法;3. 试写出无符号整数对应的正则表达式;4. 根据上述结果,构造出最简的DFA;5.编写对应的词法分析程序,并识别下述符号串:((23+12)*9-200)/54. 流程图开始接受输入字符串是是否为字符串尾否按位字符判断否是否为有效输入是进入自动机判断结果结束1.源程序FILE *fp;char cbuffer;char*key[8]={"if","else","for","while","do","return","break","contin ue"};char *border[6]={",",";","{","}","(",")"};char *arithmetic[4]={"+","-","*","/"};char *relation[6]={"<","<=","=",">",">=","<>"};char *consts[20]={"0","1","2","3","4","5","6","7","8","9"}; char *label[20];int constnum=0,labelnum=0;int search(char searchchar[],int wordtype){ int i=0;switch (wordtype) {case 1:for (i=0;i<=7;i++){ if (strcmp(key[i],searchchar)==0){return(i+1);}}break;case 2:{for (i=0;i<=5;i++){ if (strcmp(border[i],searchchar)==0) return(i+1);} return(0);}break;case 3:{for (i=0;i<=3;i++){ if (strcmp(arithmetic[i],searchchar)==0) { return(i+1);}}return(0);}break;case 4:{for (i=0;i<=5;i++){ if (strcmp(relation[i],searchchar)==0) {return(i+1);} }return(0);}break;case 5:{for (i=0;i<=constnum;i++){ if (strcmp(consts[i],searchchar)==0){ return(i+1);} }}break;case 6:{for (i=0;i<=labelnum;i++){ if (strcmp(label[i],searchchar)==0){ return(i+1);} }label[i-1]=(char *)malloc(sizeof(searchchar));strcpy(label[i-1],searchchar);labelnum++;return(i);}break;}}char alphaprocess(char buffer)//关键字{ int atype;int i=-1;char alphatp[20];while ((isalpha(buffer))||(isdigit(buffer))){ alphatp[++i]=buffer;buffer=fgetc(fp);}alphatp[i+1]='\0';if (atype=search(alphatp,1))printf("%s \t(1,%d)\n",alphatp,atype-1);//结束else { atype=search(alphatp,6);printf("%s \t(6,%d)\n",alphatp,atype-1);}return(buffer);}char digitprocess(char buffer)//数字{ int i=-1;char digittp[20];int dtype;while ((isdigit(buffer))){ digittp[++i]=buffer;buffer=fgetc(fp);}digittp[i+1]='\0';dtype=search(digittp,5);printf("%s \t(5,%d)\n",digittp,dtype-1);return(buffer);}char otherprocess(char buffer)//其它字符{ int i=-1;char othertp[20];int otype,otypetp;othertp[0]=buffer;othertp[1]='\0';if (otype=search(othertp,3)){ printf("%s \t(3,%d)\n",othertp,otype-1);buffer=fgetc(fp);goto out;}if (otype=search(othertp,4)){ buffer=fgetc(fp);othertp[1]=buffer;othertp[2]='\0';if (otypetp=search(othertp,4)){ printf("%s \t(4,%d)\n",othertp,otypetp-1);goto out;}elseothertp[1]='\0';printf("%s \t(4,%d)\n",othertp,otype-1); goto out;}if (buffer==':'){ buffer=fgetc(fp);if (buffer=='=')printf(":= (2,2)\n");buffer=fgetc(fp);goto out;}else{ if (otype=search(othertp,2)) { printf("%s \t(2,%d)\n",othertp,otype-1); buffer=fgetc(fp);goto out;}}if ((buffer!='\n')&&(buffer!=' '))printf("%c error,not a word\n",buffer); buffer=fgetc(fp);out: return(buffer);}void main(){int i;for (i=0;i<=20;i++){label[i]=NULL;};if ((fp=fopen("message.txt","r"))==NULL)printf("error");else{cbuffer = fgetc(fp);while (cbuffer!=EOF){if (isalpha(cbuffer))cbuffer=alphaprocess(cbuffer);else if (isdigit(cbuffer))cbuffer=digitprocess(cbuffer);elsecbuffer=otherprocess(cbuffer);}printf("over\n");getchar();}}2.运行结果四、实验小结。
《编译原理》实验教学大纲
《编译原理》实验教学大纲一、实验目的和任务编译原理是计算机科学与技术专业的一门重要课程,它主要研究的是将高级语言程序翻译成机器语言程序的方法和技术。
通过本实验课程的学习,旨在使学生掌握编译原理的基本原理和方法,培养学生对编译器结构与构造技术的专门知识和技能,为学生今后进行编译器设计与实现打下基础。
二、实验设备和工具1.计算机和相关硬件设备2. 编程语言的开发环境,如C/C++或Java三、实验内容1.实验一:词法分析器设计与实现a)实验目的:学习词法分析器的原理和设计方法,掌握正则表达式、DFA和NFA的转换方法。
b)实验任务:i.设计并实现一个词法分析器的原型,能够正确地识别出给定的程序中的词法单元。
ii. 使用给定的正则表达式设计并实现识别给定程序中的关键字、标识符、常量等的词法分析器。
2.实验二:语法分析器设计与实现a)实验目的:学习语法分析器的原理和设计方法,掌握上下文无关文法和LR分析表的构造方法。
b)实验任务:i.学习并理解上下文无关文法和LR分析表的构造方法。
ii. 设计并实现一个简单的递归下降语法分析器。
3.实验三:语义分析器设计与实现a)实验目的:学习语义分析器的原理和设计方法,掌握语义动作的定义和处理方法。
b)实验任务:i.学习并理解语义分析器的原理和设计方法。
ii. 设计并实现一个简单的语义分析器,能够对给定的程序进行语义分析和语义动作的处理。
4.实验四:中间代码生成器设计与实现a)实验目的:学习中间代码生成器的原理和设计方法,掌握中间代码的生成和优化方法。
b)实验任务:i.学习并理解中间代码生成器的原理和设计方法。
ii. 设计并实现一个简单的中间代码生成器,能够将给定的程序翻译成中间代码。
5.实验五:目标代码生成器设计与实现a)实验目的:学习目标代码生成器的原理和设计方法,掌握目标代码的生成和优化方法。
b)实验任务:i.学习并理解目标代码生成器的原理和设计方法。
ii. 设计并实现一个简单的目标代码生成器,能够将中间代码翻译成目标代码。
编译原理实验一
编译原理实验一实验1 词法分析程序的设计计科143 王祥真6103114095一、实验目的掌握计算机语言的词法分析程序的开发方法。
二、实验内容编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。
三、实验要求1、根据以下的正规式,编制正规文法,画出状态图;标识符<字母>(<字母>|<数字字符>)*十进制整数0 |(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*如有余力,则进一步分析八进制和十六进制整数,其正规式如下:八进制整数0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)*十六进制整数0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)*运算符和界符+ - * / > < = <= >= ( ) ;{ }关键字main if then else while do int (可根据需要添加)2、根据状态图,设计词法分析函数int scan( ),完成以下功能:1)从文本文件中读入测试源代码,根据状态转换图,分析出一个单词,2)以二元式形式输出单词<单词种类,单词属性>其中单词种类用整数表示:0:标识符1:十进制整数2:八进制整数3:十六进制整数运算符和界符,关键字采用一字一符,不编码其中单词属性表示如下:标识符,整数由于采用一类一符,属性用单词表示运算符和界符,关键字采用一字一符,属性为空3、编写测试程序,反复调用函数scan( ),输出单词种别和属性。
四、实验环境PC微机DOS操作系统或Windows 操作系统Turbo C 程序集成环境或Visual C++ 程序集成环境或Eclipse集成环境五、实验步骤1、根据正规式,画出状态转换图;2、根据状态图,设计词法分析算法;3、采用C或C++或Java语言,设计函数scan( ),实现该算法;4、编制测试程序(主函数main);5、调试程序:读入文本文件program.txt,运行程序得到输出结果result.txt,并检查输出结果是否正确。
编译原理实验教案
一、实验目的与要求1. 实验目的(1) 理解编译原理的基本概念和流程。
(2) 掌握常用的编译方法和技术。
(3) 熟练使用编译器开发工具。
2. 实验要求(1) 熟悉计算机专业基础知识。
(2) 掌握C/C++编程语言。
(3) 了解基本的编译原理。
二、实验环境1. 硬件环境(1) 计算机一台。
(2) 编译器开发工具(如GCC、Clang等)。
2. 软件环境(1) 操作系统(如Windows、Linux等)。
(2) 文本编辑器或集成开发环境(如Visual Studio、Eclipse等)。
三、实验内容1. 实验一:词法分析(1) 实现一个简单的词法分析器,识别出关键字、标识符、常量等。
(2) 分析输入的程序,输出词法分析结果。
2. 实验二:语法分析(1) 实现一个简单的语法分析器,根据给定的语法规则分析输入的程序。
(2) 分析输入的程序,输出语法分析树。
3. 实验三:语义分析(1) 实现一个简单的语义分析器,检查程序中的语义错误。
(2) 分析输入的程序,输出语义分析结果。
4. 实验四:中间代码(1) 实现一个简单的中间代码器,将转换为中间代码表示。
(2) 对输入的程序进行转换,输出中间代码。
5. 实验五:目标代码(1) 实现一个简单的目标代码器,将中间代码转换为目标代码。
(2) 对输入的中间代码进行转换,输出目标代码。
四、实验步骤与方法1. 实验一:词法分析(1) 编写词法分析器的代码。
(2) 测试并调试词法分析器。
2. 实验二:语法分析(1) 编写语法分析器的代码。
(2) 测试并调试语法分析器。
3. 实验三:语义分析(1) 编写语义分析器的代码。
(2) 测试并调试语义分析器。
4. 实验四:中间代码(1) 编写中间代码器的代码。
(2) 测试并调试中间代码器。
5. 实验五:目标代码(1) 编写目标代码器的代码。
(2) 测试并调试目标代码器。
五、实验注意事项1. 按照实验要求编写代码,注意代码规范和可读性。
编译原理实验1预处理
一、实验目的与任务编制一个源程序的输入过程,从键盘、文件或文本框输入若干行语句,依次存入输入缓冲区(字符型数据);并编制一个扫描子程序,该子程序中每次调用能依次从存放源程序的输入缓冲区中读出一个有效字符。
二、实验涉及的相关知识点1、VC++中微软基础类库MFC的使用,包括控件、菜单的使用以及消息映射。
2、原程序的扫描,分析及处理。
三、实验内容与过程1、创建一个单文档应用程序,添加控件,关联变量,结果如下:2、为控件添加消息映射,代码如下:void CMainFrame::OnBYYuChuLi(){// TODO: Add your command handler code herechar strWrite[1024];char strTmp[32];int i;if (!bFileOk){MessageBox("请先打开一个源程序文件!","预处理",MB_OK|MB_ICONINFORMATION);return;}GetAppPath();strcpy(strWrite,strAppPath);strcat(strWrite,"yuchuli.txt");//定义输入文件及输出文件/*///////////////////////////////方法(1)CFile//缺点:文件结束的判断CFile fpIn,fpOut;char ch;UINT nfLen;if (!fpIn.Open(strFile,CFile::modeRead,NULL))MessageBox("Open Error!");if(!fpOut.Open(strWrite,CFile::modeWrite|CFile::modeCreate,NULL)) MessageBox("Write Error!");fpIn.Read(&ch,1);//读一个字节nfLen=fpIn.GetLength();//取得文件长度fpOut.Write(&ch,1); //写一个字节/////////////////*//*///////////////////////////////方法(2)fstreamchar ch;fstream fpIn(strFile,ios::in);//定义文件用于输入fstream fpOut(strWrite,ios::out);//定义文件用于输出fpIn>>ch;//读入一个字节或使用fpIn.read();fpout<<ch;///写一个字节到文件或使用fpOut.write();fpIn.close();//关闭文件fpOut.close();/////////////////////////////*////////////////////////////////方法(3)FILEchar ch=' ',ch1;FILE *fpIn,*fpOut;//打开文件用于读入数据if ((fpIn=fopen(strFile,"rt"))==NULL){MessageBox("无法读入文件数据!","预处理",MB_OK|MB_ICONEXCLAMATION);return;}//打开文件用于写入数据if ((fpOut=fopen(strWrite,"wt"))==NULL){MessageBox("无法写数据到文件!","预处理",MB_OK|MB_ICONEXCLAMATION);return;}//去掉程序最前面的空格while (ch==' ')ch=fgetc(fpIn);//开始对程序进行扫描i=0;while(!feof(fpIn)){if (islower(ch) || ch=='#'){strTmp[i++]=ch;fprintf(fpOut,"%c",ch);ch=fgetc(fpIn);}else{if (!(isalpha(ch) || isdigit(ch))){//不是字母和数字strTmp[i]='\0';if (i!=0)if (isKeyWord(strTmp))fprintf(fpOut,"%c",' ');i=0;switch(ch){case ' ':while (ch==' ' &&!feof(fpIn))ch=fgetc(fpIn);break;case '/':ch1='/';ch=fgetc(fpIn);if ( ch=='*'){while ((ch1!='*' || ch!='/')&&!feof(fpIn)){ch1=ch;ch=fgetc(fpIn);}if (!feof(fpIn)){ch=fgetc(fpIn);while (ch=='\n' &&!feof(fpIn))ch=fgetc(fpIn);}}elsefprintf(fpOut,"%c",'/');break;default:fprintf(fpOut,"%c",ch);ch=fgetc(fpIn);if (ch=='\n'){fprintf(fpOut,"%c",'\n');ch=fgetc(fpIn);}while (ch=='\n' && !feof(fpIn))ch=fgetc(fpIn);}}else{fprintf(fpOut,"%c",ch);ch=fgetc(fpIn);}}}fclose(fpIn);fclose(fpOut);//打开处理的结果CByylApp *pApp=(CByylApp *)AfxGetApp();POSITION curTemplatePos=pApp->GetFirstDocTemplatePosition();CDocTemplate*curTemplate=pApp->GetNextDocTemplate(curTemplatePos);curTemplate->OpenDocumentFile(strWrite);}void CMainFrame::OnByOpen(){// TODO: Add your command handler code herestatic TCHAR szFilter[]=_T("C Source Files(*.c)|*.c|Text Files(*.txt)|*.txt|C++ Source Files(*.cpp)|*.cpp|");CString strOpen;CByylApp *pApp=(CByylApp *)AfxGetApp();CFileDialogdlg(TRUE,"",NULL,OFN_HIDEREADONLY|OFN_PATHMUSTEXIST,szFilter,NULL);dlg.m_ofn.lpstrTitle="打开文件";if (dlg.DoModal()==IDOK){POSITION curTemplatePos=pApp->GetFirstDocTemplatePosition();CDocTemplate*curTemplate=pApp->GetNextDocTemplate(curTemplatePos);curTemplate->OpenDocumentFile(dlg.GetPathName());strOpen=dlg.GetPathName();strcpy(strFile,LPCTSTR(strOpen));bFileOk=TRUE;}}void CMainFrame::GetAppPath(){CString strName;GetModuleFileName(NULL,strAppPath,1024);strName=strAppPath;int x=strName.ReverseFind('\\');strAppPath[x+1]='\0';return;}BOOL CMainFrame::isKeyWord(char* word){char*keyWords[]={"#include","#define","int","char","short","long", "unsigned","signed","float","double","FILE","struct","enum","static","return"};int i,n=15;for(i=0;i<n;i++)if (strcmp(word,keyWords[i])==0)return TRUE;return FALSE;}四、实验结果及分析1、打开一个CPP文件:处理前:处理后:五、实验相关说明文中利用了单文档应用程序的菜单和工具栏进行数据的处理。
编译原理实验报告 词法分析
编译原理实验一·词法分析一、实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。
同时增强编写和调试程序的能力。
二、实验内容及要求对某特定语言A ,构造其词法规则。
该语言的单词符号包括:保留字(见左下表)、标识符(字母大小写不敏感)、整型常数、界符及运算符(见右下表) 。
功能要求如下所示:·按单词符号出现的顺序,返回二元组序列,并输出。
·出现的标识符存放在标识符表,整型常数存放在常数表,并输出这两个表格。
·如果出现词法错误,报出:错误类型,位置(行,列)。
·处理段注释(/* */),行注释(//)。
·有段注释时仍可以正确指出词法错误位置(行,列)。
三、实验过程1、词法形式化描述使用正则文法进行描述,则可以得到如下的正规式:其中ID表示标识符,NUM表示整型常量,RES表示保留字,DEL表示界符,OPR表示运算符。
A→(ID | NUM | RES | DEL | OPR) *ID→letter(letter | didit)*NUM→digit digit*letter→a | …| z | A | …| Zdigit→0 | …| 9RES→program | begin | end | var | int | and | or | not | if | then | else | while | doDEL→( | ) | . | ; | ,OPR→+ | * | := | > | < | = | >= | <= | <>如果关键字、标识符和常数之间没有确定的算符或界符作间隔,则至少用一个空格作间隔。
空格由空白、制表符和换行符组成。
2、单词种别定义;3、状态转换图;语言A的词法分析的状态转换图如下所示:空格符,制表符或回车符字母或数字4、运行环境介绍;本次实验采用win-tc进行代码的编写和编译及运行程序的运行环境为windows5、关键算法的流程图及文字解释;程序中用到的函数列表:变量ch储存当前最新读进的字符的地址strToken存放当前字符串voidmain() //主函数struct binary *lexicalAnalyze(); //词法分析的主函数,返回一个二元组的指针void GetBC(); //检查ch指向的字符是否为空格、制表或回车符,如果是则调用GetChar()直至不是上述字符void GetChar(); //ch前移一个地址单元int ConCat(); //将ch指向的字符连接到strToken之后int isLetter(); //判断ch指向的字符是否字母int isDigit(); //判断ch指向的字符是否数字int insertId(); //向标识符表中插入当前strToken的字符串int insertConst(); //将strToken的常数插入常数表中int Reserved(); //检测当前strToken中的字符串是否保留字,若是,则返回编码,否则返回0int isId(); //检测当前strToken中的字符串是否在标识符表中已存在,若是,则返回其编号,否则返回0int isConst(); //检测当前strToken中的字符串是否在常数表中已存在,若是,则返回其编号,否则返回0void errProc(int errType); //出错处理过程,errType是错误类型,将错误信息加入错误表中main()函数的流程图如下:lexicalAnalyze()函数的流程图如下所示:Reserved()、isId()和isConst()函数均采用了对链表的遍历算法,errProc()函数通过识别不同的错误编号,向错误链表中添加相应的错误信息。
编译原理_实验一_词法分析
实习一词法分析一、实验目的:根据活动状态转换图,设计并实现一个具体的C语言的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编写一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)。
二、实验过程1.活动状态转化图2.设计思路本C语言词法分析器使用JAVA语言编写。
(1)C语言词法分析●关键字将C语言32关键字"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"存储在keyword[]字符串数组中;●专用符号= + -* / <=>>= == != ;:, { } [ ] ( )将读入的字符与ASCLL表进行比较判断;对于像“==”,“<=”等字符进行超前搜索;●空格和空白、制表符和换行符。
编译原理实验报告(一)
编译原理实验报告(一)一、实验题目:简单词法分析器的设计二、实验目的:熟悉并实现一个简单的扫描器三、实验内容:1.设计扫描器的自动机;2.设计翻译、生成Token的算法;3.编写代码并上机调试运行通过。
要求:输入——源程序文件;输出——(1)相应的Token序列;(2)关键字、界符表,符号表,常数表。
四、扫描器设计:自动机:关键字表和界符表单词编码program 3procedure 4④-begin 5end 6while 7do 8+ 9* 10⑧-:11:= 12⑨-= 13,14;15五、概要设计:(1)各模块概要设计1.判断当前读入的字符是字母还是数字int IsLetter(char ch) //判断ch是否为字母 { if (ch是A~Z或a~z) return 1;else return 0;}int IsDigit(char ch) //判断ch是否为数字{ if (ch是0~9) return 1;else return 0;}2.将读入的字符连接成单词或数while (IsLetter(ch)||IsDigit(ch)){ Concat(); //将ch中的字符拼接到strToken中ch=GetChar();}3.查表判断当前的独立串是关键字、标示符还是常数4.求出当前的独立串的code 和value(2)程序说明:1、关键字表、界符表和常数表中初始化后都有元素,即都不是空表。
而符号表则是空的。
它用来存放用户自己定义的变量名,按输入的被识别串中的顺序依次标识其value的值的1,2,3,……,n。
2、value=-1用来标识它是一个关键字;value=1用来标识它是一个界符常数的code值一定为2六、程序源代码及注释:#include "stdio.h"#include "string.h"#define N 15struct TokenType{ int code,value; };char*keywords[]={"program","procedure","begin","end","while","do","+","*",":",":=","=",",",";","(",")",}; //关键字表、界符表char ID[10][10]; //符号表int m;int Cons[10]; //常数表int n;void print(struct TokenTykpe token) //输出Token{ printf("( %d %d)\n",token.code,token.value);}void ProcError(){ printf("Error! You haven't defined it!");}int IsLetter(char ch) //判断ch是否为字母¸{ if (ch>='A' && ch<='Z' || ch>='a' && ch<='z')return 1; else return 0;}int IsDigit(char ch) //判断ch是否为数字{ if (ch>='0' && ch<='9') return 1;else return 0;}int Reserve(char *strToken) //用strToken中的单词去查关键字表。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
package com.example;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
wordList.add(wList);
}else if(isFenGeFu(str)!=0){
WordList list = new WordList(row, guanjianzi.size()+isFenGeFu(str)+2, isFenGeFu(str), str);
wordList.add(list);
天津理工大学实验报告
学院(系)名称:计算机与通信工程学院
姓名
学号
专业
班级
实验项目
实验一:词法分析器
课程名称
编译原理
课程代码
实验时间
实验地点
批改意见
成绩
教师签字:
1、实验内容:实现标准C语言词法分析器。
2、实验要求:
(1)单词种别编码要求
基本字、运算符、界符:一符一种
标识符:统一为一种;
常量:按类型编码;
ArrayList<String> fuhaobiao = new ArrayList<>();
ArrayList<String> changLiangBiao = new ArrayList<>();
//将字符加入到符号表中
public ArrayList<String> addToFuHaoBiao(String s){
nc = str.charAt(i+1);
if(ch=='\n'){
ch = '$';
ts = ts+ch;
}else if(ch==' '||ch=='\t'||ch=='\r'){
if(nc==' '||nc=='\t'||nc=='\r'){
continue;
}else{
ch=' ';
ts = ts + ch;
return type;
}
public void setType(int type) {
this.type = type;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}else{
ts = ts+ch;
}
}
ch = str.charAt(str.length()-1);
if(ch!=' '&&ch!='\r'&&ch!='\t'&&ch!='\n'){
ts = ts + ch;
}
return ts;
}
//将一个长字符串按照分割规则,分割成一个个的短的字符串
public ArrayList<Word> fenGe(String str){
e.printStackTrace();
}
return str;
}
//处理字符串中的换行和空格
public String yuChuLi(String str){
String ts = "";
int i;
char ch,nc;
for(i=0;i<str.length()-1;i++){
ch = str.charAt(i);
try {
Reader reader = new FileReader(file);
char c[] = new char[1024];
int len = reader.read(c);
str = new String(c, 0, len);
reader.close();
} catch (Exception e) {
public boolean isIdent(String str){
char ch;
int i;
for(i=0;i<str.length();i++){
ch=str.charAt(i);
if((i==0&&!isLetter(ch))||(!isDigit(ch)&&!isLetter(ch))){
public class HanShu {
//定义符号表数组,常量表数组,关键字数组
List<String> guanjianzi = Arrays.asList("double","long","char","int","if","else","for","while","return"
,"break","continue","switch","case","default","void","struct","static","do","short");
}
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
@Override
public String toString() {
return "Word [row=" + row + ", string=" + string + "]";
this.row = row;
this.type = type;
this.number = number;
this.str = str;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getType() {
}else
return true;
}
//将一个集合中的数据分类,判断他们是否是关键字或者是常量,亦或是标识符
public ArrayList<WordList> fenlei(ArrayList<Word> arr){
ArrayList<WordList> wordList = new ArrayList<>();
+ ", str=" + str + "]e com.example;
public class Word {
private int row;
private String string;
public Word() {
super();
// TODO Auto-generated constructor stub
public boolean isLetter(char ch) {
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){
return true;
}else{
return false;
}
}
//判断一个字符是否是数字
public boolean isDigit(char ch) {
s = s + ch;
}else{
list.add(new Word(row,s));
s = "";
s = s + ch;
}
}else{
if(isTwoOperator(s,ch)){
s = s + ch;
}else{
if(s==""&&ch!='$'){
s = s + ch;
}else if(s==""&&ch=='$'){
List<String> caozuofu = Arrays.asList("+","-","*","/","%","=",">","<","!","==","!=",">=","<=","++","--",
"&","&&","||","[","]");