词法分析器、语法分析器试验报告
语法分析器实验报告
语法分析器的设计实验报告一、实验内容语法分析程序用LL(1) 语法分析方法。
首先输入定义好的文法书写文件(所用的文法可以用LL(1) 分析),先求出所输入的文法的每个非终结符是否能推出空,再分别计算非终结符号的FIRST 集合,每个非终结符号的 FOLLOW 集合,以及每个规则的 SELECT 集合,并判断任意一个非终结符号的任意两个规则的 SELECT 集的交集是不是都为空,如果是,则输入文法符合 LL(1) 文法,可以进行分析。
对于文法:G[E]:E->E+T|TT->T*F|FF->i|(E)分析句子 i+i*i 是否符合文法。
二、基本思想1、语法分析器实现语法分析是编译过程的核心部分,它的主要任务是按照程序的语法规则,从由词法分析输出的源程序符号串中识别出各类语法成分,同时进行词法检查,为语义分析和代码生成作准备。
这里采用自顶向下的 LL(1) 分析方法。
语法分析程序的流程图如图5-4 所示。
开始读入文法有效?是 LL(1) 文法?判断句型结束报错语法分析程序流程图该程序可分为如下几步:(1)读入文法(2)判断正误(3)若无误,判断是否为LL(1) 文法(4)若是,构造分析表;(5)由句型判别算法判断输入符号串是为该文法的句型。
三、核心思想该分析程序有 15 部分组成:(1)首先定义各种需要用到的常量和变量;(2)判断一个字符是否在指定字符串中;(3)读入一个文法;(4)将单个符号或符号串并入另一符号串;(5)求所有能直接推出 & 的符号;(6)求某一符号能否推出‘& ’;(7)判断读入的文法是否正确;(8)求单个符号的 FIRST;(9)求各产生式右部的FIRST;(10)求各产生式左部的FOLLOW ;(11)判断读入文法是否为一个LL(1) 文法;(12)构造分析表 M ;(13)句型判别算法;(14)一个用户调用函数;(15)主函数;下面是其中几部分程序段的算法思想:1、求能推出空的非终结符集Ⅰ、实例中求直接推出空的empty 集的算法描述如下:void emp(char c){ 参数 c 为空符号char temp[10]; 定义临时数组int i;for(i=0;i<=count-1;i++) 从文法的第一个产生式开始查找{i f 产生式右部第一个符号是空符号并且右部长度为then 将该条产生式左部符号保存在临时数组将临时数组中的元素合并到记录可推出1,temp 中& 符号的数组empty中。
语法法分析实验报告
一、实验目的1. 理解语法分析的基本概念和原理。
2. 掌握语法分析器的构建方法。
3. 培养实际操作能力,提高编程水平。
二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.83. 开发工具:PyCharm三、实验内容1. 语法分析概述2. 词法分析3. 语法分析4. 实验实现四、实验步骤1. 语法分析概述(1)了解语法分析的定义、作用和意义。
(2)掌握语法分析的基本原理和流程。
2. 词法分析(1)编写词法分析器代码,将源代码分解成单词序列。
(2)实现词法分析器的各个功能,如:识别标识符、关键字、运算符等。
3. 语法分析(1)设计语法分析器,将单词序列转换为抽象语法树(AST)。
(2)实现语法分析器的各个功能,如:识别表达式、语句、函数等。
4. 实验实现(1)创建Python项目,导入相关库。
(2)编写词法分析器代码,实现单词序列的分解。
(3)编写语法分析器代码,实现抽象语法树的构建。
(4)测试语法分析器,验证其正确性。
五、实验结果与分析1. 词法分析结果实验中,我们成功地将源代码分解成单词序列,包括标识符、关键字、运算符等。
词法分析器的输出结果如下:```identifier: akeyword: intoperator: +identifier: boperator: =integer: 5```2. 语法分析结果通过语法分析器,我们将单词序列转换成抽象语法树。
以下是一个示例的抽象语法树:```Program├── Declaration│ ├── Type│ │ ├── Identifier│ │ └── Integer│ └── Identifier│ └── a└── Statement├── Expression│ ├── Identifier│ └── a└── Operator└── =└── Expression├── Identifier└── b└── Integer└── 5```从实验结果可以看出,我们的语法分析器能够正确地将源代码转换为抽象语法树。
词法分析器实验报告
词法分析器实验报告引言:词法分析器(Lexical Analyzer)是编译器的重要组成部分,其主要任务是将源代码转化为一个个独立的词法单元,为语法分析器提供输入。
在本次实验中,我们设计并实现了一个简单的词法分析器,通过对其功能和性能的测试,评估其在不同场景下的表现。
实验目的:1. 确定词法分析器的输入和输出要求;2. 通过构建适当的正则表达式规则,匹配不同类型的词法单元;3. 实现一个高效的词法分析器,确保在处理大型源代码时性能不受影响;4. 对词法分析器的功能和性能进行测试和评估。
实验过程:1. 设计词法分析器的接口:1.1 确定输入:源代码字符串。
1.2 确定输出:词法单元流,每个词法单元包含类型和对应的字符串值。
2. 构建正则表达式规则:2.1 识别关键字:根据编程语言的关键字列表构建正则表达式规则,将关键字与标识符区分开。
2.2 识别标识符:一般由字母、下划线和数字组成,且以字母或下划线开头。
2.3 识别数字:整数和浮点数可以使用不同的规则来识别。
2.4 识别字符串:使用引号(单引号或双引号)包裹的字符序列。
2.5 识别特殊符号:各类操作符、括号、分号等特殊符号需要单独进行规则设计。
3. 实现词法分析器:3.1 读取源代码字符串:逐个字符读取源代码字符串,并根据正则表达式规则进行匹配。
3.2 保存词法单元:将匹配到的词法单元保存到一个词法单元流中。
3.3 返回词法单元流:将词法单元流返回给调用者。
4. 功能测试:4.1 编写测试用例:针对不同类型的词法单元编写测试用例,包括关键字、标识符、数字、字符串和特殊符号。
4.2 执行测试用例:将测试用例作为输入传递给词法分析器,并检查输出是否和预期一致。
4.3 处理错误情况:测试词法分析器对于错误输入的处理情况,如非法字符等。
5. 性能测试:5.1 构建大型源代码文件:生成包含大量代码行数的源代码文件。
5.2 执行词法分析:使用大型源代码文件作为输入,测试词法分析器的性能。
词法分析器实验报告
词法分析器实验报告词法分析器设计一、二、实验目的:对C语言的一个子集设计并实现一个简单的词法分析器,掌握利用状态转换图设计词法分析器的基本方法。
利用该词法分析器完成对源程序字符串的词法分析。
输出形式是源程序的单词符号二元式的代码,并保存到文件中。
二、实验内容:1. 设计原理词法分析的任务:从左至右逐个字符地对源程序进行扫描,产生一个个单词符号。
理论基础:有限自动机、正规文法、正规式词法分析器(Lexical Analyzer) 又称扫描器(Scanner):执行词法分析的程序2. 词法分析器的功能和输出形式功能:输入源程序、输出单词符号程序语言的单词符号一般分为以下五种:关键字、标识符、常数、运算符,界符3. 输出的单词符号的表示形式:单词种别用整数编码,关键字一字一种,标识符统归为一种,常数一种,各种符号各一种。
4. 词法分析器的结构5. 状态转换图实现三、程序设计1.总体模块设计/*用来存储目标文件名*/string file_name;/*提取文本文件中的信息。
*/string GetText();/*获得一个单词符号,从位置i开始查找。
并且有一个引用参数j,用来返回这个单词最后一个字符在str的位置。
*/string GetWord(string str,int i,int& j);/*这个函数用来除去字符串中连续的空格和换行int DeleteNull(string str,int i);/*判断i当前所指的字符是否为一个分界符,是的话返回真,反之假*/bool IsBoundary(string str,int i);/*判断i当前所指的字符是否为一个运算符,是的话返回真,反之假*/bool IsOperation(string str,int i);/*此函数将一个pair数组输出到一个文件中*/void OutFile(vector<pair<int,string> > v);/*此函数接受一个字符串数组,对它进行词法分析,返回一个pair型数组*/vector<pair<int,string> > analyst(vector<string> vec);/*此函数判断传递的参数是否为关键字,是的话,返回真,反之返回假*/bool IsKey(string str);2.各模块设计(1).首先根据上面单词符号表及ID和NUM的正规定义式,构造出状态转换图;(2).定义相关的变量和数据结构。
词法分析器实验报告
词法分析器实验报告⼀、实验⽬的通过设计⼀个词法分析程序,对词法进⾏分析,加强对词法的理解,掌握对程序设计语⾔的分解和理解。
⼆、实验内容和要求在原程序中输⼊源代码对字符串表⽰的源程序从左到右进⾏扫描和分解根据词法规则识别出⼀个⼀个具有独⽴意义的单词符号以供语法分析之⽤发现词法错误,则返回出错信息在源程序中,⾃动识别单词,把单词分为五种,并输出对应的单词种别码。
1. 识别关键字:main if int for while do return break continue,该类的单词码为1.2. 识别标识符:表⽰各种名字,如变量名、数组名、函数名等,如char ch, int syn, token,sum,该类的单词码为2.3. 运算符:+、-、*、/、=、>、<、>=、<=、!=4. 分隔符:,、;、{、}、(、)5. 常数,例:123各种单词符号对应的种别码。
输出形式:⼆元式– (单词种别,单词⾃⾝的值)单词种别,表明单词的种类,语法分析需要的重要信息– 整数码关键字、运算符、界符:⼀符⼀码标识符:10, 常数:11单词⾃⾝的值– 标识符token、常数sum– 关键字、运算符、界符token三、实验⽅法、步骤及结果测试1.源程序#include <stdio.h>#include <string.h>char string[80],simbol[8],ch;int wordID,index,m,n,sum;char *rwtab[6]={"begin","if","then","while","do","end"};void scaner(void);main(){int index=0;printf("请输⼊代码,并以串#号键结束:\n");do{scanf("%c",&ch);string[index++]=ch;}while(ch!='#');index=0;do{scaner();switch(wordID)case11:printf("( %-10d%5d )\n",sum,wordID);break;case -1:printf("错误\n");return0;break;default:printf("( %-10s%5d )\n",simbol,wordID);break;}}while(wordID!=0);return0;}void scaner(void){sum=0;for(m=0;m<8;m++)simbol[m++]= NULL;ch=string[index++];m=0;while((ch=='')||(ch=='\n'))ch=string[index++];if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))//判断输⼊的字符是否为英⽂字母 {while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))){simbol[m++]=ch;ch=string[index++];}index--;wordID=10;for(n=0;n<6;n++)if(strcmp(simbol,rwtab[n])==0){wordID=n+1;break;}}else if((ch>='0')&&(ch<='9'))//判断输⼊的字符是否为数字{while((ch>='0')&&(ch<='9')){sum=sum*10+ch-'0';ch=string[index++];}index--;wordID=11;}else{switch(ch)//通过循环判断输⼊的字符是否为运算符{case'<':simbol[m++]=ch;ch=string[index++];if(ch=='='){wordID=22;simbol[m++]=ch;}else{wordID=20;index--;}break;case'>':simbol[m++]=ch;ch=string[index++];if(ch=='='){wordID=24;simbol[m++]=ch;else{wordID=23;index--;}break;case'+':simbol[m++]=ch;ch=string[index++];if(ch=='+'){wordID=17;simbol[m++]=ch;}else{wordID=13;index--;}break;case'-':simbol[m++]=ch;ch=string[index++];if(ch=='-'){wordID=29;simbol[m++]=ch;}else{wordID=14;index--;}break;case'!':ch=string[index++];if(ch=='='){wordID=21;simbol[m++]=ch;}else{wordID=31;index--;}break;case'=':simbol[m++]=ch;ch=string[index++];if(ch=='='){wordID=25;simbol[m++]=ch;}else{wordID=18;index--;}break;case'*':wordID=15;simbol[m++]=ch;break;case'/':wordID=16;simbol[m++]=ch;break;case'('://判断输⼊的字符是否为分隔符 wordID=27;simbol[m++]=ch;break;case')':wordID=28;simbol[m++]=ch;break;case'{':wordID=5;simbol[m++]=ch;break;case'}':wordID=6;simbol[m++]=ch;break;case';':wordID=26;simbol[m++]=ch;break;case'\"':wordID=30;simbol[m++]=ch;break;case'#':wordID=0;simbol[m++]=ch;break;case':':wordID=17;simbol[m++]=ch;break;default:wordID=-1;break;}}simbol[m++]='\0'; }四.运⾏结果及分析。
词法分析器实验报告
词法分析器实验报告词法分析器实验报告一、引言词法分析器是编译器中的重要组成部分,它负责将源代码分解成一个个的词法单元,为之后的语法分析提供基础。
本实验旨在设计和实现一个简单的词法分析器,以深入理解其工作原理和实现过程。
二、实验目标本实验的目标是设计和实现一个能够对C语言代码进行词法分析的程序。
该程序能够将源代码分解成关键字、标识符、常量、运算符等各种词法单元,并输出其对应的词法类别。
三、实验方法1. 设计词法规则:根据C语言的词法规则,设计相应的正则表达式来描述各种词法单元的模式。
2. 实现词法分析器:利用编程语言(如Python)实现词法分析器,将源代码作为输入,根据词法规则将其分解成各种词法单元,并输出其类别。
3. 测试和调试:编写测试用例,对词法分析器进行测试和调试,确保其能够正确地识别和输出各种词法单元。
四、实验过程1. 设计词法规则:根据C语言的词法规则,我们需要设计正则表达式来描述各种词法单元的模式。
例如,关键字可以使用'|'操作符将所有关键字列举出来,标识符可以使用[a-zA-Z_][a-zA-Z0-9_]*的模式来匹配,常量可以使用[0-9]+的模式来匹配等等。
2. 实现词法分析器:我们选择使用Python来实现词法分析器。
首先,我们需要读取源代码文件,并将其按行分解。
然后,针对每一行的代码,我们使用正则表达式进行匹配,以识别各种词法单元。
最后,我们将识别出的词法单元输出到一个结果文件中。
3. 测试和调试:我们编写了一系列的测试用例,包括各种不同的C语言代码片段,以测试词法分析器的正确性和鲁棒性。
通过逐个测试用例的运行结果,我们可以发现和解决词法分析器中的问题,并进行相应的调试。
五、实验结果经过多次测试和调试,我们的词法分析器能够正确地将C语言代码分解成各种词法单元,并输出其对应的类别。
例如,对于输入的代码片段:```cint main() {int a = 10;printf("Hello, world!\n");return 0;}```我们的词法分析器将输出以下结果:```关键字:int标识符:main运算符:(运算符:)运算符:{关键字:int标识符:a运算符:=常量:10运算符:;标识符:printf运算符:(常量:"Hello, world!\n"运算符:)运算符:;关键字:return常量:0运算符:;```可以看到,词法分析器能够正确地将代码分解成各种词法单元,并输出其对应的类别。
词法分析器的实验报告
词法分析器的实验报告词法分析器的实验报告引言:词法分析器是编译原理中的重要组成部分,它负责将源代码中的字符序列转换为有意义的词法单元,为后续的语法分析提供基础。
本实验旨在设计和实现一个简单的词法分析器,并对其进行测试和评估。
实验设计:1. 词法规则设计:在开始实验之前,我们首先需要设计词法规则,即定义源代码中的合法词法单元。
例如,对于一门类C的语言,我们可以定义关键字(如if、while、int等)、标识符、运算符(如+、-、*等)、分隔符(如()、{}等)等。
2. 有限自动机(DFA)的设计:基于词法规则,我们可以设计一个有限自动机,用于识别和分析源代码中的词法单元。
有限自动机是一个状态转换图,其中每个状态代表一种词法单元,而边表示输入字符的转换关系。
3. 实现代码:根据有限自动机的设计,我们可以使用编程语言(如Python、C++等)实现词法分析器的代码。
代码的主要功能包括读取源代码文件、逐个字符进行词法分析、识别和输出词法单元。
实验过程:1. 词法规则设计:我们以一门简单的算术表达式语言为例,设计了以下词法规则:- 数字:由0-9组成的整数或浮点数。
- 运算符:包括+、-、*、/等。
- 分隔符:包括括号()和逗号,。
- 标识符:以字母开头,由字母和数字组成的字符串。
2. 有限自动机(DFA)的设计:我们基于词法规则,设计了一个简单的有限自动机。
该自动机包含以下状态:- 初始状态:用于读取和识别源代码中的字符。
- 数字状态:用于识别和输出数字。
- 运算符状态:用于识别和输出运算符。
- 分隔符状态:用于识别和输出分隔符。
- 标识符状态:用于识别和输出标识符。
3. 实现代码:我们使用Python编程语言实现了词法分析器的代码。
代码主要包括以下功能:- 读取源代码文件。
- 逐个字符进行词法分析,根据有限自动机的设计进行状态转换。
- 识别和输出词法单元。
实验结果:我们对几个测试样例进行了词法分析,并对结果进行了评估。
语法分析器实验报告
词法分析器实验报告实验名称:语法分析器实验内容:利用LL(1)或LR(1)分析语句语法,判断其是否符合可识别语法。
学会根据状态变化、first、follow或归约转移思想构造状态分析表,利用堆栈对当前内容进行有效判断实验设计:1.实现功能可对一段包含加减乘除括号的赋值语句进行语法分析,其必须以$为终结符,语句间以;隔离,判断其是否符合语法规则,依次输出判断过程中所用到的产生式,并输出最终结论,若有错误可以报错并提示错误所在行数及原因2.实验步骤3.算法与数据结构a)LLtable:left记录产生式左端字符;right记录产生式右端字符;ln记录产生式右端字符长度Status:记录token分析情况Token:category,类型;value,具体内容b)根据LL(1)算法,手工构造分析表,并将内容用数组存储,便于查找c)先将当前语句的各token按序存储,当前处理语句最后一个token以#标记,作为输入流与产生式比较,堆栈中初始放入#,x,a为处理输入流中当前读头内容✓若top=a=‘#‘表示识别成功,退出分析程序✓若top=a!=‘#‘表示匹配,弹出栈顶符号,读头前进一个✓若top为i或n,但top!=a,出错,输出当前语句所在行,出错具体字符✓若top不为i或n,查预测分析表,若其中存放关于top产生式,则弹出top,将产生式右部自右向左压入栈内,输出该产生式,若其中没有产生式,出错,输出当前语句所在行,出错具体字符d)以;作为语句终结,每次遇到分号则处理之前语句并清空后预备下语句处理,当遇到$表示该段程序结束,停止继续处理4.分析表构造过程a)x->i=ee->e+t|e-t|tt->t*f|t/f|ff->(e)|i|nnote: i表示变量,n表示数字,!表示空串b)提取左公因子x->i=ee->ea|ta->+t|-tt->tb|fb->*f|/ff->(e)|i|nc)消除左递归x->i=ee->tcc->ac|!a->+t|-tt->fdd->bd|!b->*e|/ff->(e)|i|n5.类class parser{public:LLtable table[100][100]; //LL(1)表void scanner(); //扫描输入流中内容并分析parser(istream& in); //初始化,得到输入文件地址int getLine() const; //得到当前行数private:int match(); //分析语法stack <char> proStack; //分析堆栈void constructTable(); //建立LL(1)表int getRow(char ch); //取字符所在表中行int getCol(char ch); //取字符所在表中列istream* pstream; //输入流void insertToken(token& t); //插入当前tokenstatus getToken(token& t); //找到tokenint getChar(); //得到当前字符int peekChar(); //下一个字符void putBackChar(char ch); //将字符放回void skipChar(); //跳过当前字符void initialization(); //初始化堆栈等int line; //当前行数token tokens[1000]; //字符表int counter; //记录当前字符表使用范围}6.主要代码void parser::constructTable() //建立LL(1)表{for (int i=0;i<8;i++){for (int j=0;j<9;j++){table[i][j].left=' ';for (int k=0;k<3;k++)table[i][j].right[k]=' ';}}table[0][6].left='x';table[0][6].ln=3;table[0][6].right[0]='i';table[0][6].right[1]='=';table[0][6].right[2]='e';table[1][4].left='e';table[1][4].ln=2;table[1][4].right[0]='t';table[1][4].right[1]='c';table[1][6].left='e';table[1][6].ln=2;table[1][6].right[0]='t';table[1][6].right[1]='c';table[1][7].left='e';table[1][7].ln=2;table[1][7].right[0]='t';table[1][7].right[1]='c';table[2][0].left='c';table[2][0].ln=2;table[2][0].right[0]='a';table[2][0].right[1]='c';table[2][1].left='c';table[2][1].ln=2;table[2][1].right[0]='a';table[2][1].right[1]='c';table[2][5].left='c';table[2][5].ln=0;table[2][5].right[0]='!';table[2][8].left='c';table[2][8].ln=0;table[2][8].right[0]='!';table[3][0].left='a';table[3][0].ln=2;table[3][0].right[0]='+'; table[3][0].right[1]='t'; table[3][1].left='a';table[3][1].ln=2;table[3][1].right[0]='-'; table[3][1].right[1]='t'; table[4][4].left='t';table[4][4].ln=2;table[4][4].right[0]='f'; table[4][4].right[1]='d'; table[4][6].left='t';table[4][6].ln=2;table[4][6].right[0]='f'; table[4][6].right[1]='d'; table[4][7].left='t';table[4][7].ln=2;table[4][7].right[0]='f'; table[4][7].right[1]='d'; table[5][0].left='d';table[5][0].ln=0;table[5][0].right[0]='!'; table[5][1].left='d';table[5][1].ln=0;table[5][1].right[0]='!'; table[5][2].left='d';table[5][2].ln=2;table[5][2].right[0]='b'; table[5][2].right[1]='d'; table[5][3].left='d';table[5][3].ln=2;table[5][3].right[0]='b'; table[5][3].right[1]='d'; table[5][5].left='d';table[5][5].ln=0;table[5][5].right[0]='!'; table[5][8].left='d';table[5][8].ln=0;table[5][8].right[0]='!'; table[6][2].left='b';table[6][2].ln=2;table[6][2].right[0]='*'; table[6][2].right[1]='f'; table[6][3].left='b';table[6][3].ln=2;table[6][3].right[0]='/'; table[6][3].right[1]='f'; table[7][4].left='f';table[7][4].ln=3;table[7][4].right[0]='(';table[7][4].right[1]='e';table[7][4].right[2]=')';table[7][6].left='f';table[7][6].ln=1;table[7][6].right[0]='i';table[7][7].left='f';table[7][7].ln=1;table[7][7].right[0]='n';}int parser::match() //分析语法{ofstream ofs("out.txt",ios::app);char a;int i=0;for (int p=0;p<counter;p++){cout<<tokens[p].value;ofs<<tokens[p].value;}cout<<endl;ofs<<endl<<"ANALYSIS:"<<endl;while(1){if(tokens[i].category=='n' || tokens[i].category=='i')a=tokens[i].category;elsea=(tokens[i].value)[0];if(a==proStack.top()){if(a=='#'){cout<<"This is valid!"<<endl<<endl;ofs<<"This is valid!"<<endl<<endl;return 0;}else{proStack.pop();i++;}}else{if(proStack.top() =='n'|| proStack.top() =='i'){if(a!='#'){cout<<"ERROR(LINE "<<getLine()<<" ): "<<a<<" cannot be matched"<<endl;ofs<<"ERROR(LINE "<<getLine()<<" ): "<<a<<" cannot be matched"<<endl;}else{cout<<"ERROR(LINE "<<getLine()<<" ): Unexpected ending"<<endl;ofs<<"ERROR(LINE "<<getLine()<<" ): Unexpected ending"<<endl;}cout<<"This is invalid!"<<endl<<endl;ofs<<"This is invalid!"<<endl<<endl;return 0;}else{if((table[getRow(proStack.top())][getCol(a)]).left!=' '){char pst=proStack.top();int n=table[getRow(pst)][getCol(a)].ln;int k=0;ofs<<table[getRow(pst)][getCol(a)].left<<"->"<<table[getRow(pst)][getCol(a)].right[0]<<table[getRow(pst)][g etCol(a)].right[1]<<table[getRow(pst)][getCol(a)].right[2]<<endl;proStack.pop();while (n>0){//cout<<n<<" "<<table[getRow(pst)][getCol(a)].right[n-1]<<endl;proStack.push(table[getRow(pst)][getCol(a)].right[n-1]);n--;}}else{if(a!='#'){cout<<"ERROR(LINE "<<getLine()<<" ): "<<a<<" cannot be matched"<<endl;ofs<<"ERROR(LINE "<<getLine()<<" ): "<<a<<" cannot be matched"<<endl;}else{cout<<"ERROR(LINE "<<getLine()<<" ): Unexpected ending"<<endl;ofs<<"ERROR(LINE "<<getLine()<<" ): Unexpected ending"<<endl;}cout<<"This is invalid!"<<endl<<endl;ofs<<"This is invalid!"<<endl<<endl;return 0;}}}}}实验结果:●输入(in.txt)●输出1输出2(out.txt)实验总结:原本以为处理四则运算赋值将会很困难,但在使用LL(1)后发现,思路还是挺清晰简单的,但在实验过程中,由于LL(1)不能出现左递归和左公因子,不得不将其消除,原本简单的产生式一下变多了,而在产生式理解上也没有原来直观,不过其状态复杂度没有LR高,故仍选择该方法。
编译实验报告(语法分析、词法分析)
printf("(3, %s)\n",digittp);
实
验
原
理
(
算
法
流
程
)
5、其他函数
char alphaprocess(char buffer)
char othertp [20];
othertp[0]=buffer;
othertp[1]='\0';
char *border[7]={",",";",".","(",")","{","}"}; //分格符
char *arithmetic[8]={"+","-","*","/","<",">","=","+="}; //运算符
////////////////////////////////////////////////////////////////////////////////////////
if (search(othertp,4)) do//判断字符是否是运算符
printf("(4, %s)\n",othertp);
buffer=fgetc(fp);
goto out;
if (search(othertp,5)) do //判断字符是否是分隔符
printf("(5, %s)\n",othertp);
词法分析器语法分析器实验报告(编译原理超实用)
山东大学编译技术课程设计班级软件一班学号**********XX姓名软件一班万岁指导老师贺老师二零一一年三月一、目的<<编译技术>>是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。
从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。
二、任务及要求基本要求:1.词法分析器产生下述小语言的单词序列这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表:对于这个小语言,有几点重要的限制:首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。
所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。
例如,下面的写法是绝对禁止的:IF(5)=x其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。
也就是说,对于关键字不专设对应的转换图。
但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。
当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。
再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。
例如,一个条件语句应写为IF i>0 i= 1;而绝对不要写成IFi>0 i=1;因为对于后者,我们的分析器将无条件地将IFI看成一个标识符。
这个小语言的单词符号的状态转换图,如下图:2.语法分析器能识别由加+ 减- 乘* 除/ 乘方^ 括号()操作数所组成的算术表达式,其文法如下:E→E+T|E-T|TT→T*F|T/F|FF→P^F|Pp→(E)|i使用的算法可以是:预测分析法;递归下降分析法;算符优先分析法;LR分析法等。
3.中间代码生成器产生上述算术表达式的中间代码(四元式序列)三、实现过程说明给出各题目的详细算法描述,数据结构和函数说明,流程图。
编译原理词法分析,语法分析实验报告
else
{
left[count]=point[0];
memcpy(right[count],temp,m);
right[count][m]='\0';
m=0;
count++;
}
}
left[count]=point[0];
memcpy(right[count],temp,m);
(3)若无误,判断是否为LL(1)文法
(4)若是,构造分析表;
(5)由总控算法判断输入符号串是否为该文法的句型。
3.流程图
是
是
4.源程序
/*******************************************
语法分析程序
作者:xxx
学号:xxx
********************************************/
int i;
for(i=0;i<=count-1;i++)
{
if(right[i][0]==c&&strlen(right[i])==1)
{
temp[0]=left[i];
temp[1]='\0';
merge(empty,temp,1);
emp(left[i]);
}
}
}
/*******************************************
int i,j;
for(i=0;i<=strlen(s)-1;i++)
{
if(type==2&&s[i]=='^')
编译原理实验报告(词法分析器语法分析器)
编译原理实验报告实验一一、实验名称:词法分析器的设计二、实验目的:1,词法分析器能够识别简单语言的单词符号2,识别出并输出简单语言的基本字.标示符.无符号整数.运算符.和界符。
三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
2、程序流程图(1)主程序(2)扫描子程序3、各种单词符号对应的种别码五、实验容: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语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术。
语法分析实验报告
语法分析实验报告一、实验目的语法分析是编译原理中的重要环节,本次实验的目的在于深入理解和掌握语法分析的基本原理和方法,通过实际操作和实践,提高对编程语言语法结构的分析能力,为进一步学习编译技术和开发相关工具打下坚实的基础。
二、实验环境本次实验使用的编程语言为 Python,使用的开发工具为 PyCharm。
三、实验原理语法分析的任务是在词法分析的基础上,根据给定的语法规则,将输入的单词符号序列分解成各类语法单位,并判断输入字符串是否符合语法规则。
常见的语法分析方法有自顶向下分析法和自底向上分析法。
自顶向下分析法包括递归下降分析法和预测分析法。
递归下降分析法是一种直观、简单的方法,但存在回溯问题,效率较低。
预测分析法通过构建预测分析表,避免了回溯,提高了分析效率,但对于复杂的语法规则,构建预测分析表可能会比较困难。
自底向上分析法主要包括算符优先分析法和 LR 分析法。
算符优先分析法适用于表达式的语法分析,但对于一般的上下文无关文法,其适用范围有限。
LR 分析法是一种功能强大、适用范围广泛的方法,但实现相对复杂。
四、实验内容(一)词法分析首先,对输入的源代码进行词法分析,将其分解为一个个单词符号。
单词符号包括关键字、标识符、常量、运算符、分隔符等。
(二)语法规则定义根据实验要求,定义了相应的语法规则。
例如,对于简单的算术表达式,可以定义如下规则:```Expression > Term | Expression '+' Term | Expression ''TermTerm > Factor | Term '' Factor | Term '/' FactorFactor >'(' Expression ')'| Identifier | Number```(三)语法分析算法实现选择了预测分析法来实现语法分析。
首先,根据语法规则构建预测分析表。
然后,从输入字符串的起始位置开始,按照预测分析表的指导进行分析。
词法分析、语法分析、语义分析实例解析及实验报告
词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
二、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。
(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。
空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。
2.2 各种单词符号对应的种别码:输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。
例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……标识符(需进一步判断是否为关键字)数字+=+-=-词法分析状态转换图(终结状态右上角*表示多读一个符号)三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
3.1 主程序示意图:主程序示意图如图3-1所示。
其中初始包括以下两个方面: ⑴ 关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:Char *rwtab[6] = {“begin ”, “if ”, “then ”, “while ”, “do ”, “end ”,};图3-1(2)程序中需要用到的主要变量为syn,token 和sum 3.2 扫描子程序的算法思想:首先设置3个变量:①token 用来存放构成单词符号的字符串;②sum 用来存放整型单词;③syn 用来存放单词符号的种别码。
编译原理教程实验报告
一、实验目的本次实验旨在使学生通过编译原理的学习,了解编译程序的设计原理及实现技术,掌握编译程序的各个阶段,并能将所学知识应用于实际编程中。
二、实验内容1. 词法分析2. 语法分析3. 语义分析4. 中间代码生成5. 代码优化6. 目标代码生成三、实验步骤1. 词法分析(1)设计词法分析器,识别输入源代码中的各种词法单元;(2)使用C语言实现词法分析器,并进行测试。
2. 语法分析(1)根据文法规则设计语法分析器,识别输入源代码的语法结构;(2)使用C语言实现语法分析器,并进行测试。
3. 语义分析(1)设计语义分析器,检查语法分析后的语法树,确保语义正确;(2)使用C语言实现语义分析器,并进行测试。
4. 中间代码生成(1)设计中间代码生成器,将语义分析后的语法树转换为中间代码;(2)使用C语言实现中间代码生成器,并进行测试。
5. 代码优化(1)设计代码优化器,对中间代码进行优化,提高程序性能;(2)使用C语言实现代码优化器,并进行测试。
6. 目标代码生成(1)设计目标代码生成器,将优化后的中间代码转换为特定目标机的汇编语言;(2)使用C语言实现目标代码生成器,并进行测试。
四、实验结果与分析1. 词法分析实验结果:成功识别输入源代码中的各种词法单元,包括标识符、关键字、运算符、常量等。
2. 语法分析实验结果:成功识别输入源代码的语法结构,包括表达式、语句、程序等。
3. 语义分析实验结果:成功检查语法分析后的语法树,确保语义正确。
4. 中间代码生成实验结果:成功将语义分析后的语法树转换为中间代码,为后续优化和目标代码生成提供基础。
5. 代码优化实验结果:成功对中间代码进行优化,提高程序性能。
6. 目标代码生成实验结果:成功将优化后的中间代码转换为特定目标机的汇编语言,为程序在目标机上运行做准备。
五、实验心得1. 编译原理是一门理论与实践相结合的课程,通过本次实验,我对编译程序的设计原理及实现技术有了更深入的了解。
编译原理熟悉实验报告
一、实验目的1. 理解编译原理的基本概念和流程;2. 掌握编译器的各个阶段及其实现方法;3. 熟悉编译器各个阶段中使用的算法和数据结构;4. 培养编程能力和问题解决能力。
二、实验内容1. 词法分析;2. 语法分析;3. 语义分析;4. 代码生成;5. 符号表;6. 中间代码生成。
三、实验步骤1. 词法分析(1)设计词法分析器:首先需要确定源程序中的词法单元,如标识符、关键字、运算符等。
然后,编写代码实现词法分析器,对源程序进行扫描,将词法单元转换成词法符号。
(2)实现词法分析器:使用C语言或Java等编程语言实现词法分析器,完成词法单元的识别和转换。
2. 语法分析(1)设计语法分析器:根据源程序的语言规范,设计语法分析器,实现语法规则的定义和匹配。
(2)实现语法分析器:使用递归下降分析法、LL(1)分析法、LR(1)分析法等实现语法分析器,对词法分析器输出的词法符号序列进行语法分析。
3. 语义分析(1)设计语义分析器:根据源程序的语言规范,设计语义分析器,实现语义规则的检查和类型检查。
(2)实现语义分析器:使用C语言或Java等编程语言实现语义分析器,完成语义规则的检查和类型检查。
4. 代码生成(1)设计代码生成器:根据源程序的语言规范,设计代码生成器,将抽象语法树转换成目标代码。
(2)实现代码生成器:使用C语言或Java等编程语言实现代码生成器,完成抽象语法树到目标代码的转换。
5. 符号表(1)设计符号表:在编译过程中,需要记录变量、函数等信息,设计符号表实现这些信息的存储和管理。
(2)实现符号表:使用C语言或Java等编程语言实现符号表,完成变量、函数等信息的存储和管理。
6. 中间代码生成(1)设计中间代码生成器:根据源程序的语言规范,设计中间代码生成器,将抽象语法树转换成中间代码。
(2)实现中间代码生成器:使用C语言或Java等编程语言实现中间代码生成器,完成抽象语法树到中间代码的转换。
四、实验结果与分析1. 词法分析器能够正确识别源程序中的词法单元,并将它们转换成词法符号。
语法分析器实验报告
杭州电子科技大学班级: 12052312 专业: 计算机科学与技术实验报告【实验名称】实验二语法分析一. 实验目的编写一个语法分析程序, 实现对词法分析程序所提供的单词序列的语法检查和结构分析。
二. 实验内容利用编程语言实现语法分析程序, 并对简单语言进行语法分析。
2.1 待分析的简单语言的语法用扩充的BNF表示如下:⑴<程序>: : =begin<语句串>end⑵<语句串>: : =<语句>{;<语句>}⑶<语句>: : =<赋值语句>⑷<赋值语句>: : =ID: =<表达式>⑸<表达式>: : =<项>{+<项> | -<项>}⑹<项>: : =<因子>{*<因子> | /<因子>⑺<因子>: : =ID | NUM | (<表达式>)2.2 实验要求说明输入单词串, 以“#”结束, 如果是文法正确的句子, 则输出成功信息, 打印“success”, 否则输出“error”。
例如:输入begin a:=9; x:=2*3; b:=a+x end #输出success!输入x:=a+b*c end #输出error测试以上输入的分析, 并完成实验报告。
2.3 语法分析程序的算法思想(1)主程序示意图如图2-1所示。
图2-1 语法分析主程序示意图(2)递归下降分析程序示意图如图2-2所示。
(3)语句串分析过程示意图如图2-3所示。
图2-3 语句串分析示意图图2-2 递归下降分析程序示意图(4)statement 语句分析程序流程如图2-4.2-5.2-6.2-7所示。
图2-4 statement 语句分析函数示意图 图2-5 expression 表达式分析函数示意图图2-7 factor 分析过程示意图三.个人心得一、 通过该实验, 主要有以下几方面收获: 二、 对实验原理有更深的理解。
编译原理课程实验报告(词法分析器及语法分析器)
编译原理实验报告班级:软件0501班学号:**********姓名:***词法分析器与语法分析器I. 问题描述设计、编制并调试一个词法分析子程序,完成识别语言单词的任务;设计、编制、调试一个语法分析程序,并用它对词法分析程序所提供的单词序列进行语法检查和结构分析。
ii. 设计简要描述界面需求:为了更加形象的模拟过程,此实验使用图形界面。
要求从图形界面上输入输入串,点击词法分析,可以将词法分析后识别的单词符号显示,点击语法分析,可以将语法分析的堆栈过程显示,并且显示结果(是否是符合文法的句子),清空则可以将所有置空。
功能分析:1、由用户输入输入串;2、用户点击“词法分析”,可以将词法分析后识别的单词符号显示。
3、用户点击语法分析,可以将语法分析的堆栈过程显示,并且显示结果(是否是符合文法的句子)4、用户点击清空,则将界面所有组件置为空思路描述:一、设计构想:本实验决定编写一个简易C语言的词法分析器和语法分析器。
使其能够识别while,if等关键字,可以判断赋值语句、条件语句、循环语句。
二、文法分析1、需要识别的关键字及其识别码有:关键字识别码关键字识别码关键字识别码main 0 - 11 ;22int 1 * 12 > 23char 2 / 13 < 24if 3 ( 14 >= 25else 4 ) 15 <= 26for 5 [ 16 == 27while 6 ] 17 != 28ID 7 { 18 ERROR -1NUM 8 } 19= 9 , 20+ 10 : 212、文法〈程序〉→ mai n()〈语句块〉〈语句块〉→{〈语句串〉}〈语句串〉→〈语句〉;〈语句串〉|〈语句〉;〈语句〉→〈赋值语句〉|〈条件语句〉|〈循环语句〉〈赋值语句〉→ ID =〈表达式〉;〈条件语句〉→ if〈条件〉〈语句块〉〈循环语句〉→ while〈条件〉〈语句块〉〈条件〉→(〈表达式〉〈关系符〉〈表达式〉)〈表达式〉→〈表达式〉〈运算符〉〈表达式〉|(〈表达式〉)|ID|NUM〈运算符〉→+|-|*|/〈关系符〉→<|<=|>|>=|=|!>转化为符号表示:S→ main() K|空K→ { C }C→Y;C |空Y→F | T | XF→ ID = BT→ if J KX→ while J KJ→( B G B )B→ B Z B |( B )| ID | NUMZ→ + | - | * | /G→< | <= | > | >= | == | !>表示含义:S:程序 K:语句块 C:语句串 Y:语句 F :赋值语句T:条件语句 X:循环语句 J:条件 B:表达式 I:项 Z :运算符G:关系符3、LL(1)分析表(1),求出first集及follow集:FIRST(S)={mian}FIRST(K)={{}FIRST(C)= FIRST(Y)= {ID,if,while,空};FIRST(Y)= FIRST(F)+ FIRST(T)+ FIRST(X)={ID,if,while};FIRST(F)={ID};FIRST(T)={if};FIRST(X)={while};FIRST(J)= FIRST(B)={};FIRST(B)={(,ID,NUM };FIRST(Z)={+,-,*,/}FIRST(G)={<,<= ,>,>=,==,!= };FOLLO W(S)={#};FOLLO W(K)={;};FOLLO W(C)={}};FOLLO W(Y)={;}FOLLO W(F)={;};FOLLO W(T)={;};FOLLO W(X)={;};FOLLO W(J)={{,;};FOLLO W(B)={+,-,*,/,),<,<= ,>,>=,==,!=,;};FOLLO W(B’)={+,-,*,/,),<,<= ,>,>=,==,!=,;};FOLLO W(Z)={(,ID,NUM };FOLLO W(G)={(,ID,NUM };(2)消除左递归,拆分文法关系并编号0、S→ 空1、S→ main() K2、K→ { C }3、C→Y;C4、C→空5、Y→ F6、Y→ T7、Y→ X8、F→ ID = B9、T→ if J K10、X→ while J K11、J→( B G B )12、 B→( B )B'13、B→ ID B'14、B→ NUM B'15、B'→ BZB B'16、B'→空17、Z→ +18、Z→ -19、Z→ *20、Z→ /21、 G→ <22、 G→ <=23、 G→ >24、 G→ >=25、 G→ ==26、 G→ !=(3)构造LL (1)分析表(注:在表中用上一步的编号表示所需要的产生式)iii. 详细设计描述 项目构架:各函数功能介绍:main 空 () { } ; = if while ID num + - * / < <= > >= == != # S 10 K 2 C 4 4 3 3 3 Y 6 7 5 F 8 T 9 X10 J11 B1213 14B '16 15 16 16 15 15 16 16 16 16 16 16 16 16 16 16 Z 17 18 19 20G21 22 232425261、word.wordList包(存储了关键字):word:此类是定义了存储关键字的结构:包括String型的关键字,和int型的识别符。
(完整)编译原理实验报告(词法分析器 语法分析器)
编译原理实验报告实验一一、实验名称:词法分析器的设计二、实验目的:1,词法分析器能够识别简单语言的单词符号2,识别出并输出简单语言的基本字。
标示符。
无符号整数.运算符.和界符。
三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号.2、程序流程图(1)主程序(2)扫描子程序3、各种单词符号对应的种别码五、实验内容: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、算术表达式语法分析程序的算法思想首先通过关系图法构造出终结符间的左右优先函数f(a),g(a)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
词法分析器、语法分析器试验报告一.程序思路1.词法分析器对输入的程序进行分析,将关键字,保留字与系统标识符分开,并对其属性进行说明。
建立数组,将单词读入,对单词的ASCII码进行判断,将在ASCII码值在一定区间进行区分(使用if语句来判断),分开来后,对其所在ASCII值区间的不同,给予以不同的属性(比如:系统保留字…),词法分析器完成后要能识别+,-,=等字符。
2.语法分析器对输入的程序语句进行分析。
对每个非终结点定义单个函数,定义了它的后继节点。
然后用一个构造来的函数,使定义的后继节点符合语法,否则报错。
二.源程序cifafenxi:#include"string.h"#include"iostream.h"#include"stdio.h"#include"conio.h"#define OK 1#define……#define……class word{ int ch;char code[50][50];public://word();int scan();int letter(int ch);int digit(int ch);int flag(int ch);int keyword(char * ch);int alpha(char * ch);int judge(char * ch);};int word::letter(int ch) //字符判断int word::alpha(char * ch) //字符属性设定int word::digit(int ch) //数字判断int word::flag(int ch){if(((ch>='0')&&(ch<='9'))||((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))||(ch=='+')||(ch=='-')||(ch=='*')||(ch=='/')||(ch=='=')||(ch=='==')||(ch=='%')||(ch=='<')||(ch=='>')||(ch=='(')||(ch==')'))return(1);else return(0);}int word::keyword(char * ch) //关键字判断{if((ch[0]=='i')&&(ch[1]=='n')&&(ch[2]=='t')&&(ch[3]==0)){ cout<<"\n"<<"The [int] is a keyword !"<<"\n"; return(INT); }if((ch[0]=='c')&&(ch[1]=='h')&&(ch[2]=='a')&&(ch[3]=='r')&&(ch[4]==0)){ cout<<"\n"<<"The [char] is a keyword !"<<"\n"; return(CHAR); }……………………………………………………{ cout<<"\n"<<"It is a keyword [if] !"<<"\n"; return(SWITCH); }return(0);}int word::judge(char * ch) //数字进位制判断if((ch[0]=='0')&&((ch[1]>='0')&&(ch[1]<='7'))){ cout<<"\n"<<"This is a OTC number, OTC value is"<<"["<<ch<<"] !"<<"\n";return(OTC); }……………………………………………………return(1);}int word::scan(){ int i=0,j=0,x=1;cout<<"Please input !"<<"\n"; ch=getc(stdin);while((ch==' ')||(ch==10))ch=getc(stdin);if((flag(ch)==NO)){ cout<<"\n"<<"ERROR"<<"\n"; return(ERROR); }ungetc(ch,stdin);while(x) { ch=getc(stdin); if((letter(ch)==YES)){ i=0; while (letter(ch)||digit(ch)) {code[j][i]=ch;ch=getc(stdin);i++; }code[j][i]=0;if(keyword(code[j])==0) {if(alpha(code[j]))cout<<"The identifier's ID is ["<<j<<"] !"<<"\n";} j++;if(ch==10)x=0; }if((digit(ch)==YES)){ i=0;while(digit(ch)||(ch=='x')||((ch>='a')&&(ch<='f'))){code[j][i]=ch;ch=getc(stdin);i++;}code[j][i]=0;judge(code[j]);cout<<"The number's ID is ["<<j<<"] !"<<"\n";j++;if(ch==10)x=0; }if(ch==':'){ i=0; code[j][i]=ch; ch=getc(stdin); if(ch=='='){ code[j][i++]=ch;cout<<"The ["<<"code[j]"<<" is (ASSIGN-OP, -) ."; j++; ch=getc(stdin); if(ch==10)x=0; }} switch(ch){case'+':{ i=0; code[j][i]=ch; code[j][i++]=0; cout<<"\n"<<"The ["<<char(ch)<<"] is a identifier (PLUS-OP, AND) ."<<"\n"; } //ch=getc(stdin); if(ch==59)ungetc(ch,stdin); }break;case'-':{ i=0; code[j][i]=ch; code[j][i++]=0; cout<<"\n"<<"The ["<<char(ch)<<"] is a identifier (MINUS-OP, SUB) ."<<"\n"; } //ch=getc(stdin);if(ch==59)ungetc(ch,stdin); }break;……………………………………………………break;case')':{ i=0; code[j][i]=ch; code[j][i++]=0; cout<<"\n"<<"The ["<<char(ch)<<"] is a identifier (RELATION-OP, RP) ."<<"\n";}// ch=getc(stdin); if(ch==59)ungetc(ch,stdin); }break;}if(ch==10)x=0;}return(OK);}int main(){char ch1;word word;while(ch1!='q'){word.scan();ch1=getch();}return(OK);}yufafenxi:#include"string.h"#include"iostream.h"#include"stdio.h"#include"conio.h"class word{ int ch;char code[MAX][MAX];public:// word ();int scan();int letter(int ch);int digit(int ch);int right(int ch);int keyword(char * ch);int alpha(char * ch);int judge(char * ch);int yufa(int ch);int match(int ch);int word _e();int word _t();int word _f();int word _s();int word _c();};int word::letter(int ch)……int word::alpha(char * ch)……int word::digit(int ch)……int word::right(int ch)……int word::match(int ch){ int i=0;int j=0;int x=1;ch=getc(stdin);while((ch==' ')||(ch==10))ch=getc(stdin);if((isright(ch)==NO)){ cout<<"\n"<<"ERROR"<<"\n"; return(ERROR); }ungetc(ch,stdin);while(x){ ch=getc(stdin); if((isletter(ch)==YES)) { i=0; while (isletter(ch)||isdigit(ch)){ code[j][i]=ch; ch=getc(stdin);i++; }code[j][i]=0;ungetc(ch,stdin);if(ch==10)x=0;j++;return(iskeyword(code[j-1]));}if((isdigit(ch)==YES)){ i=0; while(isdigit(ch)||(ch=='x')||((ch>='a')&&(ch<='f'))){code[j][i]=ch;ch=getc(stdin);i++; }code[j][i]=0;ungetc(ch,stdin); j++;if(ch==10)x=0;return(judge(code[j-1])); } if(ch==':'){ i=0; code[j][i]=ch; ch=getc(stdin); if(ch=='='){ code[j][i++]=ch; code[j][i++]=0; j++; return(ASSIGN);} }switch(ch){ case'+':{ i=0; code[j][i]=ch; code[j][i++]=0; return(AND); }case'-':{ i=0; code[j][i]=ch; code[j][i++]=0; return(SUB); } ……………………………………………………} i f(ch==10)x=0;}return(OK);}int word:: word _t()……int word:: word _f()……int word::word_s()……int main(){char ch1;word word;while(ch1!='q'){clrscr();cout<<"Please Input !"<<"\n";lookhead=word.scan();word.fun_s();ch1=getch();}return(OK);}三.小节——心得体会这次小程序的编写让我对编译程序的工作有了个大概的了解,让我的编译程序的原理及设计有了长足的进步,使我明白和更好的体会到了编译程序的作用。