编译原理课程设计题目 (1)
编译原理试题及答案
编译原理试题及答案一、选择题1. 编译器的主要功能是什么?A. 程序设计B. 程序翻译C. 程序调试D. 数据处理答案:B2. 下列哪一项不是编译器的前端处理过程?A. 词法分析B. 语法分析C. 语义分析D. 代码生成答案:D3. 在编译原理中,词法分析器的主要作用是什么?A. 识别程序中的关键字和标识符B. 将源代码转换为中间代码C. 检查程序的语法结构D. 确定程序的运行环境答案:A4. 语法分析通常采用哪种方法?A. 自顶向下分析B. 自底向上分析C. 正则表达式匹配D. 直接解释执行答案:B5. 语义分析的主要任务是什么?A. 检查程序的语法结构B. 检查程序的类型安全C. 识别程序中的变量和常量D. 将源代码转换为机器代码答案:B二、简答题1. 简述编译器的工作原理。
答案:编译器的工作原理主要包括以下几个步骤:词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成。
词法分析器将源代码分解成一系列的词素;语法分析器根据语法规则检查词素序列是否合法;语义分析器检查程序的语义正确性;中间代码生成器将源代码转换为中间代码;代码优化器对中间代码进行优化;最后,目标代码生成器将优化后的中间代码转换为目标机器代码。
2. 什么是词法分析器,它在编译过程中的作用是什么?答案:词法分析器是编译器前端的一个组成部分,负责将源代码分解成一个个的词素(tokens),如关键字、标识符、常量、运算符等。
它在编译过程中的作用是为语法分析器提供输入,是编译过程的基础。
三、论述题1. 论述编译器中的代码优化技术及其重要性。
答案:代码优化是编译过程中的一个重要环节,它旨在提高程序的执行效率,减少资源消耗。
常见的代码优化技术包括:常量折叠、死代码消除、公共子表达式消除、循环不变代码外提、数组边界检查消除等。
代码优化的重要性在于,它可以显著提高程序的运行速度和性能,同时降低程序对内存和处理器资源的需求。
四、计算题1. 给定一个简单的四则运算表达式,请写出其对应的逆波兰表达式。
编译原理设计题目
编译原理设计题目设计原则:1.使用了《编译原理》中的某些内容,如原理、概念等;2.具有完整性,表现或演示了某种完整的功能;3.实用性,有一定的应用价值。
设计目的:花了足够的时间,做了一定量的工作,从而使得水平提高。
设计语言:任意熟悉的开发环境。
设计步骤:1.选好题目2.思考你将要把软件编成什么模样?3.写出需求分析4.开始设计5.测试第一大类:充分利用《编译原理》1.与表达式有关的内容:●表达式计算器:这是一款算术表达式计算程序,用户通过输入表达式达到计算的目的,可代替目前普遍使用的计算器。
使用了编译原理中的词法分析、算符优先分析等。
根据功能的不同可分为:⏹无符号整数表达式计算器:输入无符号整数表达式,输出结果。
难度:较难。
工作量:中等。
⏹整数表达式计算器:考虑负数。
难度:较难。
工作量:中等。
⏹定点实数表达式计算器:难度:较难。
工作量:中等。
⏹通用表达式计算器:考虑1.23e-2的形式输入。
难度:难。
工作量:中等。
●函数表达式计算程序:这是一款能计算函数值的实用程序,用户输入含有自变量x的函数表达式被电脑接受后,可接着输入自变量x的值,电脑输出函数值y的值。
用户可以是数学、物理等教师,他们可以在上课教授与函数有关的课程时进行课堂演算,也可以在备课时验证数据;用户也可以是工程技术人员和学生。
使用了词法分析、算符优先分析。
根据功能的不同可以分为:⏹多项式函数计算程序:只处理多项式函数,如f(x)=x^3+x^2+5等。
难度:较难。
也可设计成其他专用函数计算程序,如幂函数计算、三角函数计算等。
但要避免出现不同用,如不要设计成仅能处理f(x)=2^x的幂函数,因为这样的函数利用普通编程就能实现,无法体现编译原理。
工作量:中等。
⏹通用初等函数计算程序:能处理所有的初等函数的计算。
如f(x)=3*sin(x/2+3.1415)+x^2等。
难度:难(因为涉及到函数名称和参数的识别问题)。
工作量:较大。
⏹二元或多元函数的计算:请参考立体解析几何中相关方程。
编译原理课程设计LL(1)文法
本次课程设计主要是介绍LL(1)文法的一般原理,根据给定的一文法编制调试LL(1)文法语法分析程序,以便对任意输入的符号串进行分析。
本次课程设计的目的主要是加深对预测分析LL(1)文法语法分析的理解,加深对自顶向下语法分析方法的认识。
具体如下:1、对语法规则有明确的定义;2、编写的分析程序能够对给定文法进行正确的语法分析;3、对输入给定的文法,手工计算First、Follow集合以及各产生式的Select 集合,再根据Select集合构造出预测分析表;4、对于输入串,应能根据预测分析表判断识别该输入串是否为给定文法的句子;5、对于遇到的错误,给出简单的错误信息提示,保证能够顺利完成语法分析过程。
前言------------------------------------------------------------- Ⅰ目录------------------------------------------------------------- Ⅱ一、系统分析------------------------------------------------------ 11.1 判断LL(1)文法---------------------------------------------- 11.2 构造预测分析表---------------------------------------------- 1二、系统设计------------------------------------------------------ 22.1 基本设计---------------------------------------------------- 22.2 程序流程图-------------------------------------------------- 2三、系统实现------------------------------------------------------ 33.1 程序主要函数------------------------------------------------ 33.2 程序主要代码------------------------------------------------ 3四、系统测试------------------------------------------------------ 7五、总结---------------------------------------------------------- 8 参考文献---------------------------------------------------------- 9一、系统分析有文法G[E]:E->TG T->FSG->+TG|ε S->*FS|ε F->(E)|i 1.1 判断LL(1)文法当我们需选用自顶向下分析技术时,首先必须判别所给文法是否是LL(1)文法,分析所给文法可知文法中不含左公因子,也不存在左递归,因而再对给定文法计算First 集、Follow 集以及Select 集,对于求出的每个产生式的Select 集,看对于同一个左部非终结符是否存在交集,如果它们的交为空则表示所给文法是LL(1)文法,否则不是L(1)文法。
编译原理课程实验题目
编译原理实验题目编译原理的课程实验既是培养学生理论联系实际的必要手段也是检验我们教学理念的贯彻与实现、检查教学效果、让学生展示能力的重要途径。
为了达到上述目的,作为编译原理课程的上机实验,最好是能完成一个小型语言的基本编译系统,但这需要有较好的实验条件特别是较多的实验学时(理想的情形是专门配置一个两到三周的课程设计)的支撑。
对于一个只有56学时的编译原理课程的上机实验(仅为12学时),构造一个小型语言的完整的编译系统显然是不现实的;为最大程度达到教学目的,经由课程组的认真研究,将本课程实验分解为两个上机实验:1、词法分析器编制实验;2、语法制导的三地址代码生成器编制实验(第2个实验又可分解为自顶向下的语法分析器的设计与实现和三地址代码生成器的设计与实现两个实验)。
通过这两个程序的编制,使学生学会和体验构造一个微型编译系统的基本框架的主要工作。
实验一:词法分析程序的设计与实现一.实验目的基本掌握计算机语言的词法分析程序的开发方法。
二.实验内容编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。
三.实验要求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)*运算符和分隔符+ - * / > < = ( ) ;关键字if then else while do2.根据状态图,设计词法分析函数int scan( ),完成以下功能:1)从键盘读入数据,分析出一个单词。
2)返回单词种别(用整数表示),3)返回单词属性(不同的属性可以放在不同的全局变量中)。
编译原理课程设计选题
编译原理课程设计选题一、教学目标本节课的教学目标是使学生掌握编译原理的基本概念、原理和方法,培养学生运用编译原理解决实际问题的能力。
具体目标如下:1.知识目标:(1)了解编译原理的基本概念,如编译器、解释器、源程序等;(2)掌握编译过程的各个阶段,如词法分析、语法分析、语义分析、中间代码生成、目标代码生成等;(3)熟悉常见编程语言的编译原理及其特点。
2.技能目标:(1)能够使用编译器或解释器对简单程序进行编译或解释;(2)能够运用编译原理分析程序的正确性和性能问题;(3)具备编写简单的编译器或解释器的能力。
3.情感态度价值观目标:(1)培养学生对编译原理的兴趣和好奇心,激发学生主动学习的动力;(2)培养学生团队协作、沟通交流的能力,提高学生解决实际问题的能力;(3)培养学生追求真理、勇于创新的精神风貌。
二、教学内容本节课的教学内容主要包括以下几个部分:1.编译原理概述:介绍编译器、解释器、源程序等基本概念,使学生了解编译原理的应用范围和重要性。
2.编译过程及其各个阶段:详细讲解编译过程的词法分析、语法分析、语义分析、中间代码生成、目标代码生成等阶段,使学生掌握编译过程的基本方法。
3.常见编程语言的编译原理:分析C、Java、Python等常见编程语言的编译原理及其特点,使学生了解不同编程语言的编译机制。
4.编译器设计实例:以一个简单的编译器为例,讲解编译器的实现方法和技巧,让学生具备编写简单编译器的能力。
三、教学方法为了提高教学效果,本节课将采用以下教学方法:1.讲授法:教师讲解编译原理的基本概念、原理和方法,引导学生掌握知识要点。
2.案例分析法:通过分析具体编程语言的编译实例,使学生了解编译原理在实际应用中的作用。
3.实验法:安排课后实验,让学生动手编写简单的编译器或解释器,提高学生的实践能力。
4.讨论法:学生分组讨论,鼓励学生提出问题、分享心得,培养学生的团队协作和沟通能力。
四、教学资源为了支持教学内容和教学方法的实施,本节课将采用以下教学资源:1.教材:《编译原理》(作者: Alfred V. Aho et al.);2.参考书:《计算机编译原理》(作者:陈意云);3.多媒体资料:PPT课件、视频教程等;4.实验设备:计算机、编程环境等。
编译原理课程设计-LL1文法分析器设计C++语言实现
集美大学计算机工程学院编译原理课程设计报告选题名称:LL(1)文法分析院(系):计算机工程学院专业:计算机科学与技术班级:计算1412指导教师:付永刚学年学期:2016 ~ 2017 学年第 2 学期2017 年06 月29 日摘要:选题要求:根据某一文法编制调试LL(1) 文法语法分分析程序,以便对任意输入的符号串进行分析。
本次课程设计的目的主要是加深对预测分析LL(1)文法语法分析法的理解。
具体如下:1、对语法规则有明确的定义;2、编写的分析程序能够对给定文法进行正确的语法分析;3、对输入给定的文法,手工计算FIRST、FOLLOW集合和select集合,应能判断识别是否为给定文法的句子,并给出推导过程。
4、对输入给定的文法,由程序自动构造FIRST、FOLLOW集合。
5、对于遇到的语法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成语法分析过程。
关键词:语法分析;FIRST集合;FOLLOW集合;分析表一、设计内容及要求(1) 基于PL/0语言,通过编程判断该文法是否为LL(1)文法;(2)计算出文法的First() Follow()(3)构造相应文法的预测分析表(4)对某个输入句子进行语法分析二、实现原理1.LL(1)文法LL(1)文法是一类可以进行确定的自顶向下语法分析的文法。
就是要求描述语言的文法是无左递归的和无回溯的。
根据LL(1)文法的定义,对于同一非终结符A的任意两个产生式A:=a和A:=b,都要满足:SELECT(A:=a )∩SELECT(A:=b)=Ø。
(1)文法的左递归当一个文法是左递归文法时,采用自顶向下分析法会使分析过程进入无穷循环之中。
所以采用自顶向下语法分析需要消除文法的左递归性。
文法的左递归是指若文法中对任一非终结符A有推导AÞA…,则称该文法是左递归的。
左递归又可以分为直接左递归和间接左递归。
●直接左递归若文法中的某一产生式形如A→Aα,α∈V*,则称该文法是直接左递归的。
编译原理试题及答案
编译原理试题及答案
试题:
1. 解释编译原理的定义,同时给出编译器的作用。
2. 简要描述编译过程中的四个基本步骤。
3. 解释词法分析器的功能和作用。
4. 解释语法分析器的功能和作用。
答案:
1. 编译原理是研究如何将高级语言程序转化为等价机器语言程序的一门学科。
编译器是将高级语言文本转换成等价的机器语言的软件工具。
它负责将源代码转化为目标代码,以便计算机能够理解和执行。
2. (1) 词法分析:将源代码分解成一系列单词或标记。
(2) 语法分析:根据语法规则组织单词或标记形成语法树。
(3) 语义分析:分析语法树以检测语义错误。
(4) 代码生成:根据语法树生成目标代码。
3. 词法分析器的功能是将源代码分解成一系列单词或标记。
它将源代码读取为字符流,然后将这些字符组成单词,同时可以去除空格、注释等不具有实际意义的内容。
词法分析器的作用是为语法分析器提供正确的单词序列,为后续的语义分析和代
码生成步骤建立基础。
4. 语法分析器的功能是根据语法规则组织单词或标记形成语法树。
它通过构建语法树来分析源代码的语法结构,同时可以检测语法错误。
语法分析器的作用是为后续的语义分析和代码生成步骤提供一个结构化的表示形式,便于后续的处理和转换。
编译原理课程设计-LL(1)文法的判定
课程设计报告课程:编译原理课程设计学号:姓名:班级:教师:时间:计算机科学与技术系结果与分析(可以加页):1、输入一个LL(1)进行测试,测试文法,测试结果如下图所示G(Z):Z->dAZ | bAcA->aA|ε图4 输入LL(1)文法并测试2、输入上述文法的一个句型进行测试,测试结果如下图所示待测试的句型1: bac图5 测试满足指定文法的句型待测试句型2:abc图6 测试不满足指定文法的句型3、测试一个非LL(1)文法图7 测试非LL(1)文法设计体会与建议:近一个月的设计过程,虽然题目早已经布下,但当时正在学习中,看到题目仅是一头雾水,没有一点头绪。
刚拿到题目的时候,乍看很简单,但当真正入手做的时候,觉得设计一个合理的数据结构不是一件很容易的事。
因为一个好的软件设计,应该考虑到它的健壮性和可扩充性,而且能够做的比较完善,对于系统运行中可能遇到的问题能够给出人性化的提示。
这需要在问题分析和题目设计的过程中逐渐改进。
就本次设计而言,要构造预测分析表,就要考虑输入的文法是否是LL(1)文法,对检测的结果应该给予适当的处理。
经过查找资料和他人的耐心答疑,我终于设计处理较为合理的程序,达到了预期的课程设计目的。
随着课程的深入,逐渐了解到一点解题的方法,但对于上机实践还是没有什么想法,后来到图书馆和网上找了很多资料,才了解到大致的实现方法,有根据以前的一点编程经验,于是开始一个模块一个模块的去实现,然后在进行整合,合并成一个完整的程序。
通过本次课程设计,使学到的理论知识得到了实践,清晰地看到了LL(1)分析的全过程,掌握了first,follow,select的机上实现方法,掌握了分析表的构造过程和方法,但遗憾的是,对于一些实现方法,例如句型分析的跟踪过程,仍是参考的网上的源程序,感到了自己的不足,还需更加努力!附录:程序代码#include<stdlib.h>#include<stdio.h>#include<string.h>/*******************************************/int count=0; /*分解的产生式的个数*/int number; /*所有终结符和非终结符的总数*/char start; /*开始符号*/char termin[50]; /*终结符号*/char non_ter[50]; /*非终结符号*/char v[50]; /*所有符号*/char left[50]; /*左部*/char right[50][50]; /*右部*/char first[50][50],follow[50][50]; /*各产生式右部的FIRST和左部的FOLLOW集合*/ char first1[50][50]; /*所有单个符号的FIRST集合*/char select[50][50]; /*各单个产生式的SELECT集合*/char f[50],F[50]; /*记录各符号的FIRST和FOLLOW是否已求过*/char empty[20]; /*记录可直接推出^的符号*/char TEMP[50]; /*求FOLLOW时存放某一符号串的FIRST集合*/int validity=1; /*表示输入文法是否有效*/int ll=1; /*表示输入文法是否为LL(1)文法*/int M[20][20]; /*分析表*/char choose; /*用户输入时使用*/char empt[20]; /*求_emp()时使用*/char fo[20]; /*求FOLLOW集合时使用*//*******************************************判断一个字符是否在指定字符串中********************************************/int in(char c,char *p){int i;if(strlen(p)==0)return(0);for(i=0;;i++){if(p[i]==c)return(1); /*若在,返回1*/if(i==strlen(p))return(0); /*若不在,返回0*/}}/*******************************************得到一个不是非终结符的符号********************************************/char c(){char c='A';while(in(c,non_ter)==1)c++;return(c);}/*******************************************分解含有左递归的产生式********************************************/void recur(char *point){ /*完整的产生式在point[]中*/int j,m=0,n=3,k;char temp[20],ch;ch=c(); /*得到一个非终结符*/k=strlen(non_ter);non_ter[k]=ch;non_ter[k+1]='\0';for(j=0;j<=strlen(point)-1;j++){if(point[n]==point[0]){ /*如果‘|’后的首符号和左部相同*/ for(j=n+1;j<=strlen(point)-1;j++){while(point[j]!='|'&&point[j]!='\0')temp[m++]=point[j++];left[count]=ch;memcpy(right[count],temp,m);right[count][m]=ch;right[count][m+1]='\0';m=0;count++;if(point[j]=='|'){n=j+1;break;}}}else{ /*如果‘|’后的首符号和左部不同*/ left[count]=ch;right[count][0]='^';right[count][1]='\0';count++;for(j=n;j<=strlen(point)-1;j++){if(point[j]!='|')temp[m++]=point[j];else{left[count]=point[0];memcpy(right[count],temp,m);right[count][m]=ch;right[count][m+1]='\0';printf(" count=%d ",count);m=0;count++;}}left[count]=point[0];memcpy(right[count],temp,m);right[count][m]=ch;right[count][m+1]='\0';count++;m=0;}}}/*******************************************分解不含有左递归的产生式********************************************/void non_re(char *point){int m=0,j;char temp[20];for(j=3;j<=strlen(point)-1;j++){if(point[j]!='|')temp[m++]=point[j];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);right[count][m]='\0';count++;m=0;}/*******************************************读入一个文法********************************************/char grammer(char *t,char *n,char *left,char right[50][50]){char vn[50],vt[50];char s;char p[50][50];int i,j,k;printf("请输入文法的非终结符号串:");scanf("%s",vn);getchar();i=strlen(vn);memcpy(n,vn,i);n[i]='\0';printf("请输入文法的终结符号串:");scanf("%s",vt);getchar();i=strlen(vt);memcpy(t,vt,i);t[i]='\0';printf("请输入文法的开始符号:");scanf("%c",&s);getchar();printf("请输入文法产生式的条数:");scanf("%d",&i);getchar();for(j=1;j<=i;j++){printf("请输入文法的第%d条(共%d条)产生式:",j,i);scanf("%s",p[j-1]);getchar();}for(j=0;j<=i-1;j++)if(p[j][1]!='-'||p[j][2]!='>'){ printf("\ninput error!");validity=0;return('\0');} /*检测输入错误*/for(k=0;k<=i-1;k++){ /*分解输入的各产生式*/if(p[k][3]==p[k][0])recur(p[k]);elsenon_re(p[k]);}return(s);}/*******************************************将单个符号或符号串并入另一符号串********************************************/void merge(char *d,char *s,int type){ /*d是目标符号串,s是源串,type=1,源串中的‘ ^ ’一并并入目串;type=2,源串中的‘ ^ ’不并入目串*/int i,j;for(i=0;i<=strlen(s)-1;i++){if(type==2&&s[i]=='^');else{for(j=0;;j++){if(j<strlen(d)&&s[i]==d[j])break;if(j==strlen(d)){d[j]=s[i];d[j+1]='\0';break;}}}}}/*******************************************求所有能直接推出^的符号********************************************/void emp(char c){ /*即求所有由‘ ^ ’推出的符号*/ char temp[10];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 _emp(char c){ /*若能推出,返回1;否则,返回0*/ int i,j,k,result=1,mark=0;char temp[20];temp[0]=c;temp[1]='\0';merge(empt,temp,1);if(in(c,empty)==1)return(1);for(i=0;;i++){if(i==count)return(0);if(left[i]==c) /*找一个左部为c的产生式*/{j=strlen(right[i]); /*j为右部的长度*/if(j==1&&in(right[i][0],empty)==1)return(1);else if(j==1&&in(right[i][0],termin)==1)return(0);else{for(k=0;k<=j-1;k++)if(in(right[i][k],empt)==1)mark=1;if(mark==1)continue;else{for(k=0;k<=j-1;k++){result*=_emp(right[i][k]);temp[0]=right[i][k];temp[1]='\0';merge(empt,temp,1);}}}if(result==0&&i<count)continue;else if(result==1&&i<count)return(1);}}}/*******************************************判断读入的文法是否正确********************************************/int judge(){int i,j;for(i=0;i<=count-1;i++){if(in(left[i],non_ter)==0){ /*若左部不在非终结符中,报错*/ printf("\nerror1!");validity=0;return(0);}for(j=0;j<=strlen(right[i])-1;j++){if(in(right[i][j],non_ter)==0&&in(right[i][j],termin)==0&&right[i][j]!='^'){ /*若右部某一符号不在非终结符、终结符中且不为‘ ^ ’,报错*/printf("\nerror2!");validity=0;return(0);}}}return(1);}/*******************************************求单个符号的FIRST********************************************/void first2(int i){ /*i为符号在所有输入符号中的序号*/char c,temp[20];int j,k,m;char ch='^';c=v[i];emp(ch);if(in(c,termin)==1) /*若为终结符*/{first1[i][0]=c;first1[i][1]='\0';}else if(in(c,non_ter)==1) /*若为非终结符*/{for(j=0;j<=count-1;j++){if(left[j]==c){if(in(right[j][0],termin)==1||right[j][0]=='^'){temp[0]=right[j][0];temp[1]='\0';merge(first1[i],temp,1);}else if(in(right[j][0],non_ter)==1){if(right[j][0]==c)continue;for(k=0;;k++)if(v[k]==right[j][0])break;if(f[k]=='0'){first2(k);f[k]='1';}merge(first1[i],first1[k],2);for(k=0;k<=strlen(right[j])-1;k++){empt[0]='\0';if(_emp(right[j][k])==1&&k<strlen(right[j])-1){for(m=0;;m++)if(v[m]==right[j][k+1])break;if(f[m]=='0'){first2(m);f[m]='1';}merge(first1[i],first1[m],2);}else if(_emp(right[j][k])==1&&k==strlen(right[j])-1){temp[0]='^';temp[1]='\0';merge(first1[i],temp,1);}elsebreak;}}}}}f[i]='1';}/*******************************************求各产生式右部的FIRST********************************************/void FIRST(int i,char *p){int length;int j,k,m;char temp[20];length=strlen(p);if(length==1) /*如果右部为单个符号*/ {if(p[0]=='^'){if(i>=0){first[i][0]='^';first[i][1]='\0';}else{TEMP[0]='^';TEMP[1]='\0';}}else{for(j=0;;j++)if(v[j]==p[0])break;if(i>=0){memcpy(first[i],first1[j],strlen(first1[j]));first[i][strlen(first1[j])]='\0';}else{memcpy(TEMP,first1[j],strlen(first1[j]));TEMP[strlen(first1[j])]='\0';}}}else /*如果右部为符号串*/{for(j=0;;j++)if(v[j]==p[0])break;if(i>=0)merge(first[i],first1[j],2);elsemerge(TEMP,first1[j],2);for(k=0;k<=length-1;k++){empt[0]='\0';if(_emp(p[k])==1&&k<length-1){for(m=0;;m++)if(v[m]==right[i][k+1])break;if(i>=0)merge(first[i],first1[m],2);elsemerge(TEMP,first1[m],2);}else if(_emp(p[k])==1&&k==length-1){temp[0]='^';temp[1]='\0';if(i>=0)merge(first[i],temp,1);elsemerge(TEMP,temp,1);}else if(_emp(p[k])==0)break;}}}/*******************************************求各产生式左部的FOLLOW********************************************/ void FOLLOW(int i){int j,k,m,n,result=1;char c,temp[20];c=non_ter[i]; /*c为待求的非终结符*/ temp[0]=c;temp[1]='\0';merge(fo,temp,1);if(c==start){ /*若为开始符号*/temp[0]='#';temp[1]='\0';merge(follow[i],temp,1);}for(j=0;j<=count-1;j++){if(in(c,right[j])==1) /*找一个右部含有c的产生式*/{for(k=0;;k++)if(right[j][k]==c)break; /*k为c在该产生式右部的序号*/for(m=0;;m++)if(v[m]==left[j])break; /*m为产生式左部非终结符在所有符号中的序号*/ if(k==strlen(right[j])-1){ /*如果c在产生式右部的最后*/if(in(v[m],fo)==1){merge(follow[i],follow[m],1);continue;}if(F[m]=='0'){FOLLOW(m);F[m]='1';}merge(follow[i],follow[m],1);}else{ /*如果c不在产生式右部的最后*/for(n=k+1;n<=strlen(right[j])-1;n++){empt[0]='\0';result*=_emp(right[j][n]);}if(result==1){ /*如果右部c后面的符号串能推出^*/if(in(v[m],fo)==1){ /*避免循环递归*/merge(follow[i],follow[m],1);continue;}if(F[m]=='0'){FOLLOW(m);F[m]='1';}merge(follow[i],follow[m],1);}for(n=k+1;n<=strlen(right[j])-1;n++)temp[n-k-1]=right[j][n];temp[strlen(right[j])-k-1]='\0';FIRST(-1,temp);merge(follow[i],TEMP,2);}}}F[i]='1';}/*******************************************判断读入文法是否为一个LL(1)文法********************************************/int ll1(){int i,j,length,result=1;char temp[50];for(j=0;j<=49;j++){ /*初始化*/first[j][0]='\0';follow[j][0]='\0';first1[j][0]='\0';select[j][0]='\0';TEMP[j]='\0';temp[j]='\0';f[j]='0';F[j]='0';}for(j=0;j<=strlen(v)-1;j++)first2(j); /*求单个符号的FIRST集合*/ printf("\nfirst1:");for(j=0;j<=strlen(v)-1;j++)printf("%c:%s ",v[j],first1[j]);printf("\nempty:%s",empty);printf("\n_emp:");for(j=0;j<=strlen(v)-1;j++)printf("%d ",_emp(v[j]));for(i=0;i<=count-1;i++)FIRST(i,right[i]); /*求FIRST*/for(j=0;j<=strlen(non_ter)-1;j++){ /*求FOLLOW*/if(fo[j]==0){fo[0]='\0';FOLLOW(j);}}printf("\nfirst:");for(i=0;i<=count-1;i++)printf("%s ",first[i]);printf("\nfollow:");for(i=0;i<=strlen(non_ter)-1;i++)printf("%s ",follow[i]);for(i=0;i<=count-1;i++){ /*求每一产生式的SELECT集合*/ memcpy(select[i],first[i],strlen(first[i]));select[i][strlen(first[i])]='\0';for(j=0;j<=strlen(right[i])-1;j++)result*=_emp(right[i][j]);if(strlen(right[i])==1&&right[i][0]=='^')result=1;if(result==1){for(j=0;;j++)if(v[j]==left[i])break;merge(select[i],follow[j],1);}}printf("\nselect:");for(i=0;i<=count-1;i++)printf("%s ",select[i]);memcpy(temp,select[0],strlen(select[0]));temp[strlen(select[0])]='\0';for(i=1;i<=count-1;i++){ /*判断输入文法是否为LL(1)文法*/ length=strlen(temp);if(left[i]==left[i-1]){merge(temp,select[i],1);if(strlen(temp)<length+strlen(select[i]))return(0);}else{temp[0]='\0';memcpy(temp,select[i],strlen(select[i]));temp[strlen(select[i])]='\0';}}return(1);}/*******************************************构造分析表M********************************************/void MM(){int i,j,k,m;for(i=0;i<=19;i++)for(j=0;j<=19;j++)M[i][j]=-1;i=strlen(termin);termin[i]='#'; /*将#加入终结符数组*/termin[i+1]='\0';for(i=0;i<=count-1;i++){for(m=0;;m++)if(non_ter[m]==left[i])break; /*m为产生式左部非终结符的序号*/ for(j=0;j<=strlen(select[i])-1;j++){if(in(select[i][j],termin)==1){for(k=0;;k++)if(termin[k]==select[i][j])break; /*k为产生式右部终结符的序号*/ M[m][k]=i;}}}}/*******************************************总控算法********************************************/ void syntax(){int i,j,k,m,n,p,q;char ch;char S[50],str[50];printf("请输入该文法的句型:");scanf("%s",str);getchar();i=strlen(str);str[i]='#';str[i+1]='\0';S[0]='#';S[1]=start;S[2]='\0';j=0;ch=str[j];while(1){if(in(S[strlen(S)-1],termin)==1){if(S[strlen(S)-1]!=ch){printf("该符号串不是文法的句型!");return;}else if(S[strlen(S)-1]=='#'){printf("该符号串是文法的句型.");return;}else{S[strlen(S)-1]='\0';j++;ch=str[j];}}else{for(i=0;;i++)if(non_ter[i]==S[strlen(S)-1])break;for(k=0;;k++){if(termin[k]==ch)break;if(k==strlen(termin)){printf("词法错误!");return;}}if(M[i][k]==-1){printf("语法错误!");return;}else{m=M[i][k];if(right[m][0]=='^')S[strlen(S)-1]='\0';else{p=strlen(S)-1;q=p;for(n=strlen(right[m])-1;n>=0;n--)S[p++]=right[m][n];S[q+strlen(right[m])]='\0';}}}printf("S:%s str:",S);for(p=j;p<=strlen(str)-1;p++)printf("%c",str[p]);printf(" \n");}}/*******************************************一个用户调用函数********************************************/ void menu(){syntax();printf("\n是否继续?(y or n):");scanf("%c",&choose);getchar();while(choose=='y'){menu();}}/*******************************************主函数********************************************/void main(){int i,j;start=grammer(termin,non_ter,left,right); /*读入一个文法*/ printf("count=%d",count);printf("\nstart:%c",start);strcpy(v,non_ter);strcat(v,termin);printf("\nv:%s",v);printf("\nnon_ter:%s",non_ter);printf("\ntermin:%s",termin);printf("\nright:");for(i=0;i<=count-1;i++)printf("%s ",right[i]);printf("\nleft:");for(i=0;i<=count-1;i++)printf("%c ",left[i]);if(validity==1)validity=judge();printf("\nvalidity=%d",validity);if(validity==1){ll=ll1();printf("\nll=%d",ll);if(ll==0)printf("\n该文法不是一个LL1文法!");else{MM();printf("\n");for(i=0;i<=19;i++)for(j=0;j<=19;j++)if(M[i][j]>=0)printf("M[%d][%d]=%d ",i,j,M[i][j]);menu();}}}。
编译原理试题及答案
编译原理试题及答案一、选择题1. 编译器的主要功能是什么?A. 将高级语言代码翻译成机器语言代码B. 进行程序调试C. 进行代码优化D. 管理程序运行时的内存分配答案:A2. 词法分析器的主要任务是什么?A. 将源代码分解成多个语句B. 将源代码分解成多个词素C. 检查源代码的语法正确性D. 将词素转换为相应的语法单位答案:B3. 下列哪个是自顶向下的语法分析方法?A. LL(1)分析法B. LR(1)分析法C. LALR(1)分析法D. GLR分析法答案:A4. 语义分析的主要任务是什么?A. 检查程序的语法正确性B. 检查程序的类型正确性C. 将源代码转换为目标代码D. 进行程序的优化答案:B5. 代码生成阶段的主要任务是什么?A. 将语法树转换为目标代码B. 进行程序的优化C. 检查程序的类型正确性D. 将源代码分解成多个词素答案:A二、简答题1. 简述编译过程的主要阶段。
答案:编译过程主要分为四个阶段:词法分析、语法分析、语义分析和代码生成。
词法分析将源代码分解成词素,语法分析检查源代码的语法结构,语义分析检查源代码的语义正确性,代码生成将源代码转换为目标代码。
2. 什么是中间代码?它在编译过程中起到什么作用?答案:中间代码是一种介于源代码和目标代码之间的代码形式,它通常具有更接近于机器语言的特性,但仍然保持一定的抽象级别。
中间代码在编译过程中起到桥梁的作用,它使得代码优化和目标代码生成更加方便和高效。
三、论述题1. 论述编译器优化的几种常见方法。
答案:编译器优化主要包括以下几种方法:常量折叠、死代码消除、公共子表达式消除、循环优化、代码内联、寄存器分配等。
这些优化方法可以提高程序的执行效率,减少资源消耗,提高程序的运行速度。
结束语:本试题涵盖了编译原理的基本知识点,包括编译器的功能、编译过程的主要阶段、中间代码的作用以及编译器优化的方法。
希望考生能够通过本试题加深对编译原理的理解和掌握。
编译原理试题及答案
编译原理试题及答案1. 选择题(每题4分,共40分)1) 当编译器在词法分析阶段遇到无法识别的字符时,应该采取的动作是:A. 直接忽略该字符并继续进行词法分析B. 输出错误信息并终止词法分析过程C. 将该字符标记为非法字符并继续词法分析D. 转交给语法分析器进行处理答案:B2) 下列关于语法分析器的描述中,错误的是:A. 语法分析器使用文法规则将输入的记号流转化为推导树B. 语法分析器可以通过自上而下或自下而上的方式进行解析C. LL(1)文法是一种常用于自上而下语法分析的文法形式D. 语法分析器的输入是词法分析器输出的记号流答案:A3) 以下关于语法制导翻译的说法,正确的是:A. 语法制导翻译是在语义分析阶段完成的B. 语法制导翻译通过产生式的属性传递进行信息的传递和计算C. 语法制导翻译只能用于自上而下的语法分析D. 语法制导翻译是在语法分析阶段完成的答案:B4) 在SLR分析算法中,项目集簇的构造过程中需要进行的操作是:A. 闭包操作和移进操作B. 移进操作和规约操作C. 闭包操作和规约操作D. 闭包操作、移进操作和规约操作答案:D5) 下列关于中间代码生成的叙述中,错误的是:A. 中间代码是一种类似于汇编代码的表示形式B. 中间代码可以直接被目标代码生成器所使用C. 中间代码的生成可以采用三地址码的形式D. 中间代码的生成在语法分析和语义分析之后进行答案:B2. 简答题(每题10分,共30分)1) 请简要描述编译器的主要工作流程。
答案:编译器的主要工作流程包括词法分析、语法分析、语义分析、中间代码生成、优化和目标代码生成等阶段。
在词法分析阶段,编译器将输入的源代码转化为一个个记号流。
接下来,在语法分析阶段,编译器使用文法规则对记号流进行分析,并生成语法树或推导树。
在语义分析阶段,编译器对语法树进行语义检查,并进行类型推导和符号表管理等操作。
中间代码生成阶段将经过语义分析的源代码转化为一种中间表示形式,通常是三地址码。
编译原理词法分析习题集带答案
编译原理词法分析习题集带答案《编译原理》习题(⼀)——词法分析⼀、就是⾮题(请在括号内,正确得划√,错误得划×)1.编译程序就是对⾼级语⾔程序得解释执⾏。
(× )2.⼀个有限状态⾃动机中,有且仅有⼀个唯⼀得终态。
(×)9.两个正规集相等得必要条件就是她们对应得正规式等价。
(× )⼆、选择题1.词法分析器得输出结果就是_____。
A.( ) 记号B.( ) 相应条⽬在符号表中得位置C.( ) 记号与属性⼆元组D.( ) 属性值2. 正规式M 1 与M 2 等价就是指_____。
A.( ) M1与M2得状态数相等B.( ) M1与M2得有向边条数相等C.( ) M1与M2所识别得语⾔集相等D.( ) M1与M2状态数与有向边条数相等3.语⾔就是A.句⼦得集合B.产⽣式得集合C.符号串得集合D.句型得集合4.编译程序前三个阶段完成得⼯作就是A.词法分析、语法分析与代码优化B.代码⽣成、代码优化与词法分析C.词法分析、语法分析、语义分析与中间代码⽣成D.词法分析、语法分析与代码优化5.扫描器所完成得任务就是从字符串形式得源程序中识别出⼀个个具有独⽴含义得最⼩语法单位即A. 字符B.单词C.句⼦D.句型6.构造编译程序应掌握______。
A.( )源程序B.( ) ⽬标语⾔C.( ) 编译⽅法D.( ) 以上三项都就是7.词法分析得任务就是A.识别单词B.分析句⼦得含义C.识别句⼦D.⽣成⽬标代码三、填空题1.计算机执⾏⽤⾼级语⾔编写得程序主要有两种途径:___解释__与__编译___。
3、编译过程可分为( 词法分析) ,(语法分析),(语义分析与中间代码⽣成),(优化)与(⽬标代码⽣成)五个阶段。
6、扫描器得任务就是从( 源程序中)中识别出⼀个个( 单词符号)。
17、⼀张转换图只包含有限个状态,其中有⼀个被认为就是(初)态;⽽且实际上⾄少要有⼀个(终)态。
1.编译程序⾸先要识别出源程序中每个(单词),然后再分析每个(句⼦)并翻译其意义。
编译原理课程设计-LL(1)语法分析器的构造
LL(1)语法分析器的构造摘要语法分析的主要任务是接收词法分析程序识别出来的单词符由某种号串,判断它们是否语言的文法产生,即判断被识别的符号串是否为某语法部分。
一般语法分析常用自顶向下方法中的LL分析法,采用种方法时,语法分程序将按自左向右的顺序扫描输入的的符号串,并在此过程中产生一个句子的最左推导,即LL是指自左向右扫描,自左向右分析和匹配输入串。
经过分析,我们使用VC++作为前端开发工具,在分析语法成分时比较方便直观,更便于操作。
运行程序的同时不断修正改进程序,直至的到最优源程序。
关键字语法分析文法自顶向下分析 LL(1)分析最左推导AbstractGrammatical analysis of the main tasks was to receive lexical analysis procedure to identify the words from a website, string, and judge whether they have a grammar of the language, that is, judging by the series of symbols to identify whether a grammar part. General syntax analysis commonly used top-down methods of LL analysis, using methods, Grammar hours will be from the procedures of the order left-to-right scanning input string of symbols, and in the process produced one of the most left the sentence is derived, LL is scanned from left to right, From left to right analysis and matching input strings. After analysis, we use VC + + as a front-end development tool for the analysis of syntax ingredients more convenient visual, more easy to operate. Operational procedures at the same time constantly improving procedures, until the source of optimal .Key WordsGrammatical analysis grammar Top-down analysis LL (1) AnalysisMost left Derivation目录摘要 (1)引言 (3)第一章设计目的 (4)第二章设计的内容和要求 (5)2.1 设计内容 (5)2.2 设计要求 (5)2.3 设计实现的功能 (5)第三章设计任务的组织和分工 (6)3.1 小组的任务分工 (6)3.2 本人主要工作 (6)第四章系统设计 (9)4.1 总体设计 (9)4.2 详细设计 (9)第五章运行与测试结果 (22)5.1 一组测试数据 (22)5.2 界面实现情况 (23)第六章结论 (27)课程设计心得 (28)参考文献 (29)致谢 (30)附录(核心代码清单) (31)引言编译器的构造工具是根据用户输入的语言的文法,编译器的构造工具可以生成程序来处理以用户输入的文法书写的文本。
编译原理课程设计_词法语法分析器
编译原理课程设计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运行结果九、 实验体会通过本次次法分析设计实验,我加深了对词法分析过程的理解。
编译原理课程设计LR(1)分析法
课程设计说明书课程名称:_编译原理课程设计_题目: LR(1)分析法院系:_专业班级:学号:__学生姓名:___指导教师:___2012年 6 月 22 日安徽理工大学课程设计(论文)任务书2012年6 月22 日安徽理工大学课程设计(论文)成绩LR(1)分析法一、系统简介及需求分析1.1 设计目的及要求(1)掌握LR(1)分析法的基本原理;(2)掌握LR(1)分析表的构造方法;(3)掌握LR(1)驱动程序的构造方法。
(4)构造LR(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文法识别的句子.1.2实验内容根据某一文法编制调试LR(1)分析程序,以便对任意输入的符号串进行分析。
本次实验的目的主要是加深对LR(1)分析法的理解。
对下列文法,用LR(1)分析法对任意输入的符号串进行分析:(0)E->S(1)S->BB(2)B->aB(3)B->b程序输入一以#结束的符号串(包括a、b、#),如:abb#。
输出过程如下:步骤状态栈符号栈输入串ACTION GOTO1 0 # abb# S3... ... ... ... ... ...图1-1二、设备与环境2.1硬件设备内存容量 2 GB硬盘容量 320 GB硬盘描述 7200转,SATA流处理器个数 322.2软件环境操作系统:WINDOWS XP开发平台:C语言开发软件: VC++ 6.0三、系统分析3.1 LR(1)分析法定义LR分析法是一种有效的自底向上的语法分析技术,它能适用于大部分上下文无关文法的分析,一般叫LR(k)分析方法,其中L是指自左(Left)向右扫描输入单词串,R是指分析过程都是构造最右(Right)推导的逆过程(规范归约),括号中的k是指在决定当前分析动作时向前看的符号个数。
3.2 LR(1)分析方法的主要思想(1)严格地进行最左归约(识别句柄并归约它)。
(2)将识别句柄的过程划分为由若干状态控制,每个状态控制识别出句柄的一个符号。
编译原理典型例题
编译原理典型案例1.对于文法G[S]S →(L)S→aSS→aL →L,SL→S(1) 画出句型(S,(a)) 的语法树;(2) 写出上述句型的所有短语、直接短语、句柄和素短语。
解答这类题目重点考查语法树、推导、短语、直接短语、句柄和素短语等基本概念。
在句型中寻找短语、直接短语、句柄的方法:(1) 画出句型对应的语法树。
句型(S,(a)) 的语法树如下图所示(2) 在该语法树中寻找短语、直接短语、句柄。
首先我们看短语的定义:令G是一个文法,S是文法的开始符,假设α,β,δ是文法G的句型,如果有S*⇒αAδ且 A +⇒β则称β是句型αβδ相对于非终结符A的短语。
如果有A⇒β,则称β是句型αβδ相对于规则A→β的直接短语。
一个句型的最左直接短语称为该句型的句柄。
根据短语的定义可知,以非终结符A为根的子树的叶结点从左到右排列就是相对于非终结符A的短语;如果子树只有两代,则短语就是直接短语;最左边的两代子树的所有叶结点从左到右排列,就是该句型的句柄。
素短语是一个短语,它至少包含一个终结符,且除自身外不再包含其他素短语。
处于句型最左边的素短语为最左素短语。
从语法树中我们可以找到:短语:a,S,(a),S, (a),(S, (a))直接短语:a,S句柄:S素短语:a2. 写一个上下文无关文法,使其语言能被5整除且不以0开头的无符号整数集合(如{5,10,15}) 解答能被5整除的数从形式上看,是以0,5结尾的数字串。
题目要求不以0开头,注意0不是该语言的句子。
句子的结构分为三种:其中,A 代表可以出现在个位上的数字,只能是0或5;B 代表可以出现在开始位上的数字,除了0以外,其他数字都可以;C 代表可以出现在中间位上的数字。
0-9所有数字都可以。
于是,A →0 | 5B →1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9C →0 | B写文法时,先描述一位数结构,于是有产生式S →5。
对于两位数和多位数,都是以B 开头和以A 结尾,于是有产生式S →DA 。
编译原理实验题目
编译原理课程设计指导书题目一基于语法制导翻译的表达式转换编译器一、设计目的通过本课程设计获得对实际编译器的构造原理、过程和方法的感性认识,全面掌握语法制导翻译技术。
二、设计内容采用语法制导翻译模式设计一个包含词法分析、语法分析、符号表管理、错误处理及输出等功能模块的、由中缀表达式到后缀表达式的完整编译器。
该翻译器的规格说明如下:start → list eoflist → expr |expr → expr + term { print(‘+’) }| expr –term { print(‘-’) }| term|εterm → term * factor { print(‘*’) }| term / factor { print(‘/’) }| term div factor { print(‘DIV’) }| term mod factor { print(‘MOD’) }factor → ( expr )| id { print( ) }| num { print( num.value ) }三、设计要求1、使用模块化设计思想来设计该编译器;2、词法分析模块用于读入输入串,并将其转换成供语法分析模块使用的记号流。
其中包括滤掉空格和注释、识别常数、识别标识符和关键字等功能;3、要求在语法分析模块中利用语法制导翻译技术完成具体的中缀表达式到后缀表达式的翻译,其中包括按前述翻译器的规格说明构建对应表达式、项、因子的非终结符expr、term 和factor的函数以及检查记号是否匹配的函数;并在不匹配时调用错误处理模块;4、要求符号表管理模块主要完成符号表对应数据结构的具体实现功能;5、错误处理模块负责报告错误信息及位置,并终止分析过程;6、输出模块完成翻译后所得到的后缀表达式的输出。
四、运行结果1、从键盘输入任意中缀表达式,如:4 -5 *6 DIV 4 + 8 MOD 2输出相应的后缀表达式:456*4DIV-82MOD+1、若键盘输入串为非中缀表达式时,如:4 !+*5 -6 DIV 4 + 8 MOD 2输出相应语法错误报告信息,并停止语法分析,如:line 1 : compiler error !五、提示1、将各功能模块设计为独立的源程序文件;2、建立一个全局头文件,将本设计所需要用到的系统头文件的打开、一些必要的宏定义和全局变量的声明信息放在该全局头文件中;3、将本设计所有文件加入一个工程文件。
编译原理课程设计报告-词法分析器
一.课程设计题目:词法分析器的实现二.课程设计成员三.课程设计内容和要求设计一个程序,调试、编译,实现词法分析的功能,识别各单词或字符所属类别,并显示在屏幕上。
词法分析器:逐个读入源程序字符并按照构词规则切分成一系列单词。
单词是语言中具有独立意义的最小单位,包括保留字、标识符、运算符、标点符号和常量等。
词法分析是编译过程中的一个阶段,在语法分析前进行。
也可以和语法分析结合在一起作为一遍,由语法分析程序调用词法分析程序来获得当前单词供语法分析使用。
要求:通过词法分析器能够实现以下五种类型如单词等的识别。
(1)关键字"begin","end","if","then","else","while","write","r ead"等,"do", "call","const","char","until","procedure","repeat"等(2)运算符:"+","-","*","/","="等(3)界符:"{","}","[","]",";",",",".","(",")",":"等(4)标识符(5)常量四.操作要求首先建立一个或多个文档,此处新建了两个文档,例:07196133.txt文本文档和zhaoxiaodong.txt文本文档,以供选择,各文本文档中都输入有不同的内容,运行程序,出现提示,输入文本文档的名称,即可对文本文档中的内容进行分析,并把分析结果输出显示在屏幕上。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编译原理课程设计
一、课程设计的基本要求和方法
(一)、目的
进一步培养学生编译器设计的思想,加深对编译原理和应用程序的理解,针对编译过程的重点和难点内容进行编程,独立完成有一定工作量的程序设计任务,同时强调好的程序设计风格,并综合使用程序设计语言、数据结构和编译原理的知识,熟悉使用开发工具VC /JA V A/C#/.NET 。
(二)、课程设计步骤
1、问题理解和分析
充分地分析和理解问题本身,弄清要求做什么。
2、确定解决问题的方法(设计)
主要是找到解决问题的主要思路,是怎么做。
在此阶段可考虑系统的功
能和模块划分等。
3、详细设计和编码
确定算法的主要流程,再进行编程。
在此阶段应提醒学生程序可先在纸上写,尽量想清楚了再动手上机,在编程过程中注意程序结构的清晰性,避免出现很多明显的程序逻辑错误和语法错误,提高后面程序调试效率。
4、程序调试和运行
使学生掌握程序调试和排错的基本方法,增加编程的感觉和解决问题的成就感。
5、完成课程设计报告(使用华东交通大学课程设计报告,需学生自己购买)
1)问题描述
题目要解决的问题是什么
2)分析、设计、实现
解决问题的基本方法说明,包括主要算法思想,算法的流程图。
程序中主要函数或过程的功能说明。
3)运行结果分析。
4)总结
遇到的主要问题是如何解决的、对设计和编码的回顾讨论和分析、进一步改进设想、经验和体会等。
5)附录,包括源程序关键代码和运行结果。
(三)、考核评估
通过程序实现、总结报告和学习态度综合考评,并结合学生的动手能力,独立分析解决问题的能力和创新精神。
成绩分优、良、中、及格和不及格五等。
考核标准包括:
(1)编译器思想的正确性,包括是否采用了合适的数据存储结构等。
(2)程序实现的正确性,包括程序整体结构是否合理、编程风格是否规范等。
(3)程序功能的完善程度,包括功能的基本实现、基本完善、完全实现(4)学生的工作态度、独立工作能力。
(5)课程设计报告。
以上五项考核内容,每项占的权重均为20% 。
二、 编译原理设计题目
以下有六个课程设计题目,要求学生从中选择一个题目做本次课程设计。
(一) First 集和Follow 集生成算法模拟
【问题描述】
设计一个由正规文法生成First 集和Follow 集并进行简化的算法动态模拟。
(算法参见教材)
【基本要求】
动态模拟算法的基本功能是: (1) 输入一个文法G ;
(2) 输出由文法G 构造FIRST 集的算法; (3) 输出First 集;
(4) 输出由文法G 构造FOLLOW 集的算法; (5) 输出FOLLOW 集。
【测试数据】
输入文法: E->TE ’
E ’->+TE ’|ε T->FT ’
T ’->*FT ’|εF->(E)|i
【实现提示】
用数据库存储多行文法,用LIST 控件显示算法,用GRID 类依据算法进行作图。
并实现算法与生成过程的关联。
(二)LL(1)分析过程模拟
【问题描述】
设计一个给定LL (1)分析表,输入一个句子,能由依据LL (1)分析表输出与句子对应i )
(
*
+
F 的f i r s t 集
T 的f i r s t 集 E 的f i r s t 集 1
1
1
1 1
1
1 1 1
的语法树。
能对语法树生成过程进行模拟。
(算法参见教材)
【基本要求】
动态模拟算法的基本功能是:
(1) 输入LL (1)分析表和一个句子; (2) 输出LL (1)总控程序;
(3) 输出依据句子构成的对应语法树的过程;
【测试数据】
输入句子:i*i+i
输入LL (1)分析表
【实现提示】
用结构体数组存储多行正规式,用LIST 控件显示算法,用CDC 类依据进行算法进行
作图。
并实现算法与生成过程的关联。
(三)FirstVT 集和LastVT 集生成算法模拟
【问题描述】
设计一个由正规文法生成FirstVT 集和LastVT 集的算法动态模拟。
(算法参见教材)
【基本要求】
动态模拟算法的基本功能是: (1) 输入一个文法G ;
(2) 输出由文法G 构造FIRSTVT 集的算法; (3) 输出FirstVT 集;
(4) 输出由文法G 构造LastVT 集的算法; (5) 输出LastVT 集。
→(E )
→i
F →ε → ε →*F T '
→ ε
T ' →F T ' →F T '
T →ε → ε →+T E ' E ' →T E '
→T E '
E
#
) (
* + i
【测试数据】
输入文法: E->TE ’
E ’->+TE ’|ε T->FT ’
T ’->*FT ’|εF->(E)|i
【实现提示】
用数据库存储多行文法,用LIST 控件显示算法,用GRID 类依据算法进行作图。
并实现算法与生成过程的关联。
(四) 算符优先分析表生成模拟
【问题描述】
设计一个给定文法和对应的FIRSTVT 和LASTVT 集,能依据依据文法和FIRSTVT 和LASTVT 生成算符优先分析表。
(算法参见教材)
【基本要求】
动态模拟算法的基本功能是:
(1) 输入一个给定文法,及FIRSTVT 和LASTVT 集; (2) 输出算符优先分析表生成算法;
(3) 输出算法优先分析表构造过程的过程;
【测试数据】
输入文法: E->TE ’
E ’->+TE ’|ε T->FT ’
T ’->*FT ’|εF->(E)|i
【实现提示】
用结构体数组存储多行正规式,用LIST 控件显示算法,用CDC 类依据进行算法进行作图。
并实现算法与生成过程的关联。
i )
(
*
+
F 的f i r s t V T
T 的f i r s t V T E 的f i r s t V T 1
1
1
1 1
1
1 1 1
(五)算符优先分析过程模拟
【问题描述】
设计一个给定算符优先分析表,输入一个句子,能由依据算符优先分析表输出与句子对应的语法树。
能对语法树生成过程进行模拟。
(算法参见教材)
【基本要求】
动态模拟算法的基本功能是:
(1)输入算符优先分析表和一个句子;
(2)输出算符优先分析总控程序;
(3)输出依据句子构对应的语法树的过程;
【测试数据】
输入句子:i*i+i
输入算符优先分析表
【实现提示】
用结构体数组存储多行正规式,用LIST控件显示算法,用CDC类依据进行算法进行作图。
并实现算法与生成过程的关联。
(六)L R分析过程模拟
【问题描述】
设计一个给定LR分析表,输入一个句子,能由依据LR分析表输出与句子对应的语法树。
能对语法树生成过程进行模拟。
(算法参见教材)
【基本要求】
动态模拟算法的基本功能是:
(1)输入LR分析表和一个句子;
(2)输出LR总控程序;
(3)输出依据句子构对应的语法树的过程;
【测试数据】
输入句子:i*i+i
输入LR分析表
【实现提示】 用结构体数组存储多行正规式,用LIST 控件显示算法,用CDC 类依据进行算法进行作图。
并实现算法与生成过程的关联。
【注释】
本次课程设计共6道题目,各同学的选题可自由选择,也可自己结合感兴趣知识点自行命题,鼓励创新性设计。
r 5
r 5
r 5
r 5
11
r 1 r 1 S 7 r 1 9 r 3 r 3 r 3 r 3 10
S 11 S 6 8 10 S 4
S 5
7 3 3
3 F S
4 S 4
S 4 ( r 6 r 4
r 2 ) 9 r 1
S 5 6 r 6 r 6 r 6
5 2 8
S 5
4
r 4
r 4
r 4
3
r 2 S 7 r 2 2 a c c S 6 1
2 1
S 5 0
T E # * +
i
G o T o
A C T I O N 状态。