《编译原理实验报告--词法分析器(共18页).docx》由会员分享,可在线阅读,更多相关《编译原理实验报告--词法分析器(共18页).docx(18页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上编译原理实验词法分析器 一、 实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。同时增强编写和调试程序的能力。二、 实验内容及要求对某特定语言A ,构造其词法规则。该语言的单词符号包括:保留字(见左下表)、标识符(字母大小写不敏感)、 整型常数、界符及运算符(见右下表) 。 功能要求如下所示:按单词符号出现的顺序,返回二元组序列,并输出。出现的标识符存放在标识符表,整型常数存放在常数表,并输出这两个表格。如果出现词法错误,报出:错误类型,位置(行,列)
2、。处理段注释(/* */),行注释(/)。有段注释时仍可以正确指出词法错误位置(行,列)。三、 实验过程1、 词法形式化描述使用正则文法进行描述,则可以得到如下的正规式:其中ID表示标识符,NUM表示整型常量,RES表示保留字,DEL表示界符,OPR表示运算符。 A(ID | NUM | RES | DEL | OPR) *IDletter(letter | didit)*NUMdigit digit*lettera | | z | A | | Zdigit 0 | | 9RES program | begin | end | var | int | and | or | not | if |
3、 then | else | while | doDEL( | ) | . | ; | ,OPR+ | * | := | | = | = | 如果关键字、标识符和常数之间没有确定的算符或界符作间隔,则至少用一个空格作间隔。空格由空白、制表符和换行符组成。2、 单词种别定义;A语言中的单词符号及其对应的种别编码如下表所示:单词符号种别编码单词符号种别编码program1+16begin2*17end3(18var4)19int5,20and6.21or7:=22not8;23if924then10=27do13=28标识符1429整型常量15-303、 状态转换图;语言A的词法分析的状态转换图如
4、下所示:空格符,制表符 或回车符 字母或数字非字母或数字2字母01 数字非数字3+4数字587*633()2224非=其他-142513812):9,.=101115;/16=28/*2627其他23=171819非=212025其他4、 运行环境介绍;本次实验采用MyEclipse进行代码的编写和编译及运行,编写语言为java语言;程序的运行环境为windows 7 旗舰版5、 关键算法的流程图及文字解释;程序中用到的函数列表:A类定义各种类函数以及包含主函数public static void main()变量ch储存当前最新读进的字符的地址strToken存放当前字符串main() /主
5、函数Analysis()/分析函数,每次读入一行文件,进行识别处理;char GetChar(); /取得当前位置的字符的内容放入ch,并提前指向下一个字符;char GetNextChar();/取得当前位置的下一位置的字符,String ConCat(); /将ch指向的字符连接到strToken后面isLetter(); /判断ch指向的字符是否字母isDigit(); /判断ch指向的字符是否数字add(p,str); /向p表中插入当前strToken的字符串Boolean findKeyWord(str); /检测当前strToken中的字符串是否保留字,若是,则执行getKeyW
6、ordKey(str),返回保留字的id,否则,判别其是否是已存在的标示符,若是,返回标示符的id以及该标示符在表中的位置;findPunctuation()/判断是否是一个保留的符号;getindex() /返回已经识别的标示符或者是数字的位置下标;Boolean exist(); /检测当前strToken中的字符串是否在标识符表中已存在,若是,则返回true,否则返回falsevoid callError(); /出错处理过程,将错误的位置报告出来(1)main()函数的流程图如下:开始类初始化,变量的初始化,准备执行main()函数调用Analyse()函数分析输出结果表结束(2)具体
7、分析流程图: Analyse(str)函数读取第一个字符赋给变量Ch判断ch内容?如果ch是字符,则转入标示符与保留字判断程序如果ch是数字,则转入数字判别处理程序如果ch是标点,那么在标点的保留表中查找符号如果ch是空字符,那么就转到空字符处理程序处理CallError()处理程序报错判别出符号之后,Ch=NextChar(),index未超界返回main()函数 继续判读 IndexoutofBound6、测试报告(测试用例,测试结果);首先输入一个不含错误的程序(两种注释)进行检测:运行后在控制台上得到的结果如下所示:得到的二元组序列如下:经检验,输出的是正确的二元组序列。再输入一个含有
8、错误的程序(含有注释)进行检验:运行后在控制台上得到的结果如下所示:经检验,错误的位置是正确的如果是空文件,编译也会通过; 四、 实验总结通过本次试验,我加深了对编译原理中的词法分析的理解,同时通过动手,更加锻炼了自己。本次试验由于使用的刚刚学习的java语言,通过这次机会加强了自己对java语言的熟悉的使用。在这次试验中,感谢老师的认真的讲解与同学的无私的帮助。总结来说,自己在这次试验中收获很大。附:以下为本次实验的源代码: package Analysis;import java.io.BufferedReader;import java.io.File;import java.io.Fi
9、leReader;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.Map;public class A private static char ch;private static String strToken;private static int index = 0;private static int line = 1;private static boolean noteTag=false;private Map keywords;private
10、 HashMap punctuations; private static ArrayList p=new ArrayList(); private static ArrayList q=new ArrayList();/ get and set 函数public char getCh() return ch;public void setCh(char ch) A.ch = ch;public String getStrToken() return strToken;public void setStrToken(String strToken) A.strToken = strToken;
11、public void setPunctuations(HashMap punctuations) this.punctuations = punctuations;public Map getPunctuations() return punctuations;public void setKeywords(Map keywords) this.keywords = keywords;public Map getKeywords() return keywords;/ 构造函数public A() this.keywords = new HashMap();keywords.put(1,Pr
12、ogram);keywords.put(2,begin);keywords.put(3,end);keywords.put(4,var);keywords.put(5,int);keywords.put(6,and);keywords.put(7,or);keywords.put(8,not);keywords.put(9,if);keywords.put(10,then);keywords.put(11,else);keywords.put(12,while);keywords.put(13,do);this.punctuations = new HashMap();punctuations
13、.put(+, 16);punctuations.put(*, 17);punctuations.put(, 18);punctuations.put(), 19);punctuations.put(, 20);punctuations.put(;, 21);punctuations.put(:=, 22);punctuations.put(, 23);punctuations.put(=, 24);punctuations.put(, 25);punctuations.put(=, 26);punctuations.put(., 27);punctuations.put(, 28);punc
14、tuations.put(=, 29);/ 函数定义(词法分析函数)public boolean Analyse(char strArray) index = 0;/ 每次分析一行完成后就将index置0char temp1;int rowLength = strArray.length;outer:while (index ) if( temp1=this.getNextChar(strArray)=) System.out.println(24,=); else index-; System.out.println(23,); else if(ch=) if( temp1=this.get
15、NextChar(strArray)=) System.out.println(26,) System.out.println(28,); else index-; System.out.println(25,); else if(ch=*& noteTag=false) System.out.println(17,*); else if (java.lang.Character.isLetter(ch)¬eTag=false) strToken = contact(strToken, ch);ch = getNextChar(strArray);while (java.lang.Cha
16、racter.isLetter(ch)| (java.lang.Character.isDigit(ch) strToken = contact(strToken, ch);ch = getNextChar(strArray);index-;/ System.err.println(!+strToken);if (findKeyword(strToken) /System.out.println(15, + strToken.toString() + )n);int i=getKeyWordKey(strToken);System.out.println(+i+,-); elseif(!exi
17、st(p,strToken) p.add(strToken);int i=getindex(p,strToken);/System.out.println(14, + strToken.toString() + )n);System.out.println(14,+i+); else if (java.lang.Character.isDigit(ch)¬eTag=false) strToken = this.contact(strToken, ch);ch = this.getNextChar(strArray);while (java.lang.Character.isDigit(c
18、h) strToken = this.contact(strToken, ch);ch = this.getNextChar(strArray);index-;/System.out.println(15, + strToken.toString() + )n); if(!exist(q,strToken) q.add(strToken); int i=getindex(q,strToken); System.out.println(15,+i+);strToken = ; else if (ch = /|noteTag=true) int startj=index; /注释起始位置标记int
19、 starti=line;if(noteTag=false) /System.out.println(该部分是注释注释,从第+starti+行第+startj+列开始); char temp = this.getNextChar(strArray);if (temp = *¬eTag=false) temp = this.getNextChar(strArray);while(index=rowLength)noteTag=true;break outer;else if(noteTag=true&ch!=*) while(index=rowLength)break outer; els
20、e return false; else String key = String.valueOf(ch);if (this.findPunctuation(key) System.out.println(+this.getPunctuation(key)+,+ key + ); else if (key.equals( ) | key.equals( ) / *?*break; elsereturn false; /System.out.println( 未知符号 + key + n); /strToken = ;return true;public char GetChar(char arr
21、ay) try while (arrayindex) = ) index+;index+;/ 提前指向下一个字符* catch (ArrayIndexOutOfBoundsException e) return ;return arrayindex - 1;public char getNextChar(char strChar) index+;return strCharindex - 1;public String contact(String token, char ch) return token + String.valueOf(ch);public boolean findKeyw
22、ord(String str) for(int i=0;i13;i+)if(str.equalsIgnoreCase(this.keywords.get(i)return true;return false;public boolean findPunctuation(String str) if (this.punctuations.containsKey(str) return true; elsereturn false;public int getPunctuation(String str) return this.punctuations.get(str);public boole
23、an Clean() return true;public void callError(int line) System.out.println(出现错误,错误位置在第 + line + 行,第 + index + 列);public boolean exist(ArrayList p,String strToken)if(p.contains(getStrToken()return true;elsereturn false;public int getKeyWordKey(String str)for(int i=1;i=13;i+)if(str.equalsIgnoreCase(thi
24、s.keywords.get(i)return i;return 10000; public int getindex(ArrayList p,String Str) return p.lastIndexOf(Str)+1; /*int j=0; for(int i=0;ip.size();i+) if(p.get(i).equals(Str) j+; return j;*/ public static void main(String args) File file = new File(F:sample.txt);A a = new A();char strChar = new char1
25、00;/ 限制每行代码字符数不超过100BufferedReader reader = null;try /System.out.println(以行为单位读取文件内容,一次读一整行:);reader = new BufferedReader(new FileReader(file);String tempString = null;/ int line = 1;/ 一次读入一行,直到读入null为文件结束while (tempString = reader.readLine() != null) / 显示行号/System.out.println(line + line + : + temp
26、String);strChar = tempString.toCharArray();boolean flag = a.Analyse(strChar);if (flag = true)line+;else a.callError(line);break;System.out.println(标示符表);System.out.println(p.toString();System.out.println(常数表);System.out.println(q.toString();reader.close(); catch (IOException e) e.printStackTrace(); finally if (reader != null)try reader.close(); catch (IOException e1) / TODO Auto-generated catch blocke1.printStackTrace();专心-专注-专业