《编译原理 实验三 实验报告.doc》由会员分享,可在线阅读,更多相关《编译原理 实验三 实验报告.doc(19页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、实 验 报 告 第 1 页专业_软件工程_ 班级_2_ 姓名_71李飞强77欧艺欣81吴文浩 89张泰鑫_ 组别:第四组实验日期:2014年 3 月 26 日 报告退发 (订正 、 重做) 课程 编译原理 实验名称 递归下降的预测分析 一、实验目的1. 学会用语法图来形式化地描述一门简单的语言;2. 掌握递归下降的预测分析;3. 掌握词法分析。二、实验环境Visual Studio 或 GCC 或Eclipse三、实验内容、步骤和结果分析实验内容:请基于递归下降的分析方法(教材P55页),编写一个“语法图.doc”所对应语言的语法分析器。该语法分析器能读入一个源代码文件(如“test.c”文件
2、所示),并判断其中的源代码是否符合“语法图.doc”的规定。如果符合,打印出Yes;如果不符合,打印出No。(所用编程语言不限)C语言版:#include#include#include#define MaxIdLen 20 /标志符的最大长度#define KeyWordsCount 5 /该语言拥有的关键字个数#define BoolValueCount 2/bool类型可能取值的个数#define SymTypeCount 17/symType个数 enum SymType/枚举OR ,/或AND,/与LP,/左括号RP,/右括号ID,/标志符ASSIGN,/赋值LB,/左大括号RB,/
3、右大括号COMMA,/逗号SEMICOLON,/分号UNDEFINED,/未定义BOOLVALUE,/bool类型的值IF,/ifELSE,/elseWHILE,/whilePRINTF,/printfBOOL,/bool;enum boolValueTRUE, FALSE,;/关键字static char * keywordsKeyWordsCount = if,else,while,printf,bool,;/关键字对应类别static int keyTypeKeyWordsCount = IF,ELSE,WHILE,PRINTF,BOOL,;/static char * boolvalu
4、eBoolValueCount=true,false,;static int boolValueTypeBoolValueCount=TRUE,FALSE,; char ch= ; /当前字符char idMaxIdLen+1;/当前符号串int token;/当前记号(的类型)int value;/当前记号的值FILE * fp;/用来打开要识别的源代码文件int lineNum=1;/要识别的代码行数bool isPass = false ;/判断识别的代码是否全部合法 void getToken();void program();void program();void statement
5、();void definition();void term();void factor();void expression();void match(int t); void main() fopen_s(&fp,D:test.c,r);getToken();program();if(isPass)printf(Yn);else printf(Nn);fclose(fp);/*lexical*/ int getKeyWord(char * str)for(int i=0;iKeyWordsCount;i+)if(strcmp(str,keywordsi)=0) return keyTypei
6、;return UNDEFINED;int getBoolValue(char* str) for(int i=0;i=A&ch=a&ch=0&ch=9;void nextChar() ch = fgetc(fp); void getToken() while(ch= |ch=t|ch=r|ch=n)if(ch = n)lineNum+; nextChar();if(isLetter(ch)int index=0;idindex+ = ch;nextChar();while(isLetter(ch) | isDigit(ch)if(indexMaxIdLen)idindex+ = ch;nex
7、tChar();else/coutidentifier is too long. + type);if (lookahead.tokenType.equals(type) lookahead = lexer.getToken(); else error(NO);/ 否则报错private void error(String str) / out.println(str);System.out.println(str);System.exit(-1);/* * program:程序 definition-statement- */public void program() definition(
8、);/定义statement();/ 声明/ definition:定义/* * bool-id-=-expression-; */public void definition() do match(TokenType.BOOLEAN);match(TokenType.ID);match(TokenType.EQUAL);expression();match(TokenType.SEMICOLON);/ 匹配分号 while (lookahead.isBoolean();/ statement:声明public void statement() if (lookahead.isIf() / -
9、if-(-expression-)-statement-match(TokenType.IF);match(TokenType.LeftP);expression();match(TokenType.RightP);statement();if (lookahead.isElse() /缺陷:如果用全部代码测试时,程序走到这里停止了,while循环后的语句将不能执行!match(TokenType.ELSE);statement(); else else if (lookahead.isWhile() match(TokenType.WHILE);match(TokenType.LeftP);
10、expression();match(TokenType.RightP);statement(); else if (lookahead.isPrint() match(TokenType.PRINT);match(TokenType.LeftP);expression();while (lookahead.isComma() match(TokenType.COMMA);expression();match(TokenType.RightP);match(TokenType.SEMICOLON); else if (lookahead.isSemicolon() / ;match(Token
11、Type.SEMICOLON); else if (lookahead.isLeftBrace() match(TokenType.LeftBrace);statement(); while (!lookahead.isRightBrace() | lookahead.isId() )/必须加入lookahead.isId()否则a = false;运行不出来(语法图缺陷吧!) statement(); match(TokenType.RightBrace); else if (lookahead.isId() / id = expression;/System.out.println(+);
12、match(TokenType.ID);match(TokenType.EQUAL);expression();match(TokenType.SEMICOLON); else /* * expression:式子 -term()-(-|-term()-); */private void expression() term();while (lookahead.isOr() / 如果是|就继续循环处理match(TokenType.OR);term();/* * term:项 Factor(); While(match(&) Factor(); */private void term() fa
13、ctor();while (lookahead.isAnd() / 判断是&就继续进行match(TokenType.AND);factor();/* * -(-expression-)- * -true- * -false- * -id- */private void factor() if (lookahead.isTrue() match(TokenType.TRUE); else if (lookahead.isLeftP() match(TokenType.LeftP);expression();match(TokenType.RightP); else if (lookahead.
14、isFalse() match(TokenType.FALSE); else if (lookahead.isId() match(TokenType.ID); else/* * 获取下一个Token */public Token getToken() int value = 0;char cur;while (true) if (index = src.length()return Token.EOF;else / 取下一字符cur = next();/ 如果下一个字符是空白,继续读取字符if (this.isBlank(cur)continue;else if (this.isAlpha(
15、cur) / 字符缓冲 区StringBuilder buffer = new StringBuilder();buffer.append(cur);while (isAlpha(char) peek() buffer.append(next();if (buffer.toString().equals(KeyWord.BOOLEAN) return new Token(TokenType.BOOLEAN, buffer.toString(); else if (buffer.toString().equals(KeyWord.FALSE) return new Token(TokenType
16、.FALSE, buffer.toString(); else if (buffer.toString().equals(KeyWord.TRUE) return new Token(TokenType.TRUE, buffer.toString(); else if (buffer.toString().equals(KeyWord.IF) return new Token(TokenType.IF, buffer.toString(); else if (buffer.toString().equals(KeyWord.WHILE) return new Token(TokenType.W
17、HILE, buffer.toString(); else if (buffer.toString().equals(KeyWord.PRINT) return new Token(TokenType.PRINT, buffer.toString(); else return new Token(TokenType.ID, buffer.toString(); else if (cur = ,) return Token.COMMA; else if (cur = () return Token.LeftP; else if (cur = ) return Token.RightP; else
18、 if (cur = | & next() = |) return Token.OR;/ 或者 else if (cur = & & next() = &) return Token.AND;/ 且 else if (cur = =) return Token.EQUAL; else if (cur = ;) return Token.SEMICOLON;/ 分号 else if (cur = ) / 左大括号return Token.LeftBrace; else if (cur = ) return Token.RightBrace; else if (cur = n) line+; el
19、se this.error();运行这个测试代码的截图:String src = boolean a = true;boolean b = false;boolean c = (a & b);if( a | b)print(a,b);elseprint(c);运行这个测试代码的截图:String src = boolean a = true; while(a & (b|c)print(a,b,c);a = false;四、讨论(说明实验过程中遇到的问题及解决办法;未解决/需进一步研讨的问题或建议新实验方法等)在text.c中先是声明bool类型,然后是if语句,最后是while语句。语法图中,
20、执行program之后,definition对bool声明进行判断,statement对if语句判断,然后program就算结束了,没有对while判断;如果执行2次program,因为while之前没有bool的声明,所以在第二次执行program时,它里面的definition会提示错误。Java版总结: 代码框架是参考实验一的老师给的样式。经过自己的理解,添加了一个关键字类,这个类主要存储关键字。按照语法图,一点点的翻译成代码,最初在语法图中的分支结构上,都是用if做为判断,并没有match(),在这个方面调试花了最多的时间。逐个针对老师给的语法图进行代码测试,除了while循环中的a = false;这句不能测试成功外其他基本都测试成功了(程序中必须现有定义部分,否则这个声明部分不能执行(语法图的缺陷)。当测试全部代码时,while后语句不能执行,这个应该是语法的图的缺陷吧!