编译原理---实验题目
- 格式:doc
- 大小:118.00 KB
- 文档页数:8
编译原理试题及答案一、选择题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简单的词法分析子程序【实验目的】●理解词法分析在编译程序中的作用●初步了解和掌握词法分析程序的实现方法和技术【实验内容】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,()…说明:关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符,查关键字表。
编译原理词法分析器-ll1-lr0-python实现代码计算机科学与通信工程学院编译原理实验报告题目: 1.词法分析器2. LL(1)分析器3. LR(0)分析器班级:姓名:学号:指导老师:2017年月目录一、实验题目 (1)二、实验目的和要求 (1)三、代码实现 (2)四、总结 (25)一、实验题目1.词法分析器分析一段程序代码,将代码中的单词符号分解出来,并对其进行检查,输出token表和error表2.LL(1)文法分析器分析给定文法。
求出文法的FIRST集,FOLLOW集,并构建分析表,对给定输入串进行分析。
3.LR(0)文法分析器分析给定文法。
用Ꜫ_CLOSURE方法构造文法的LR(0)项目集规范族,根据状态转换函数GO构造出文法的DFA,并转换为分析表,对给定输入串进行分析。
二、实验目的和要求1.学会词法分析器的实现思路。
2.学会求解FIRST集, FOLLOW集,构造LL(1)分析表。
3.学会Ꜫ_CLOSURE方法,状态转换函数GO, 构造LR(0)分析表。
三、代码实现1.词法分析器program.txt 中存放要分析的文法:E->TRR->+TR|-TR|~T->FGG->*FG|/FG|~F->(E)|i代码:KEYWORD_LIST = ['while', 'if', 'else', 'switch', 'case']SEPARATOR_LIST = [';', ':', ',', '(', ')', '[', ']', '{', '}']OPERATOR_LIST1 = ['+', '-', '*']OPERATOR_LIST2 = ['<=', '<', '==', '=', '>', '>=']CATEGORY_DICT = {# KEYWORD"while": {"while": ""},"if": {"if": ""},"else": {"else": ""},"switch": {"switch": ""},"case": {"case": ""},# OPERATOR"+": {"+": ""},"-": {"-": ""},"*": {"*": ""},"<=": {"relop": "LE"},"<": {"relop": "LT"},">=": {"relop": "GE"},">": {"relop": "GT"},"==": {"relop": "EQ"},"=": {"=": ""},# SEPARATOR";": {";": ""},":": {":": ""},",": {",": ""},"(": {"(": ""},")": {")": ""},"[": {"]": ""},"]": {"]": ""},"{": {"{": ""},"}": {"}": ""},}CONSTANTTABLE = []TOKENTABLE = []OPERATORTABLE = []KEYWORDTABLE = []SEPARATORTABLE = []UNDEFINEDTABLE = []# READ FILEdef read_file(path, method):temp_str = ""try:file = open(path, method)for line in file:line = line.replace('\n', " ") temp_str += linetemp_str = str(temp_str)except IOError as e:print(e)exit()finally:file.close()return temp_str.strip() + " "# GETBEdef getbe():global tokengetchar()token = ""return# GETCHARdef getchar():global characterglobal locationwhile all_string[location] == " ":location = location + 1character = all_string[location]return character# LINK TOKENdef concatenation():global tokenglobal charactertoken = token + character# IS NUMBERdef digit():if '0' <= character <= '9':return Truereturn False# IS ALPHABETdef letter():if 'A' <= character <= 'Z' or 'a' <= character <= 'z': return Truereturn False# IS IDENTIFIERdef reserve():if token in KEYWORD_LIST:return CATEGORY_DICT[token]else:return 0# RETRACTdef retract():global locationglobal character# location = location - 1character = ""return# MAIN FUNCTIONdef main():global tokenglobal characters = getchar()getbe()if 'a' <= s <= 'z' or 'A' <= s <= 'Z':while letter() or digit():concatenation()location = location + 1character = all_string[location]retract()c = reserve()if c == 0:TOKENTABLE.append(token)print("这是标识符:{'", token, "':'", TOKENTABLE.index(token), "'}") else:KEYWORDTABLE.append(token)print("这是保留字:", CATEGORY_DICT[token])elif '0' <= s <= '9':while digit():concatenation()location = location + 1character = all_string[location]retract()CONSTANTTABLE.append(token)print("这是常数:{'", token, "':'", CONSTANTTABLE.index(token), "'}") elif s in OPERATOR_LIST1:location = location + 1OPERATORTABLE.append(s)print("这是单操作符:", CATEGORY_DICT[s])elif s in OPERATOR_LIST2:location = location + 1character = all_string[location]if character == '=':OPERATORTABLE.append(s + character)print("这是双操作符:", CATEGORY_DICT[s + character])else:retract()location = location + 1OPERATORTABLE.append(s)print("这是单操作符:", CATEGORY_DICT[s])elif s in SEPARATOR_LIST:location = location + 1SEPARATORTABLE.append(s)print("这是分隔符:", CATEGORY_DICT[s])else:UNDEFINEDTABLE.append(s)print("error:undefined identity :'", s, "'")if __name__ == '__main__':character = ""token = ""all_string = read_file("program.txt", "r")location = 0while location + 1 < len(all_string):main()print('KEYWORDTABLE:', KEYWORDTABLE)print('TOKENTABLE:', TOKENTABLE)print('CONSTANTTABLE:', CONSTANTTABLE)print('OPERATORTABLE:', OPERATORTABLE)print('SEPARATORTABLE:', SEPARATORTABLE)运行结果:2.LL(1)分析器program.txt 中存放要分析的文法:E->TRR->+TR|-TR|~T->FGG->*FG|/FG|~F->(E)|i输入串:i+i*i代码:NonTermSet = set() # 非终结符集合TermSet = set() # 终结符集合First = {} # First集Follow = {} # Follow集GramaDict = {} # 处理过的产生式Code = [] # 读入的产生式AnalysisList = {} # 分析表StartSym = "" # 开始符号EndSym = '#' # 结束符号为“#“Epsilon = "~" # 由于没有epsilon符号用“~”代替# 构造First集def getFirst():global NonTermSet, TermSet, First, Follow, FirstAfor X in NonTermSet:First[X] = set() # 初始化非终结符First集为空for X in TermSet:First[X] = set(X) # 初始化终结符First集为自己Change = Truewhile Change: # 当First集没有更新则算法结束Change = Falsefor X in NonTermSet:for Y in GramaDict[X]:k = 0Continue = Truewhile Continue and k < len(Y):if not First[Y[k]] - set(Epsilon) <= First[X]: # 没有一样的就添加,并且改变标志if Epsilon not in First[Y[k]] and Y[k] in NonTermSet and k > 0: # Y1到Yi候选式都有~存在Continue = Falseelse:First[X] |= First[Y[k]] - set(Epsilon)Change = Trueif Epsilon not in First[Y[k]]:Continue = Falsek += 1if Continue: # X->~或者Y1到Yk均有~产生式First[X] |= set(Epsilon)# FirstA[Y] |= set(Epsilon)# 构造Follow集def getFollow():global NonTermSet, TermSet, First, Follow, StartSymfor A in NonTermSet:Follow[A] = set()Follow[StartSym].add(EndSym) # 将结束符号加入Follow[开始符号]中Change = Truewhile Change: # 当Follow集没有更新算法结束Change = Falsefor X in NonTermSet:for Y in GramaDict[X]:for i in range(len(Y)):if Y[i] in TermSet:continueFlag = Truefor j in range(i + 1, len(Y)): # continueif not First[Y[j]] - set(Epsilon) <= Follow[Y[i]]:Follow[Y[i]] |= First[Y[j]] - set(Epsilon) # 步骤2 FIRST(β)/~ 加入到FOLLOW(B)中。
PL/0实验报告课程名称编译原理题目名称PL/0编译程序学生学院计算机科学与技术学院专业班级学号学生姓名班内序号山东理工大学实验报告纸第 1 页姓名:蔡鹏飞计算机院_11_级02班同组者成绩_________室温:气压:课程名称:编译原理教师签字实验项目编号(1)PL/0编译程序的分析指导教师鞠传香实验目的1.熟悉pl/0语言并能编写小程序2.掌握pl/0编译程序的编译过程(词法分析、语法分析、语义分析等)实验仪器(编号)材料、工具PC机、VC++6.0(原理概述)pl/0语言编译程序采用以语法分析为核心、一遍扫描的编译方法。
词法分析和代码生成作为独立的子程序供语法分析程序调用。
语法分析的同时,提供了出错报告和出错恢复的功能。
在源程序没有错误编译通过的情况下,调用类pcode解释程序解释执行生成的类pcode代码。
PL/0语言文法的EBNF表示EBNF表示的符号说明。
〈〉:用左右尖括号括起来的中文字表示语法构造成分,或称语法单位,为非终结符。
∷= :该符号的左部由右部定义,可读作'定义为'。
| :表示'或',为左部可由多个右部定义。
{ } :花括号表示其内的语法成分可以重复。
在不加上下界时可重复0到任意次数,有上下界时为可重复次数的限制。
如:{*}表示*重复任意次,{*}38表示*重复3-8次。
[ ] :方括号表示其内的成分为任选项。
( ) :表示圆括号内的成分优先。
例:用EBNF描述<整数>文法的定义:<整数>∷=[+|-]<数字>{<数字>}<数字>∷=0|1|2|3|4|5|6|7|8|9或更好的写法<整数>∷=[+|-]<非零数字>{<数字>}|0<非零数字>∷=1|2|3|4|5|6|7|8|9<数字>∷=0|<非零数字>PL/0语言文法的EBNF表示PL/0语言文法的EBNF表示为:〈程序〉∷=〈分程序〉.〈分程序〉∷=[〈常量说明部分〉][〈变量说明部分〉][〈过程说明部分〉]〈语句〉〈常量说明部分〉∷=CONST〈常量定义〉{,〈常量定义〉};〈常量定义〉∷=〈标识符〉=〈无符号整数〉〈无符号整数〉∷=〈数字〉{〈数字〉}〈变量说明部分〉∷=VAR〈标识符〉{,〈标识符〉};〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉}〈过程说明部分〉∷=〈过程首部〉〈分程序〉{;〈过程说明部分〉};〈过程首部〉∷=PROCEDURE〈标识符〉;〈语句〉∷=〈赋值语句〉|〈条件语句〉|〈当型循环语句〉|〈过程调用语句〉|〈读语句〉|〈写语句〉|〈复合语句〉|〈空〉〈赋值语句〉∷=〈标识符〉∶=〈表达式〉〈复合语句〉∷=BEGIN〈语句〉{;〈语句〉}END〈条件〉∷=〈表达式〉〈关系运算符〉〈表达式〉|ODD〈表达式〉〈表达式〉∷=[+|-]〈项〉{〈加法运算符〉〈项〉}〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}〈因子〉∷=〈标识符〉|〈无符号整数〉|'('〈表达式〉')'〈加法运算符〉∷=+|-〈乘法运算符〉∷=*|/// 栈顶指针减一相关过程:base(),interpret()。
编译原理实验题目编译原理的课程实验既是培养学生理论联系实际的必要手段也是检验我们教学理念的贯彻与实现、检查教学效果、让学生展示能力的重要途径。
为了达到上述目的,作为编译原理课程的上机实验,最好是能完成一个小型语言的基本编译系统,但这需要有较好的实验条件特别是较多的实验学时(理想的情形是专门配置一个两到三周的课程设计)的支撑。
对于一个只有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)返回单词属性(不同的属性可以放在不同的全局变量中)。
实验报告编译原理与技术ytinrete程序设计1题目:词法分析程序的设计与实现。
实验内容:设计并实现C语言的词法分析程序,要求如下。
(1)、可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。
(2)、可以识别并读取源程序中的注释。
(3)、可以统计源程序汇总的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果(4)、检查源程序中存在的错误,并可以报告错误所在的行列位置。
((5)、发现源程序中存在的错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。
实验要求:方法1:采用C/C++作为实现语言,手工编写词法分析程序。
方法2:通过编写LEX源程序,利用LEX软件工具自动生成词法分析程序。
算法思路:首先通过遍历,统计行号和字符数,并记录所有的注释。
其次,再次读取,利用一个字符数组作为buffer保存一行的数据,在对其中的数据进行处理,完成之后再读下一行,跳过注释。
对于整行数据的处理,依靠空格将其分成单个单词再具体处理。
对于查错问题实在是一个难题,只能根据一些规则判定有错并记录。
-程序源代码:==*p || 'E'==*p || 'e'==*p)//小数和指数形式{(1,*p);p++;while(isdigit(*p)){(1,*p);—p++;}}sum_word++;(temp_word);cout<<endl<<"第"<<sum_word<<"个单词:"<<" 无符号数:" <<temp_word<<endl;}}elseif('#'==*p)//预处理文件特殊处理&while('\0'!=*p){(1,*p);p++;}//p指向换行,完成直接退出(temp_word);}else-if('"'==*p)//字符串{();p++;while('"'!=*p){(1,*p);p++;}p++;:sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 字符串:" <<temp_word<<endl;elseif('+'==*p)//处理符号{();if('='==*(p+1))//自加{temp_word = "+=";¥(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自加号:" <<temp_word<<endl;p+=2;//推进}elseif('+'==*(p+1))//自加1{temp_word = "++";(temp_word);—sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自加1号:" <<temp_word<<endl;p+=2;//推进}elseif(isdigit(*(p+1)))//有符号数{temp_word="+";for(int j=1; isdigit(*(p+j));j++)(1,*(p+j));,(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 有符号数:" <<temp_word<<endl;p+=2;//推进}else{temp_word = "+";(temp_word);sum_word++;,cout<<endl<<"第"<<sum_word<<"个单词:"<<" 加号:" <<temp_word<<endl;p+=2;//推进}}elseif('-'==*p)//处理符号{();if('='==*(p+1))//自减{—temp_word = "-=";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自减号:" <<temp_word<<endl;p+=2;//推进}elseif('-'==*(p+1))//自减1{temp_word = "--";、(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自减1号:" <<temp_word<<endl;p+=2;//推进}elseif(isdigit(*(p+1)))//有符号数{temp_word="-";for(int j=1; isdigit(*(p+j));j++)~(1,*(p+j));(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 有符号数:" <<temp_word<<endl;p+=2;//推进}else{temp_word = "-";(temp_word);:sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 减号:" <<temp_word<<endl;p+=2;//推进}}elseif('*'==*p)//处理符号{();if('='==*(p+1))//自乘!{temp_word = "*=";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自乘号:" <<temp_word<<endl;p+=2;//推进}else{temp_word = "*";[(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 乘号:" <<temp_word<<endl;p+=2;//推进}}elseif('/'==*p)//处理符号{'();if('='==*(p+1))//自除{temp_word = "*=";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 自除号:" <<temp_word<<endl;p+=2;//推进}else|if('/'==*(p+1))//行注释return;// 直接跳出elseif('*'==*(p+1))//多行注释{in_comment=true;p+=2;while('\0'!=*p)//判断这行为止注释能不能结束{if(('*'==*p)&&('/')==*(p+1)),{in_comment = false;break;}p++;}}else{temp_word = "/";—(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 除号:" <<temp_word<<endl;p+=2;//推进}}elseif('='==*p)//处理等号{();¥if('='==*(p+1))//比较{temp_word = "==";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 比较号:"<<temp_word<<endl;p+=2;//推进}else{}temp_word = "=";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 赋值号:" <<temp_word<<endl;p+=2;//推进}}elseif('>'==*p)){();if('='==*(p+1)){temp_word = ">=";(temp_word);sum_word++;<<temp_word<<endl;p+=2;//推进}·else{temp_word = ">";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 大于号:" <<temp_word<<endl;p+=2;//推进}}《elseif('<'==*p){();if('='==*(p+1)){temp_word = "<=";(temp_word);sum_word++;<<temp_word<<endl;&p+=2;//推进}else{temp_word = "<";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 小于号:" <<temp_word<<endl;p+=2;//推进}[}elseif('!'==*p){();if('='==*(p+1)){temp_word = "!=";(temp_word);;sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 不等于号:" <<temp_word<<endl;p+=2;//推进}else{temp_word = "!";(temp_word);sum_word++;cout<<endl<<"第"<<sum_word<<"个单词:"<<" 取反号:" <<temp_word<<endl;'p+=2;//推进}}elseif(':'==*p || '('==*p || ')'==*p || ';'==*p || '{' ==*p|| '}'==*p || ','==*p||'['==*p||']'==*p||'\0'==*p||'\n'==*p)//标点不算单词{if('('==*p)small_bracket++;//查错`if(')'==*p)small_bracket--;//查错if('{'==*p)big_bracket++;//查错if('}'==*p)big_bracket--;//查错p++;//推进}else//非法字符{`cout<<endl<<"error: 在第"<<current_line<<"行,出现非法字符:"<<*p<<endl;p++;}}}void analyse(void)//循环填充buffer并进行词法分析{char *p=buffer;(0);//文件指针回到头]while(!()){(*p);if('\n'==*p)//充满一句{*(p+1)='\0';*(p+2)='\0';current_line++;word_analyse();if(0!=small_bracket),{cout<<endl<<"error: 在第"<<current_line<<"行,小括号不匹配!"<<endl;small_bracket=0;}p=buffer;//重新填充}elsep++;{}if(0!=big_bracket)cout<<endl<<"error: 大括号不匹配!"<<endl;}void show_result(void)//显示统计结果{cout<<endl<<"the number of words is:"<<sum_word<<endl;cout<<endl<<"the number of char is:"<<sum_char<<endl;cout<<endl<<"the number of line is:"<<sum_line<<endl;¥cout<<"the followings are header:"<<endl;for(int i=0; i<(); i++){cout<<(i);}cout<<"the followings are comment:"<<endl;for(int i=0; i<(); i++){cout<<(i);}$}int main(void){("");if(NULL==file)》cout<<endl<<"找不到文件!"<<endl;else{//开始处理init();//初始化关键字analyse();();sum();//统计行数字节数注释show_result();//显示统计结果}int test;cin>>test;return 0;}实验结果测试:正常文件运行结果:有问题文件:运行结果:。
例1设有文法G[S]:S →a|(T )| T →T,S|S (1) 试给出句子(a,a,a)的最左推导。
(2) 试给出句子(a,a,a)的分析树 (3) 试给出句子(a,a,a)的最右推导和最右推导的逆过程(即最左规约)的每一步的句柄。
【解】(1) (a,a,a)的最左推导S=>(T) =>(T,S) =>( T,S,S) =>( S,S,S) =>(a,S,S) =>(a,a,S) =>(a,a,a) (2)(a,a,a)的分析树S( T ) T , S S T ,S aa(3) (a,a,a)最右推导 最左规约每一步的句柄S=>(T) 句柄为:(T) =>(T,S) 句柄为:T,S =>(T,a) 句柄为:a =>(T,S,a) 句柄为:T,S =>(T,a,a) 句柄为:第一个a =>(S,a,a) 句柄为:S=>(a,a,a) 句柄为:第一个a例2已知文法G[Z]:Z →0U|1V U →1Z|1 V →0Z|0(1) 请写出此文法描述的只含有4个符号的全部句子。
(2) G [Z]产生的语言是什么? (3) 该文法在Chomsky 文法分类中属于几型文法? 【解】(1)0101,0110,1010, 1001(2)分析G[Z]所推导出的句子的特点:由Z 开始的推导不外乎图1所示的四种情形。
图 1文法G[Z]可能的几种推导Z1U Z UZ1Z1Z1V由Z 推导出10或01后就终止或进入递归,而Z 的每次递归将推导出相同的符号串:10或01。
所以G[Z]产生的语言L(G[Z])={x|x∈(10|01)+ }(3)该文法属于3型文法。
例3 已知文法G=({A,B,C},{a,b,c},P,A), P由以下产生式组成:A→abcA→aBbcBb→bBBc→CbccbC→CbaC→aaBaC→aa此文法所表示的语言是什么?【解】分析文法的规则:每使用一次Bc→Cbcc,b、c的个数各增加一个;每使用一次aC→aaB或aC→aa, a的个数就增加一个;产生式Bb→bB、 bC→Cb起连接转换作用。
Pl/0语言文法的BNF表示:〈程序〉→〈分程序>.〈分程序〉→ [<常量说明部分>][<变量说明部分>][<过程说明部分>]〈语句〉 <常量说明部分> → const<常量定义>{ ,<常量定义>};<常量定义> → <标识符>=<无符号整数><无符号整数> → <数字>{<数字>}<变量说明部分> → var<标识符>{ ,<标识符>};<标识符> → <字母>{<字母>|<数字>}<过和说明部分> → <过程首部><分程度>;{<过程说明部分>}<过程首部> → procedure<标识符>;<语句> → <赋值语句>|<条件语句>|<当型循环语句>|<过程调用语句>|<读语句>|<写语句>|<复合语句>|<空><赋值语句> → <标识符>:=<表达式><复合语句> → begin<语句>{ ;<语句>}<end><条件> → <表达式><关系运算符><表达式>|ood<表达式><表达式> → [+|-]<项>{<加减运算符><项>}<项> → <因子>{<乘除运算符><因子>}<因子> → <标识符>|<无符号整数>|(<表达式>)<加减运符> → +|-<乘除运算符> → *|/<关系运算符> → =|#|<|<=|>|>=<条件语句> → if<条件>then<语句><过程调用语句> → call<标识符><当型循环语句> → while<条件>do<语句><读语句> → read(<标识符>{ ,<标识符>})<写语句> → write(<标识符>{,<标识符>})<字母> → a|b|c…x|y|z<数字> → 0|1|2…7|8|9一.为PL/0语言建立一个词法分程序GETSYM(函数)把关键字、算符、界符称为语言固有的单词,标识符、常量称为用户自定义的单词。
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)。
编译原理上机实验试题
一、实验目的
通过本实验使学生进一步熟悉和掌握程序设计语言的词法分析程序的设计原理及相关的设计技术,
如何针对确定的有限状态自动机进行编程序;熟悉和
掌握程序设计语言的语法分析程序的设计原理、熟悉
和掌握算符优先分析方法。
二、实验要求
本实验要求:①要求能熟练使用C++程序设计语言编程;②在上机之前要有详细的设计报告(预习报
告);③要编写出完成相应任务的程序并在计算机上
准确地运行;④实验结束后要写出上机实验报告。
三、实验题目
针对下面文法G(S):
S→v = E
E→E+E│E-E│E*E│E/E│(E)│v │i 其中,v为标识符,i为整型或实型数。
要求完成
①使用自动机技术实现一个词法分析程序;
②使用算符优先分析方法实现其语法分析程序;
③在语法分析过程中同时完成常量表达式的计算。
#include <iostream>
#include<string>
using namespace std;
FILE*fileP;
char a[100];
void Ee();
void T();
void Tt();
void F();
void E();
int i=0;
int j=0;
int flag=0;
boolis letter(char c)
{if((c>='A&&c<='Z')||(c>'a'&&c<='z')) return true;
else return false;}
boolisDigit(char c)
{if(c>='0'&&c>='9')
return true;
else return false;}
void read()
{
if(fgetc(fileP)=='#'){
char c=fgetc(fileP);
while (c!='#')
{
a[j++]=c;
fgetc(fileP);
}
}
}
void E()
{T();
Ee();}
void Ee()
{
if(a=='+')
{
i++;
T();
Ee();
}
}
void T()
{
F();
Tt();
}
void Tt()
{
if(a=='*')
{
i++;
F();
Tt();
}
}
void F()
{
char c=a;
if(isLetter(c))
{
while (isDigit(c)||isLetter(c))
{
i++;
c=a;
}
}
else if (isDigit(C))
{
while (isDigit(c))
{
i++;
c=a;
}
}
else if(c=='(')
{
i++;
F();
if(a==')')
{
}
else flag=1;
}
else flag=1;
}
void main()
{
if((fileP=fopen("test.txt","r"))==NULL)
{
cout<<"请创建test.txt资源文件"<<endl;} else
{
read ();
cout<<"----------text文件词法分析结果如下----------"<<endl;
E();
if (flag==0)
cout<<"success"<<endl;
else cout<<"fail"<<endl;
cout<<"------------------"<<endl;
}
if ((fileP=fopen("text.txt","r"))==NULL)
{
cout<<"
请创建test2.txt
资源文件<<endl;。