c语言编译原理预测分析法实验报告
编译原理 实验报告

编译原理实验报告编译原理实验报告引言编译原理是计算机科学中的重要课程,它研究的是如何将高级语言程序转化为机器语言程序的过程。
在本次实验中,我们学习了编译原理的基本概念和技术,并通过实践来加深对这些概念和技术的理解。
本报告将对我们在实验中遇到的问题、解决方案以及实验结果进行总结和分析。
实验目的本次实验的主要目的是设计并实现一个简单的编译器,能够将类C语言的源代码翻译成目标代码。
通过这个实验,我们可以更好地理解编译器的工作原理,掌握编译器设计的基本方法和技术。
实验过程在实验中,我们首先对给定的类C语言的语法进行了分析,并根据语法规则设计了相应的语法分析器。
然后,我们使用了自顶向下的递归下降分析法来实现语法分析器。
在实现语法分析器的过程中,我们遇到了一些问题,例如如何处理语法规则中的左递归、如何处理语法规则中的优先级和结合性等。
通过仔细研究相关的文献和资料,我们成功地解决了这些问题,并完成了语法分析器的设计和实现。
接下来,我们对语法分析器进行了测试,并对测试结果进行了分析。
通过测试,我们发现语法分析器在处理简单的源代码时能够正确地识别出语法错误,并给出相应的错误提示。
然而,在处理复杂的源代码时,语法分析器可能会出现一些错误,例如无法正确地处理嵌套的语法结构、无法正确地处理运算符的优先级和结合性等。
为了解决这些问题,我们对语法分析器进行了改进,并进行了多次测试,最终得到了令人满意的结果。
实验结果通过本次实验,我们成功地设计并实现了一个简单的编译器,能够将类C语言的源代码翻译成目标代码。
在实验中,我们对编译器的工作原理有了更深入的了解,掌握了编译器设计的基本方法和技术。
同时,我们也发现了一些问题,并通过不断地改进和测试,最终得到了令人满意的结果。
结论编译原理是一门重要的计算机科学课程,它研究的是如何将高级语言程序转化为机器语言程序的过程。
通过本次实验,我们对编译原理的基本概念和技术有了更深入的了解,并通过实践来加深了对这些概念和技术的理解。
编译原理实验报告(C语言)

else if(strcmp(word,"if")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',12,')'); else if(strcmp(word,"else")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',13,')'); else if(strcmp(word,"switch")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',14,')'); else if(strcmp(word,"case")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',15,')'); else if(strcmp(word,"for")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',16,')'); else if(strcmp(word,"do")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',17,')'); else if(strcmp(word,"while")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',18,')'); else if(strcmp(word,"goto")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',19,')'); else if(strcmp(word,"continue")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',20,')'); else if(strcmp(word,"break")==0) fprintf(out,"%c%c%s%c,%d%c\n",'(','"',word,'"',21,')');
编译原理实验报告

编译原理实验报告一、实验目的本次编译原理实验的主要目的是通过实践加深对编译原理中词法分析、语法分析、语义分析和代码生成等关键环节的理解,并提高实际动手能力和问题解决能力。
二、实验环境本次实验使用的编程语言为 C/C++,开发工具为 Visual Studio 2019,操作系统为 Windows 10。
三、实验内容(一)词法分析器的设计与实现词法分析是编译过程的第一个阶段,其任务是从输入的源程序中识别出一个个具有独立意义的单词符号。
在本次实验中,我们使用有限自动机的理论来设计词法分析器。
首先,我们定义了单词的种类,包括关键字、标识符、常量、运算符和分隔符等。
然后,根据这些定义,构建了相应的状态转换图,并将其转换为程序代码。
在实现过程中,我们使用了字符扫描和状态转移的方法,逐步读取输入的字符,判断其所属的单词类型,并将其输出。
(二)语法分析器的设计与实现语法分析是编译过程的核心环节之一,其任务是在词法分析的基础上,根据给定的语法规则,判断输入的单词序列是否构成一个合法的句子。
在本次实验中,我们采用了自顶向下的递归下降分析法来实现语法分析器。
首先,我们根据给定的语法规则,编写了相应的递归函数。
每个函数对应一种语法结构,通过对输入单词的判断和递归调用,来确定语法的正确性。
在实现过程中,我们遇到了一些语法歧义的问题,通过仔细分析语法规则和调整函数的实现逻辑,最终解决了这些问题。
(三)语义分析与中间代码生成语义分析的任务是对语法分析所产生的语法树进行语义检查,并生成中间代码。
在本次实验中,我们使用了四元式作为中间代码的表示形式。
在语义分析过程中,我们检查了变量的定义和使用是否合法,类型是否匹配等问题。
同时,根据语法树的结构,生成相应的四元式中间代码。
(四)代码优化代码优化的目的是提高生成代码的质量和效率。
在本次实验中,我们实现了一些基本的代码优化算法,如常量折叠、公共子表达式消除等。
通过对中间代码进行分析和转换,减少了代码的冗余和计算量,提高了代码的执行效率。
编译原理实验报告(C语言)

