首页 编译原理-词法分析

编译原理-词法分析

举报
开通vip

编译原理-词法分析编译原理实验报告 词法分析器与语法分析器 I. 问题描述 设计、编制并调试一个词法分析子程序,完成识别语言单词的任务; 设计、编制、调试一个语法分析程序,并用它对词法分析程序所提供的单词序列进行语法检查和结构分析。 ii. 设计简要描述 界面需求: 为了更加形象的模拟过程,此实验使用图形界面。要求从图形界面上输入输入串,点击词法分析,可以将词法分析后识别的单词符号显示,点击语法分析,可以将语法分析的堆栈过程显示,并且显示结果(是否是符合文法的句子),清空则可以将所有置空...

编译原理-词法分析
编译原理实验报告 词法分析器与语法分析器 I. 问题描述 设计、编制并调试一个词法分析子程序,完成识别语言单词的任务; 设计、编制、调试一个语法分析程序,并用它对词法分析程序所提供的单词序列进行语法检查和结构分析。 ii. 设计简要描述 界面需求: 为了更加形象的模拟过程,此实验使用图形界面。要求从图形界面上输入输入串,点击词法分析,可以将词法分析后识别的单词符号显示,点击语法分析,可以将语法分析的堆栈过程显示,并且显示结果(是否是符合文法的句子),清空则可以将所有置空。 功能分析: 1、 由用户输入输入串; 2、 用户点击“词法分析”,可以将词法分析后识别的单词符号显示。 3、 用户点击语法分析,可以将语法分析的堆栈过程显示,并且显示结果(是否是符合文法的句子) 4、 用户点击清空,则将界面所有组件置为空 思路描述: 一、设计构想: 本实验决定编写一个简易C语言的词法分析器和语法分析器。使其能够识别while,if等关键字,可以判断赋值语句、条件语句、循环语句。 2、 文法分析 1、需要识别的关键字及其识别码有: 关键字 识别码 关键字 识别码 关键字 识别码 main 0 - 11 ; 22 int 1 * 12 > 23 char 2 / 13 < 24 if 3 ( 14 >= 25 else 4 ) 15 <= 26 for 5 [ 16 == 27 while 6 ] 17 != 28 ID 7 { 18 ERROR -1 NUM 8 } 19 = 9 , 20 2、 + 10 : 21 3、 文法 〈程序〉→ main()〈语句块〉 〈语句块〉→{〈语句串〉} 〈语句串〉→〈语句〉;〈语句串〉|〈语句〉; 〈语句〉→〈赋值语句〉|〈条件语句〉|〈循环语句〉 〈赋值语句〉→ ID =〈 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 达式〉; 〈条件语句〉→ if〈条件〉〈语句块〉 〈循环语句〉→ while〈条件〉〈语句块〉 〈条件〉→(〈表达式〉〈关系符〉〈表达式〉) 〈表达式〉→〈表达式〉〈运算符〉〈表达式〉|(〈表达式〉)|ID|NUM 〈运算符〉→+|-|*|/ 〈关系符〉→<|<=|>|>=|=|!> 转化为符号表示: S→ main() K|空 K→ { C } C→Y;C |空 Y→F | T | X F→ ID = B T→ if J K X→ while J K J→( B G B ) B→ B Z B |( B )| ID | NUM Z→ + | - | * | / G→< | <= | > | >= | == | !> 表示含义: S:程序 K:语句块 C:语句串 Y:语句 F :赋值语句 T:条件语句 X:循环语句 J:条件 B:表达式 I:项 Z :运算符 G:关系符 4、 LL(1)分析表 (1),求出first集及follow集: FIRST(S)={mian} FIRST(K)={{} FIRST(C)= FIRST(Y)= {ID,if,while,空}; FIRST(Y)= FIRST(F)+ FIRST(T)+ FIRST(X)={ID,if,while}; FIRST(F)={ID}; FIRST(T)={if}; FIRST(X)={while}; FIRST(J)= FIRST(B)={}; FIRST(B)={(,ID,NUM }; FIRST(Z)={+,-,*,/} FIRST(G)={ <, <= ,>,>=,==,!= }; FOLLOW(S)={#}; FOLLOW(K)={;}; FOLLOW(C)={}}; FOLLOW(Y)={;} FOLLOW(F)={;}; FOLLOW(T)={;}; FOLLOW(X)={;}; FOLLOW(J)={{,;}; FOLLOW(B)={+,-,*,/,),<, <= ,>,>=,==,!=,;}; FOLLOW(B’)={+,-,*,/,),<, <= ,>,>=,==,!=,;}; FOLLOW(Z)={(,ID,NUM }; FOLLOW(G)={(,ID,NUM }; (2)消除左递归,拆分文法关系并编号 0、S→ 空 1、S→ main() K 2、K→ { C } 3、 C→Y;C 4、 C→空 5、Y→ F 6、Y→ T 7、Y→ X 8、F→ ID = B 9、 T→ if J K 10、X→ while J K 11、 J→( B G B ) 12、 B→ ( B )B' 13、B→ ID B' 14、B→ NUM B' 15、B'→ BZB B' 16、B'→ 空 17、 Z→ + 18、 Z→ - 19、 Z→ * 20、 Z→ / 21、 G→ < 22、 G→ <= 23、 G→ > 24、 G→ >= 25、 G→ == 26、 G→ != (3)构造LL(1)分析表 (注:在表中用上一步的编号表示所需要的产生式) main 空 ( ) { } ; = if while ID num + - * / < <= > >= == != # S 1 0 K 2 C 4 4 3 3 3 Y 6 7 5 F 8 T 9 X 10 J 11 B 12 13 14 B' 16 15 16 16 15 15 16 16 16 16 16 16 16 16 16 16 Z 17 18 19 20 G 21 22 23 24 25 26 iii. 详细设计描述 项目构架: 各函数功能介绍: 1、word.wordList包(存储了关键字): word:此类是定义了存储关键字的结构:包括String型的关键字,和int型的识别符。 wordList:此类存储了29个关键字,在构造函数中初始化。 2、word包(进行词法分析)中: basicFunction:此类定义了做词法分析的基本函数: GetChar()将下一输入字符读到ch中,搜索知识器前移一个字符位置 GetBC();检查ch中的字符是否为空白。若是,则调用GetChar直至不 是字符为止 Concat();将ch中的字符连接到strToken之后 IsLetter();判断ch中的字符是否为字母 IsDigit();判断ch中的字符是否为数字 Reserve();对strToken中的字符创查找保留字表,若是则返回它的编码,否则返回0 Retract();将搜索指示器回调一个字符位置 RetractStr();将strToken置空 lexAnalysis:此类是用来进行词法分析,将分析后的单词存入word数组中,(注:在词法分析中,若是一串字母,则认为是ID,若是数字,则认为是NUM。存储的时候识别符分别存ID与NUM的识别符,但是内容仍然是自己的内容) 其中的wordAnalysis函数就是词法分析函数(具体实现请看后面的重要函数分析) 3、stack包(定义栈)中: 栈是通过链表来定义的,因此 StringListElement:次类定义了链表的每一个节点 StringStrack:此类定义了栈,其中有长度属性,有函数: Top();用来取得栈顶 Push();压栈 Pop();出栈 4、sentence包(语法分析)中: juzi :定义了文法的句子的结构:key(左边部分) content[](右边推出的部分) lo(长度) grammar :存储了文法的27个关系式 AnalysisFB :定义了分析表的存储结构 AnalysisF :存储分析表 SentenceAnalysis :语法分析 JuProduction(word w):此函数是用来判断在当前栈与输入串的情况下,用哪一个产生式,返回产生式在数组中的下标 若输入串的第一个字符与栈顶字符相同则表示可以规约,则返回-1; 若不能过用产生式,则返回-2; AnalysisBasic(word w):此函数是分布进行语法分析,对栈操作 * 根据所需要的产生式对符号栈进行操作 * 返回0表示规约;返回1表示移进;否则表示输入串不是文法的句子 5. Main包(主界面)中 Main:此类定义了图形界面 重要函数分析: 一、词法分析函数: 当搜索指示器小于输入串长度是,就循环执行如下操作: 得到当前char,如果是字母,判断下一个,如是数字或字母,继续直至不是字母或者是数字,将此时的单词与关键字比较,获得识别符,存入word数组中 如果是数字,循环看下一个是否为数字,继续直至不是数字为止,将单词存入数组中 如果是+、-、*、/、(、)、[、]、{、}、,、:、;与关键字比较,直接存入数组中 如果是>、<、=、!时,要判断下一个,是否构成了>=、<=、==、!=。然后在存入数组中 如果下一个字符是空,换行,则跳过去下一个字符。 在做词法分析的时候,注意每一次判断结束之后要将strToken清空,而且要注意回退,即当输入串下一个不满足要求的时候,要回退一格。 2、 语法分析函数 利用词法分析已经分析出来的单词数组,循环进行每一步的语法分析,每当归并一个单词之后,index指示器加一,直至index等于单词数组长度,循环结束。 在每一次循环中,根据当前指示器指示的单词及堆栈的栈顶判断: 若相同,则表示要归并,将index++;栈顶弹出 若不相同,在分析表中查找所需要的产生式,并将栈顶弹出,将产生式逆向堆栈。 在查询的过程中,如果不能够移进也不能够归并,表示输入串不符合文法,在提示栏中提示。如果循环结束,直至栈中是由#,输入串中只剩#,表示分析完毕,输入串是符合文法的句子。 iv. 结果分析(原始图示) 图形界面: 输入句子:main() {} //空的main函数,运行结果 1、 点击词法分析之后,在右侧的词法分析结果中显示分析后的单词: 2、 点击语法分析之后,在中间的表中显示堆栈过程: 3、 语法分析结束,该语句是符合文法的句子,因此在提示栏中显示“该句子是符合文法的语句! 输入复杂一点的句子: main(){ If(zhj= =zhj){ Zhj=good; }; } 则结果是: 则他输出的单词是:(1,main)( 14, ( ) (15 , ) ) ( 18 , { ) ( 4 , if ) ( 14 , ( ) ( 7 , zhj ) ( 27 , = = ) ( 7, zhj ) ( 15 , ) ) ( 18 , { ) ( 7 , zhj ) ( 9 , = ) ( 7 , good) ( 22 , ;) ( 19 , }) ( 22 , ;) ( 19 , }) 语法分析经过了从0到37 的38步,分析结束:(在下图中将语法分析的全过程拼合) 分析结束后的输出结果是: 下图为此次语法分析的堆栈全过程: 输出更加复杂的句子: Main() { While ( lsq <= zhj ){ If ( zhj = = zhj ){ Zhj = good; }; }; } 则结果是: 右侧的单词符号序列为: 语法分析过程为: 输入串是符合文法的句子,因此,正常结束 输入一个不符合文法的句子: Main(){ zhanghuijuan is a good student ; } // zhanghuijuan is a good student 语句即不是赋 值,条件,也不是循环,因此不符合文法 输出结果是: 词法分析仍然可以进行,但是语法分析中发现进行不下去了,因此输出错误提示: “此输入串不是一个语句,不符合文法!” iiv. 调试报告: 程序在编写的过程中有很多小的地方并没有注意,在不断的调试的过程当中逐渐发现: 1、在文法中有A-->空 的情况,在文法产生式的存储过程中就用空格代替了空,但是当需要用这样的产生式移进的时候,如果跟其他的产生式一样处理,则会在堆栈中将空格压栈,因此使语法分析不能继续进行下去。因此,我们在压栈之前要先进行判断,若是这种情况,则只是弹出栈顶,而不对其进行压栈。 2、由于在此程序中应用了多个数组,因此很容易出现数组越界的情况,所以这里就要多加注意才行。 3、在堆栈过程输出的时候,要输出当前栈中的元素,以及剩余的输入串,一定要注意要将输入串的输出放在index的增加之后,否则就是输出上一次的执行时的输入串了 附:程序原代码 ************************package word.wordList;********************************** //////////////////////////////////////file word.java///////////////////////////////////// public class word { String value; int ID; public int getID() { return ID; } public void setID(int id) { ID = id; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } } //////////////////////////////////////file word.java///////////////////////////////////// public class WordList { //此类定义了语言单词符号种别码 word[] w = new word[30]; public WordList(){ w[0] = new word();w[0].setID(1);w[0].setValue("main"); w[1] = new word();w[1].setID(2);w[1].setValue("int"); w[2] = new word();w[2].setID(3);w[2].setValue("char"); .........................................................................//省略 w[27] = new word();w[27].setID(28);w[27].setValue("!="); w[28] = new word();w[28].setID(29);w[28].setValue("ERROR"); } public int Reserve(String value){ for(int i = 0 ; i<28 ; i++){ if(value.equals(w[i].getValue())){ return w[i].getID(); } } return 0; //返回0表示不在保留字之中。 } } ************************package word;;********************************** //////////////////////////////////////file basicFunction .java///////////////////////////////////// import word.wordList.WordList; //在此类中定义了一组全局变量和过程,将它们作为实现转换图的基本成分 public class basicFunction { public String input=""; //输入的源程序 public char ch; //存放最新读进的源程序的字符 public String strToken=""; //存放构成单词符号的字符串 public int index=0; //存放此时搜索指示器指向的字符位置 public int index_buf; //buffer中搜索指示器指向的字符位置 basicFunction(String input){ this.input = input; } public char getCh() { return ch; } public void setCh(char ch) { this.ch = ch; } public String getInput() { return input; } public void setInput(String input) { this.input = input; } public String getStrToken() { return strToken; } public void setStrToken(String strToken) { this.strToken = strToken; } //将下一输入字符读到ch中,搜索知识器前移一个字符位置 public int GetChar(){ this.ch = this.input.charAt(index); index++; return 0; } //检查ch中的字符是否为空白。若是,则调用GetChar直至不是字符为止 public char GetBC(){ while(ch==' '||ch=='\n'||ch=='\r'){ GetChar(); } return ch; } //将ch中的字符连接到strToken之后 public String Concat(){ strToken=strToken.concat(String.valueOf(ch)); return strToken; } //判断ch中的字符是否为字母 public boolean IsLetter(){ boolean flag=false; if(ch>='a' && ch<='z' || ch>='A' && ch<='Z' ){ flag=true; } return flag; } //判断ch中的字符是否为数字 public boolean IsDigit(){ boolean flag=false; if(ch>='0' && ch<='9' ){ flag=true; } return flag; } //对strToken中的字符创查找保留字表,若是则返回它的编码,否则返回0 //注:在编写保留字表的时候要从1开始编号,不能从0开始编号! public int Reserve(){ WordList wl = new WordList(); int f = wl.Reserve(strToken); return f; //返回0表示不在保留字之中。 } //将搜索指示器回调一个字符位置 public void Retract(){ ch=' '; int l = strToken.length(); if(l>1){ strToken = strToken.substring(0,l-1); } index--; } //将strToken置空 public void RetractStr(){ strToken=""; } } //////////////////////////////////file: lexAnalysis .java; ////////////////////////////////// import word.wordList.word; public class lexAnalysis { String input; public word[] word = new word[1000]; public String getInput() { return input; } public void setInput(String input) { this.input = input; } public int wordAnalysis(){ int i = 0; basicFunction bf = new basicFunction(input); int lo = input.length(); while(bf.index'||bf.ch=='<'||bf.ch=='='||bf.ch=='!'){ int f = 0; if(bf.index=0&&pro<=26){ int l = gg.gram[pro].lo; ss.pop(); for(int j =l-1 ; j>=0 ; j--){ ss.push(gg.gram[pro].content[j]); } f=1; } return f; } } *********************************packet main********************************** 此图形界面代码不再黏贴了,只是将词法分析的函数及语法分析的函数黏贴 private JButton getJButton() { if (jButton == null) { jButton = new JButton(); jButton.setBounds(new java.awt.Rectangle(599,80,89,41)); jButton.setText("词法分析"); jButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { String input = getJTextArea().getText().toString().trim(); System.out.print(input); TableModel model = getJTable().getModel(); DefaultTableModel tablemodel = (DefaultTableModel)model; int counts = tablemodel.getRowCount(); for(int k = counts-1;k>=0;k--){ tablemodel.removeRow(k); } lexAnalysis lex = new lexAnalysis(); lex.setInput(input); int i = lex.wordAnalysis(); for(int j = 0 ; j=0;k--){ tablemodel.removeRow(k); } SentenceAnalysis sa = new SentenceAnalysis(); lexAnalysis lex = new lexAnalysis(); lex.setInput(input); int i = lex.wordAnalysis(); // System.out.println(i); int index = 0; int b = 0; //用来求输入串 String inp0 =""; for (int j = index ; j=0&&gra<=26){ gram = sa.gg.gram[gra].key; gram = gram+"-->"; int lll = sa.gg.gram[gra].lo; for(int m = 0 ; m
本文档为【编译原理-词法分析】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_577447
暂无简介~
格式:doc
大小:3MB
软件:Word
页数:27
分类:互联网
上传时间:2012-05-11
浏览量:54