中南大学软件学院编译原理实验报告.docx
- 文档编号:923723
- 上传时间:2023-04-30
- 格式:DOCX
- 页数:19
- 大小:200.55KB
中南大学软件学院编译原理实验报告.docx
《中南大学软件学院编译原理实验报告.docx》由会员分享,可在线阅读,更多相关《中南大学软件学院编译原理实验报告.docx(19页珍藏版)》请在冰点文库上搜索。
中南大学软件学院编译原理实验报告
《320144X1(编译原理)》
实验报告
项目名称编译原理
专业班级软件工程1403
学号
姓名温睿诚
实验成绩:
批阅教师:
年月日
第一部分词法分析(实验一必作)
实验一词法分析程序设计与实现
实验报告要求
详细说明你的程序的设计思路和实现过程。
用有限自动机或者文法的形式对词法定义做出详细说明,说明词法分析程序的工作过程,说明错误处理的实现。
设计思路:
首先把单词进行分类,分为
String[]keyword={"if","int"};
ArrayList
ArrayList
String[]yunsuan={"+","=","-",">","==","!
="};
String[]spilt={",","(",")","{","}",";"};
五类,分别是关键字、标识符、常数、运算符以及分隔符。
然后逐个字符读入,对于关键字或标识符这类英文单词开始的单词,用空格隔开,其他可以用分隔符、运算符、空格、回车等。
读入一个单词后对照一开始的五类分析出是哪一类,符合后交给语法分析器处理。
实现过程:
importjava.io.*;
importjava.util.ArrayList;
/**
*Createdby温睿诚on2016/5/11/0011.
*/
publicclassCiFa{
String[]keyword={"if","int"};
ArrayList
ArrayList
String[]yunsuan={"+","=","-",">","==","!
="};
String[]spilt={",","(",")","{","}",";"};
//记录结果的符号表
//用什么数据结构呢?
//当前单词
StringBuilderstr=newStringBuilder("");
//下一个要读的字符
charnow;
//一个栈
ArrayList
privatevoidput(){
stack.add(newCharacter(now));
}
privatecharpop(){
if(stack.size()>0){
return((Character)stack.remove(stack.size()-1)).charValue();
}else{
return0;
}
}
//错误信息
StringerrorMsg;
Readerreader=null;
publicstaticvoidmain(String[]args){
CiFacifa=newCiFa();
cifa.fenXi(args[0]);
}
privatevoidfenXi(Stringfilename){
//读取文件
Filefile=newFile(filename);
try{
reader=newInputStreamReader(newFileInputStream(file));
}catch(FileNotFoundExceptione){
System.out.println("读取文件字符失败!
");
e.printStackTrace();
}
//不断读取字符直到结束
getChar();
intresult;
//使用预测分析法
YuFayuFa=newYuCeFenXi();
booleanflag=true;
while(!
(now<0||now>=65535)){
//根据返回数值查找或插入,错误则打印并提示。
正确则记录到map
result=read();
if(result!
=6){
System.out.println("("+result+",\""+str+"\")");
if(!
yuFa.fenxi(result,str.toString())){
flag=false;
System.err.println("语法分析出错!
出错单词:
"+str.toString());
}
}else{
System.err.println("("+errorMsg+",\""+str+"\")");
}
str.delete(0,str.length());
}
//结束
booleantempResult=false;
if(yuFa!
=null)
tempResult=yuFa.fenxi(6,"#");
if(tempResult&&flag)
System.out.println("语法分析通过!
");
}
//判断是否为数字
privatebooleanisDigit(){
if('0'<=now&&now<='9')
returntrue;
else
returnfalse;
}
//判断是否为字母
privatebooleanisLetter(){
if(('a'<=now&&now<='z')||('A'<=now&&now<='Z'))
returntrue;
else
returnfalse;
}
//赋值下一字符给now,返回true表示读到空格、换行等空白字符
privatebooleangetChar(){
booleanflag=false;
try{
now=(char)reader.read();
while(now==0||now=='\t'||now=='\r'||now=='\n'||now==32){
flag=true;
now=(char)reader.read();
}
}catch(IOExceptione){
e.printStackTrace();
}
returnflag;
}
//连接字符到单词
privatevoidconcat(){
str.append(now);
}
privatebooleanisSpilt(){
Stringtemp=String.valueOf(now);
for(Stringstr:
spilt){
if(str.startsWith(temp)){
returntrue;
}
}
returnfalse;
}
privatebooleaninAL(Stringstr,ArrayList
if(strings.contains(str))
returntrue;
returnfalse;
}
privatebooleaninShuzu(Stringstr,String[]strings){
for(Stringstr1:
strings){
if(str.equals(str1)){
returntrue;
}
}
returnfalse;
}
privatebooleanisYun(){
Stringtemp=String.valueOf(now);
for(Stringstr:
yunsuan){
if(str.startsWith(temp)){
returntrue;
}
}
returnfalse;
}
//词法分析器
privateintread(){
if(isLetter()){
//字母开始的,要么关键字,要么标识符,其用空格、tab、回车之类的分隔,
//而标识符还可以用分割符号、运算符号分割。
暂不判断标识符是否定义
concat();
booleanflag;
flag=getChar();
while((isDigit()||isLetter())&&flag==false){
concat();
flag=getChar();
}
if(inShuzu(str.toString(),keyword)){
return1;
}else{
if(!
inAL(toString(),biaoshi)){
biaoshi.add(str.toString());
}
return2;
}
}elseif(isDigit()){
//数字开头的,是常数,以空格、tab等以及分隔符、运算符分割
concat();
getChar();
while(isDigit()){
concat();
getChar();
}
return3;
}elseif(isSpilt()){
//分隔符,当出现{、(时入栈,接收到}、)时判断是否符合。
单个字符,不需要分隔
if(now=='{'||now=='('){
put();
}elseif(now=='}'){
chartemp=pop();
if(temp!
='{'){
errorMsg="没有'{'与'}'匹配";
concat();
getChar();
return6;
}
}elseif(now==')'){
chartemp=pop();
if(temp!
='('){
errorMsg="没有'('与')'匹配";
concat();
getChar();
return6;
}
}
concat();
getChar();
return5;
}elseif(isYun()){
//运算符,一般为单个符号,例外如下
concat();
if(now=='<'||now=='>'||now=='!
'){
getChar();
if(now=='='){
concat();
getChar();
}
}else{
getChar();
}
return4;
}else{
//ERROR
errorMsg="无法识别\""+now+"\"";
concat();
getChar();
return6;
}
}
}
结果:
对于文件:
输出:
等
第二部分语法分析(任选其中一个做实验)
实验二预测分析法设计与实现
实验报告要求
详细说明你的程序的设计思路和实现过程。
实验报告要求用文法的形式对语法定义做出详细说明,说明语法分析程序的工作过程,说明错误处理的实现。
设计思路:
首先写出文法,然后作出预测分析表,再根据算法查表判断是否符合改文法。
这是自己写的文法。
模仿C++文法,但有不少局限性。
实现过程:
importjava.util.Stack;
/**
*Createdby温睿诚on2016/6/1/0001.
*预测分析法
*/
publicclassYuCeFenXiimplementsYuFa{
Stack
String[]t={"int"};
String[]o={"+","-"};
String[]k={"if"};
String[]c={">","==","!
="};
String[]spilt={",","(",")","{","}",";"};
privatestaticString[][]map=newString[15][14];
//横排SABCNDEFGHIJKL
//对应1234567891011121314
//竖排tbz(o),;=k{}#
//对应12345678910111213
YuCeFenXi(){
//null即出错,空字符串即空字
map[1][1]="tb(A){N}S";
map[1][13]="#";
map[2][1]="B";
map[2][6]="";
map[3][1]="tbC";
map[4][6]="";
map[4][7]=",tbC";
map[5][1]="tbD;N";
map[5][2]="bI;N";
map[5][10]="k(E){N}N";
map[5][12]="";
map[6][7]=",bD";
map[6][8]="";
map[7][2]="bJ";
map[7][3]="F";
map[8][3]="zG";
map[9][5]="oHcH";
map[9][6]="";
map[10][2]="b";
map[10][3]="z";
map[11][4]="(A)";
map[11][9]="=K";
map[12][4]="(A)";
map[12][5]="oHcH";
map[12][6]="";
map[13][2]="HL";
map[13][3]="HL";
map[14][5]="oHL";
map[14][8]="";
stack=newStack<>();
stack.push("#");
stack.push("S");
}
//判断是否非终结符
privatebooleanisN(Stringstr){
if(str.length()!
=1)
returnfalse;
chartemp=str.charAt(0);
if((temp>='A'&&temp<='L')||(temp=='S')||temp=='N')
returntrue;
returnfalse;
}
//把非终结符转换为表中对应数字
privateintn2I(Stringstr){
chartemp=str.charAt(0);
switch(temp){
case'S':
return1;
case'A':
return2;
case'B':
return3;
case'C':
return4;
case'N':
return5;
default:
returntemp-'A'+3;
}
}
//把终结符转换为表中对应数字
privateintt2I(Stringstr){
chartemp=str.charAt(0);
switch(temp){
case't':
return1;
case'b':
return2;
case'z':
return3;
case'(':
return4;
case'o':
return5;
case')':
return6;
case',':
return7;
case';':
return8;
case'=':
return9;
case'k':
return10;
case'{':
return11;
case'}':
return12;
case'#':
return13;
default:
return-1;
}
}
privatebooleaninArray(Stringstr,String[]array){
for(Stringtemp:
array){
if(str.equals(temp))
returntrue;
}
returnfalse;
}
publicstaticbooleanisNumeric(Stringstr){
for(inti=0;i System.out.println(str.charAt(i)); if(! Character.isDigit(str.charAt(i))){ returnfalse; } } returntrue; } //若word是常规终结符如{,;则返回原值,若是int这种,则返回t publicStringword2T(inttype,Stringword){ switch(type){ case1: if(inArray(word,t)) return"t"; elseif(inArray(word,k)) return"k"; else returnnull; case2: return"b"; case3: return"z"; case4: if(inArray(word,o)) return"o"; elseif(inArray(word,c)) return"c"; elseif(word.equals("=")) returnword; else returnnull; case5: returnword; case6: returnword; default: returnnull; } } @Override publicbooleanfenxi(inttype,Stringstr){ Stringstr1=stack.peek();//str1是栈顶符号 //str是当前输入符号 if(! isN(str1)){ //栈顶符号是终结符 if(str1.equals("#")&&str.equals(str1)){ //System.out.println("语法分析通过"); returntrue; }elseif(str1.equals(word2T(type,str))){ stack.pop(); returntrue; }else{ returnfalse; } }else{ //栈顶符号是非终结符 Stringchanshengshi=map[n2I(str1)][t2I(word2T(type,str))]; if(chanshengshi==null) returnfalse; else{ stack.pop(); for(inti=chanshengshi.length()-1;i>=0;i--){ stack.push(String.valueOf(chanshengshi.charAt(i))); } //这里写语义分析 returnfenxi(type,str); } } } } 结果: 对于输入文件: 输出: 对于输入文件: 输出: 实验四递归下降分析法设计与实现 实验报告要求 详细说明递归下降分析法程序的工作过程,并且详细说明你的程序的设计思路和实现。 设计思路: 根据文法写几个函数即可。 这是这次实验的文法(之前自己写的文法画出的LL (1)分析表实在太大了,画不下去……就换了个实验做): /*文法 E→T{+T} T→F{*F} F→i F→(E) */ 实现: importjava.util.Scanner; /** *Createdby温睿诚on2016/6/12/0012. */ publicclassDiGuiDown{ /*文法 E→T{+T} T→F{*F} F→i F→(E) */ staticScannerscanner; staticStringsym; staticbooleanflag=true; publicstaticvoidmain(String[]args){ scanner=newScanner(System.in); advance(); E(); if(flag){ System.out.println("合法字符串"); }else{ System.err.println("非法字符串"); } } privatestaticvoidadvance(){ if(scanner.hasNext()){ sym=scanner.next(); } } privatestaticvoidE(){ T(); while(sym.equals("+")){ advance(); T(); } } privatestaticvoidT(){ F(); while(sym.equals("+")){ advance(); F(); } } privatestaticvoidF(){ if(sym.equals("i")){ advance(); }else{ if(sym.equals("(")){ advance(); E(); if(sym.equals(")")){ advance(); }else{ //error flag=false; System.err.println("此处应该输入),但输入了"+sym); } }else{ //error flag=false; System.err.println("此处应该输入(,但输入了"+sym); } } } } 结果:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 中南 大学 软件 学院 编译 原理 实验 报告