编译原理实验报告实验项目1:词法分析程序实验一、实验的目的与任务:编译原理是计算机类专业特别是计算机软件专业的一门重要专业课。
设置该课程的目的在于系统地向学生讲述编译系统的结构、工作流程及编译程序各组成部分的设计原理和实现方法,使学生通过学习既掌握编译理论和方法方面的基本知识,也具有设计、实现、分析和维护编译程序等方面的初步能力。
编译原理是一门理论性和实践性都比较强的课程。
进行上机实验的目的是使学生通过完成上机实验题目加深对课堂教学内容的理解。
同时培养学生实际动手能力。
编译实验由三个独立实验组成,按照由浅入深进行排列,希望通过本实验使学生更深学习并理解编译的主要过程和相关方法。
词法分析的目的是将输入的源程序进行划分,给出基本符号(token)的序列,并掠过注解和空格等分隔符号。
基本符号是与输入的语言定义的词法所规定的终结符。
本实验要求学生编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续进行)二、题目分析1.这里采用C语言编写的源程序作为词法分析程序的输入数据,输入数据保存在“in.txt”记事本中,将分析结果存在“out.txt”记事本中。
词法分析器的源代码使用C语言编写。
2.下面就词法分析程序中的主要变量进行说明:主函数main():打开要分析的C语言源程序,若不能正确打开,则报错。
先从源程序中读入一个字符ch,然后进行如下处理:1、cp消耗掉空格,制表符,换行符后,cp数组复位,开始检测cp;2、数字检测,对照符号表输出,若匹配成功,则返回序号;3、字符串检测, 对照符号表输出,若匹配成功,则返回序号;4、基本保留字检测,对照符号表输出,若匹配成功,则返回序号;5、运算符检测,对照符号表输出,若匹配成功,则返回序号;注意这里碰到‘/’时,要判断后面是否跟着是注释语句。
编译原理预测分析实验报告

编译原理实验报告实验题目:预测分析法学院:计算机与通信工程学院专业班级:计算机科学与技术08—2班姓名:学号:预测分析法一、实验目的二、实验要求1、通过该课程设计要学会用消除左递归的方法来使文法满足进行确定自顶向下分析的条件。
2、学会用C/C++高级程序设计语言来设计一个LL(1)分析法的语法分析器;3、通过该课程设计,加深对语法分析理论的理解,培养动手实践的能力。
三、实验代码:#include <stdio.h>#include <tchar.h>#include <string.h>int main(int argc, char* argv[]){char syn[15]; //语法栈int top; //栈顶指针char lookahead; //当前单词char exp[50]; //表达式区int m =0; //表达式指针char s[4][5]={"d","+","*","("}; //表中有空白的符号char string[3]={'E','T','F'}; //表中有同步记号的的非终结符int ll1[7][6]={{1,0,0,1,9,9}, //LL(1)分析表,9表示同步记号,第6行是#,第7行是){0,2,0,0,3,3},{4,9,0,4,9,9},{0,6,5,0,6,6},{8,9,9,7,9,9},{12,12,12,12,12,10},{13,13,13,13,11,13}};int i,j; //表行和列int code; //表项printf("************************语法分析器**********************\n");printf("请输入合法字符串:\n");scanf("%s",exp);top=1;lookahead=exp[m++];syn[0]='#';syn[1]='E';printf("***********************预测分析表*********************\n"); printf("\ti\t *\t +\t (\t )\t #\n");printf(" E\tE—>TE'\t\t\tE—>TE'\n");printf(" E'\t\t\tE'—>+TE'\t E'—>ε\n");printf(" T\tT—>FT'\t\t\tT—>FT'\t\n");printf(" T'\t\tT'—>*FT'\t\t T'—>ε\t\n");printf(" F\tF—>d\t\t\tF—>(E)\n\n");printf("调用规则顺序:\n");while(1){switch(syn[top]) //行{case 'E':i=0;break;case 'e':i=1;break;case 'T':i=2;break;case 't':i=3;break;case 'F':i=4;break;case '#':i=5;break;case ')':i=6;break;}switch(lookahead) //列{case 'd':j=0;break;case '+':j=1;break;case '*':j=2;break;case '(':j=3;break;case ')':j=4;break;case '#':j=5;break;}code=ll1[i][j];if(code==10){ printf("语法分析结束\n");// break;}else{switch(code){case 0:{// printf("出错,用户多输入了%s,跳过%s\n",s[j],s[j]);if(j==0){//lookahead=exp[m++];lookahead=exp[m++];}elselookahead=exp[m++];break;}case 1:{printf("E →TE′\n");syn[top]='e';syn[top+1]='T';top++;break;}case 2:{printf("E′→+TE`\n");syn[top+1]='T';top++;lookahead=exp[m++];break;}case 3:{printf("E′→ε\n");syn[top]='\0';top--;break;}case 4:{printf("T →FT′\n");syn[top]='t';syn[top+1]='F';top++;break;}case 5:{printf("T′→* FT′\n");syn[top+1]='F';top++;lookahead=exp[m++];break;}case 6:{printf("T′→ε\n");syn[top]='\0';top--;break;}case 7:{printf("F →(E)\n");syn[top]=')';syn[top+1]='E';top++;lookahead=exp[m++];break;}case 8:{printf("F →d\n");syn[top]='\0';top--;lookahead=exp[m++];lookahead=exp[m++];break;}case 9:{printf("弹栈,弹出非终结符%c,用户少输入了一个d\n",string[i/2]);syn[top]='\0';top--;break;}case 11:{syn[top]='\0';top--;lookahead=exp[m++];break;}case 13:{printf("弹栈,弹出终结符) ,用户少输入了一个右括号\n");syn[top]='\0';top--;break;}}}}return 0;}实验运行结果:三、总结预测分析法主要是对预测分析表的输出,关键是要理解语法内容和结构。
编译原理课程设计报告-预测分析程序的设计

1课程设计任务书学生姓名: 专业班级:指导教师: 工作单位:题目: 预测分析程序的设计初始条件:1.程序设计语言:主要使用C语言的开发工具, 或者采用LEX、YACC等工具, 也可利用其他熟悉的开发工具。
算法: 可以根据《编译原理》课程所讲授的算法进行设计。
2.要求完成的主要任务: (包括课程设计工作量及其技术要求,说明书撰写等具体要求)3.明确课程设计的目的和重要性, 认真领会课程设计的题目, 读懂课程设计指导书的要求, 学会设计的基本方法与步骤, 学会如何运用前修知识与收集、归纳相关资料解决具体问题的方法。
严格要求自己, 要独立思考, 按时、独立完成课程设计任务。
4.课设任务: 对教材P94中的上下文无关文法, 实现它的预测分析程序, 给出符号串i+i*i的分析过程。
(参考教材P93~96)5.主要功能:对于这个给的LL(1)文法, 假设所有非终结符号P的FIRST集合和FOLLOW集合都是已知的, 构造其预测分析表, 程序显示输出预测分析表, 同时用这个预测分析程序对输入串进行分析, 并给出了栈的变化过程。
进行总体设计, 详细设计:包括算法的设计和数据结构设计。
系统实施、调试, 合理使用出错处理程序。
设计报告: 要求层次清楚、整洁规范、不得相互抄袭。
正文字数不少于0.3万字。
包含内容:①课程设计的题目。
②目录。
③正文: 包括引言、需求分析、总体设计及开发工具的选择, 设计原则(给出语法分析方法及中间代码形式的描述、文法和属性文法的设计), 数据结构与模块说明(功能与流程图)、详细的算法设计、软件调试、软件的测试方法和结果、有关技术的讨论、收获与体会等。
④结束语。
⑤参考文献。
⑥附录: 软件清单(或者附盘)。
时间安排:消化资料、系统调查、形式描述1天系统分析、总体设计、实施计划3天撰写课程设计报告书1天指导教师签名: 2010年 6月 11日系主任(或责任教师)签名: 2010年6月11日目录1引言 (5)2需求分析 (6)2.1问题的提出 (6)2.2问题的解决 (6)2.3解决步骤 (6)3总体设计 (7)3.1概要设计 (7)3.1.1设计原理 (7)3.1.2构造LL(1)分析表 (8)3.2详细设计 (12)3.2.1程序流程图 (12)3.2.2设计要求 (14)3.2.3设计原理 (14)3.2.3.1FIRST(X)(X∈VN VT)的构造 (14)3.2.3.2函数getFIRST(α) (α=X1X2X3…Xn)的构造. 143.2.3.3FOLLOW(A) (A∈VN)的构造 (15)3.2.3.4分析表M【A,a】的构造 (15)3.2.3.5匹配过程的实现 (15)3.3程序设计 (16)3.3.1总体方案设计 (16)3.3.2各模块的实现 (16)4开发工具的选择 (25)5程序测试 (25)6有关技术的讨论 (27)7收获与体会 (28)8参考文献 (29)1引言一个编译程序在对某个源程序完成了词法分析工作之后, 就进入了语法分析阶段, 分析检查源程序是否语法上正确的程序, 并生成相应的内部中间表供下一阶段使用。
编译原理实验—预测分析器

strcat(VNT[t].VtoT,VNT[flag].VtoT);
}
for(j=0;j<s1;j++) //第三种情况的后半部分
for(k=0;k<length1;k++)
{
flag=0;
if(G[i].Right[j]==NT[k].Vnt&&Capital(G[i].Right[j+1]))
else return 0;
}
void FoldFirst(csc G[],db VNT[],int length)//将左部相同的产生式的非终结符合并起来 {
int i,j; for(i=0;i<length;i++)
for(j=i+1;j<length;j++) if(VNT[i].VN==VNT[j].VN&&VNT[i].VtoT[0]!=0&&VNT[j].VtoT[0]!=0) { strcat(VNT[i].VtoT,VNT[j].VtoT); VNT[j].VN='0'; }
if(flag==1) str[t++]=NT[i].Vt[j];
} for(j=0;j<strlen(VNT[i].VtoT);j++) //加入 Follow 中的非终结符 {
flag=1; for(k=0;k<t;k++)
} for(i=0;i<length;i++) {
s1=strlen(G[i].Right); for(k=0;k<length1;k++) //第三种情况的前半部分
预测分析程序实验报告

预测分析程序实验报告题⽬:预测分析法⼀、实验⽬的1、通过实验要学会⽤消除左递归和消除回溯的⽅法来使⽂法满⾜进⾏确定⾃顶向下分析的条件;2、学会⽤C/C++⾼级程序设计语⾔编写⼀个LL(1)分析法程序⼆、实验内容及要求LL(1)预测分析程序的总控程序在任何时候都是按STACK栈顶符号X和当前的输⼊符号a做哪种过程的。
对于任何(X,a),总控程序每次都执⾏下述三种可能的动作之⼀:(1)若X = a =‘#’,则宣布分析成功,停⽌分析过程。
(2)若X = a ‘#’,则把X从STACK栈顶弹出,让a指向下⼀个输⼊符号。
(3)若X是⼀个⾮终结符,则查看预测分析表M。
若M[A,a]中存放着关于X的⼀个产⽣式,那么,⾸先把X弹出STACK栈顶,然后,把产⽣式的右部符号串按反序⼀⼀弹出STACK栈(若右部符号为ε,则不推什么东西进STACK栈)。
若M[A,a]中存放着“出错标志”,则调⽤出错诊断程序ERROR。
1、给定⽂法S -> a | b | (T)T -> SH | dH -> ,SH | ε2、该⽂法对应的预测分析表3、编写预测分析程序对句⼦进⾏分析三、试验程序设计说明1、相关函数说明分析栈可以采取许多的存储⽅法来设计,在这⾥采⽤的顺序栈。
根据预测分析原理,LL(1)分析程序的实现关键在于分析栈和分析表是采⽤何种数据结构来实现。
分析表是⼀个矩阵,当我们要调⽤分析表来分析时,就根据栈顶的⾮终结符和当前输⼊的终结符来决定执⾏哪种过程。
具体设计思想如下:printStack()输出分析栈内内容;printinputString()输出⽤户输⼊的字符串;Pop()弹出栈顶元素;Push()向栈内添加⼀个元素;Search()查找⾮终结符集合VT 中是否存在输⼊的⾮终结符;yuCeFenXi()进⾏输⼊串的预测分析的主功能函数;M(char A, char a)查看预测分析表M[A,a]中是否存在相应产⽣式。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{
printf("%c",stack[i]);
}
printf("\t");
for ( i = flag-1 ; str[i]!='$' ; i++ )
{
printf("%c",str[i]);
}
if(flag2==1)
char stack[20]={'#','S'};//栈赋初值
int top = 1 ;//设置栈顶指针
char X = ' ' ;//存储栈顶字符
init();
A=str[0];
printf("\t步数\t分析栈\t输入串\t所用规则\n");//在屏幕上输出列表标题
while ( 1 )
{
printf("\n\t(%d)\t",++j);//输出当前执行步数
}
else if (isT(X))//是终结符
{
A=str[flag++];
}
else if (isNT(X))//是否是非终结符
{
flag2=1;
//逆序入栈
for( i = strlen( p[ M[ lin(X) ][col(A)] ] ) - 1; i >= 0; i--)
{
stack[++top] = *(p[M[lin(X)][col(A)]] + i ) ;
经过此实验使我更加深刻的理解预测分析程序的基本原理和过程。从程序中可以看出,该程序由一张预测分析表,一个先进后出分析栈和一个总控程序三部分组成,实现起来较为繁琐,但分析效率较高。
程序输入/输出示例:
输入:一个以#结束的符号串:例如:(a,a)#
输出:
步数 分析栈 输入串 所用规则
(1) #S (a,a))#2
源程序:
//LL(1)预测分析控制程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char str[100]; //存储待分析的句子
exit(0) ;
}
int col(char c)
{
for (int i=0; i<(int)strlen(T); i ++ )
{
if (c == T[i])return i;
}
printf("Error in col()>%c\n",c);
exit(0);
}
bool isNT(char c) //是否是非终结符
}
}
else
{
printf("Error in main()>%c\n",X);
exit(0);
}
}
}
int lin(char c)
{
for(int i = 0; i < (int)strlen(NT); i ++ )
{
if (c == NT[i])
{
return i ;
}
}
printf("Error in lin()>%c\n",c);
/*3.T→SW */"SW",
/*4. W→,SW */",SW",
/*5.W→ε; */""
};
//设M[i][j]=x,通过p[M[i][j]]=p[x]获取右部符号串。
const int M[][6] = {
/* a ^ ( ) , # */
/*S*/{ 0, 1, 2, -1, -1, -1 },
{
printf("\t%d",M[ lin(X) ][col(A)]);
flag2=0;
}
//出栈
X = stack[top--] ;
if (X=='#')//是结束符
{
if (X==A)//是结束符
{
printf("\tAcc\n");
}
else printf("\tERROR\n");
break;
{
for (int i = 0; i < (int)strlen(NT); i ++ )
{
if (c==NT[i])
return true;
}
return false;
}
bool isT(char c) //是否是终结符(不包括'#')
{
for (int i = 0; i < (int)strlen(T) - 1; i ++ )
编译原理
实
验
报
告
目的要求
1.构造文法的语法分析程序,要求采用预测分析法对输入的字符串进行语法分析。
2.加深对预测分析LL(1)分析法的理解和掌握。
实验内容
对文法G进行语法分析,文法G如下所示:
*0.S→a */
*1.S→^
*2.S→(T)
*3.T→SW *
*4.W→,SW
*5.W→ε;
并对任给的一个输入串进行语法分析检查。程序要求能对输入串进行预测分析,能判别程序是否符合已知的语法规则,如果不符合(编译出错),则输出错误信息。
/*T*/{ 3, 3, 3, -1, -1, -1 },
/*W*/{ -1, -1,-1, 5, 4, -1 }
};
void init()//输入待分析的句子
{
printf("请输入待分析的句子(以$结束):\n");
scanf("%s",str);
}
int lin(char c);//非终结符转换为行号
int col(char c);//终结转换为列号
bool isNT(char c);//isNT判断是否是非终结符
bool isT(char c);//isT判断是否是终结符。
void main(void)
{
int i,j=0;
int flag=1,flag2=0;
char A;//设置指示句子的当前字符
{
if (c == T[i])
{
return true;
}
}
return false;
}
程序运行截图
当输入为(a,a)#$时
当输入为(a,a)))#$时
经过分析,实验运行的结果与期望的结果相同,故知程序正确。
实验总结
这次的预测分析程序实验同样要求文法必须是LL(1)文法,相对来说比上次的递归下降分析程序难些。我是参照了别人的程序,然后经过自己的理解和修改,把课本上的例4.10中文法作为例子设计出了预测分析程序。在实验当中,由于用到了类似栈的处理,出现了不少的错误。不过经过不断的调试和对其基本原理的理解,总算基本解决了,并且使输出显示的比较详细,显示了对输入块的分析过程。
const char T[ ] = "a^(),#"; //终结符,分析表的列符
const char NT[ ] = "STW"; //非终结符,分析表的行符
/*指向产生式右部符号串*/
const char *p[] = {
/*0.S→a */"a",
/*1. S→^*/ "^",
/*2.S→பைடு நூலகம்T) */"(T)",