logo资料库

编译原理PL0实验报告.docx

第1页 / 共62页
第2页 / 共62页
第3页 / 共62页
第4页 / 共62页
第5页 / 共62页
第6页 / 共62页
第7页 / 共62页
第8页 / 共62页
资料共62页,剩余部分请下载后查看
实验目标
实验概览
实验要求
PL0语言文法的BNF表示
词法分析
词法分析要完成的任务
词法分析实现分析
词法分析用到的存储结构和函数
Void Init()在类型表sym中填入类型
Void pretreatment(string line)去除掉当前行代码中多余的空格
int check(char x)检测字符类型并返回对应类型的整数
Void getSym()读取文件并提取词汇
void putIn(string) 对提取出的词汇进行分析的函数
Void output()输出词法分析的结果
词法分析结果样例
语法分析
语法分析要完成的任务
PL0语言文法的EBNF表示
语法分析实现分析
实现语法分析需要的存储结构
实现语法分析需要的函数
语义分析和目标代码生成
说明部分的处理
说明部分处理的分析
语句处理和目标代码生成
8条目标指令
目标指令生成分析
解释执行
解释执行部分用到的数据结构和函数
解释执行部分函数分析
Void getResult()
Void OPR()
Int getVar(int l,int a)
Void changeVar(int l,int a)
代码结构解释
问题和总结
附件
头文件pch.h
头文件实现文件pch.cpp
主程序Grammer.cpp
PL0 语言文法编译器 实验报告 课程名称:程序设计语言编译原理 实验名称: PL0 语言文法编译器 学生学院: 学生班级: 学生学号: 学生姓名: 提交日期: 2019.12.11
目录 实验目标.................................................................................................................................................................. 3 实验概览.................................................................................................................................................................. 3 实验要求.........................................................................................................................................................3 PL0 语言文法的 BNF 表示........................................................................................................................3 词法分析.................................................................................................................................................................. 4 词法分析要完成的任务.............................................................................................................................4 词法分析实现分析...................................................................................................................................... 4 词法分析用到的存储结构和函数.................................................................................................4 Void Init()在类型表 sym 中填入类型.......................................................................................... 5 Void pretreatment(string line)去除掉当前行代码中多余的空格......................................6 int check(char x)检测字符类型并返回对应类型的整数 ....................................................... 7 Void getSym()读取文件并提取词汇............................................................................................7 void putIn(string) 对提取出的词汇进行分析的函数............................................................ 8 Void output()输出词法分析的结果..............................................................................................9 词法分析结果样例....................................................................................................................................10 语法分析................................................................................................................................................................11 语法分析要完成的任务.......................................................................................................................... 11 PL0 语言文法的 EBNF 表示................................................................................................................... 11 语法分析实现分析....................................................................................................................................13 实现语法分析需要的存储结构................................................................................................... 13 实现语法分析需要的函数............................................................................................................ 14 语义分析和目标代码生成............................................................................................................................... 16 说明部分的处理........................................................................................................................................ 16 说明部分处理的分析......................................................................................................................17 语句处理和目标代码生成......................................................................................................................17 8 条目标指令.....................................................................................................................................17 目标指令生成分析.......................................................................................................................... 18 解释执行................................................................................................................................................................18 解释执行部分用到的数据结构和函数.............................................................................................. 18 解释执行部分函数分析.......................................................................................................................... 19 Void getResult()................................................................................................................................19 Void OPR()..........................................................................................................................................21 Int getVar(int l,int a)........................................................................................................................ 23 Void changeVar(int l,int a)............................................................................................................24 代码结构解释...................................................................................................................................................... 25 问题和总结........................................................................................................................................................... 25 附件......................................................................................................................................................................... 25 头文件 pch.h...............................................................................................................................................25 头文件实现文件 pch.cpp....................................................................................................................... 29 主程序 Grammer.cpp...............................................................................................................................62
实验目标 本实验作为程序设计语言编译原理的实验课,旨在提升同学们的动手编程能力,借助实 验巩固上课所学习的编译原理相关的知识。 本实验可大致分为四个阶段,分别为词法分析、语法分析、语义分析和目标代码生成、 解释执行。四个部分相对独立,对应《高级程序语言编译原理》课本讲解顺序。实验课时长 32 学时,截止提交时间为本学期第 15 周周三。 实验概览 实验要求 PL0 语言相对来说是一种比较简易的编程语言语言,下一小节我们会给出 PL0 语言文法 的 BNF 表示。本实验的结果要求得到一个能够对 PL0 语言代码执行并能输出正确结果的程序。 词法分析:对代码进行词法分析,提取出代码中的词(包含标识符,数字,符号等); 语法分析:对代码进行语法分析,推导语言文法,给出语法树,同时检测不符合语法规 范的代码并报错; 语义分析和目标代码生成:对语法分析的结果进行语义分析,给出对应等价的中间代码; 解释执行:对中间代码解释执行,给出代码执行的结果。 PL0 语言文法的 BNF 表示 1. 〈程序〉→〈分程序〉。 2. 〈分程序〉→ [<常量说明部分>][<变量说明部分>][<过程说明部分>]〈语句〉 3. 4. 5. 6. 7. 8. 9. 10. <语句> → <赋值语句>|<条件语句>|<当型循环语句>|<过程调用语句>|<读语句>|<写语句>|< <常量说明部分> → CONST<常量定义>{ ,<常量定义>}; <常量定义> → <标识符>=<无符号整数> <无符号整数> → <数字>{<数字>} <变量说明部分> → VAR<标识符>{ ,<标识符>}; <标识符> → <字母>{<字母>|<数字>} <过程说明部分> → <过程首部><分程度>;{<过程说明部分>} <过程首部> → procedure<标识符>; 复合语句>|<空> 11. <赋值语句> → <标识符>:=<表达式> 12. <复合语句> → begin<语句>{ ;<语句>} 13. <条件> → <表达式><关系运算符><表达式>|odd<表达式> 14. <表达式> → [+|-]<项>{<加减运算符><项>} 15. <项> → <因子>{<乘除运算符><因子>} 16. <因子> → <标识符>|<无符号整数>|(<表达式>)
17. <加减运符> → +|- 18. <乘除运算符> → *|/ 19. <关系运算符> → =|#|<|<=|>|>= 20. <条件语句> → if<条件>then<语句> 21. <过程调用语句> → call<标识符> 22. <当型循环语句> → while<条件>do<语句> 23. <读语句> → read(<标识符>{ ,<标识符>}) 24. <写语句> → write(<标识符>{,<标识符>}) 25. <字母> → a|b|c…x|y|z 26. <数字> → 0|1|2…7|8|9 词法分析 把关键字、算符、界符称为语言固有的单词,标识符、常量称为用户自定义的单词。 词法分析要完成的任务 1. 滤掉单词间多余的空格 2. 识别关键字,用查关键字表的方式识别。 3. 识别标识符,标识符的类型为 ID。 4. 拼数,将数的类别 NUMBER 放在 SYM 中 5. 拼由两个字符组成的运算符,如>=、<=d 等等,识别后将其放在 SYM 中 6. 打印程序,将识别出来的字符打印 词法分析实现分析 词法分析用到的存储结构和函数 首先给出储存每一个分析出来的词汇的基本储存结构, int ID; string name; int number; Ternary(int a, string b, int c) { //储存着词汇类型对应的 ID //存储着分析出来词汇 //存储着这个词汇是对应 ID 的第几个 //重构函数 1. class Ternary { 2. public: 3. 4. 5. 6. 7. 8. 9. ID = a; name = b; number = c;
} 10. 11. }; 接下来给出主要的存储结构 1. vector sym;//类型表 2. vector sym_num;//当前这种类型的数量 3. vector word;//从程序中读到的东西 以下是词法分析部分会用到的函数 1. void init();//预处理,建立保留字/其他表格 2. int check(char);//检查当前字符的类别 3. void getSym();//词法分析部分 4. int getID(string);//获得当前单词的类别的 ID 5. void putIn(string);//把得到的单词放进 word 里 6. void output();//输出词法分析的结果 接下来的小节中,我们会介绍各个函数的实现机制。 Void Init()在类型表 sym 中填入类型 //生成类表 sym.push_back("$ID"); sym.push_back("$NUMBER"); 1. void Grammer::init() { 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. sym.push_back("$+"); sym.push_back("$-"); sym.push_back("$*"); sym.push_back("$/"); sym.push_back("$="); sym.push_back("$>"); sym.push_back("$<"); sym.push_back("$>="); sym.push_back("$<="); sym.push_back("$#"); sym.push_back("$,"); sym.push_back("$:="); sym.push_back("$("); sym.push_back("$)"); sym.push_back("$;"); sym.push_back("$.");
sym.push_back("$const"); sym.push_back("$var"); sym.push_back("$procedure"); sym.push_back("$begin"); sym.push_back("$end"); sym.push_back("$odd"); sym.push_back("$if"); sym.push_back("$then"); sym.push_back("$else"); sym.push_back("$call"); sym.push_back("$while"); sym.push_back("$do"); sym.push_back("$read"); sym.push_back("$write"); for (int i = 0; i < sym.size(); i++) { sym_num.push_back(0); } tree->ID_Name = "PROGRAM"; 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. } Void pretreatment(string line)去除掉当前行代码中多余的 空格 if (line[i] != ' ') { if (b == true) if (s != "") { s += ' '; string s = ""; bool b = false; for (int i = 0; i < line.size(); i++) 1. string Pretreatment(string line) {//去除掉当前句子里多余的空格 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. } b = false; s += line[i]; } } else { b = true; } return s;
int check(char x)检测字符类型并返回对应类型的整数 1. int Grammer::check(char x) {//检查当前字符是不是分割单词的符号 2. 3. 4. 5. 6. 7. } if (x == ' ') return 0;//是空格就返回 0 if (isalpha(x)) return 1;//是字母就返回 1 if (isdigit(x)) return 2;//是数字就返回 2 if (x == '_') return 3;//是下划线就返回 3 return 4;//是其他符号就返回 4 Void getSym()读取文件并提取词汇 //读入文件地址并打开文件 fstream f; cout << "Please enter the file address:" << endl; //cin >> fileName; fileName = "./main.txt"; f.open(fileName, ios::in); if (!f.is_open()) { cout << "dont find the file" << endl; return; string line; 1. void Grammer::getSym() { 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. } int hhh = 0; while (!f.eof()) { hhh++; getline(f, line);//读取当前文件的一行 if (line.size() == 0) continue;//如果当前行为空则继续读下一行 string strtoken = "";//储存着当前读到的单词的部分 string oldStrtoken = "";//储存着上一个单词 int index = 0; string sentence=Pretreatment(line);//对句子进行预处理,去除掉当前句子里 多余的空格 24. 25. 26. 27. 28. 29. 30. cout << sentence << endl; while (index < sentence.size()) { int x = check(sentence[index]); if ( x != 0 && x != 4 ) { strtoken+=sentence[index]; } else {
if (strtoken != "") {//对当前读到的单词进行处理 putIn(strtoken); strtoken = ""; } if (x == 4) { 情况下 strtoken += sentence[index]; if (index < sentence.size() - 1) {//在当前这一行没有读完的 if (sentence[index + 1] == ';') {//下一个字符是;时 putIn(strtoken); strtoken = ";"; } else { if (check(sentence[index + 1]) == 4)//下一个字符 strtoken += sentence[++index]; 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. } 不是分号,但是符号 } } putIn(strtoken); strtoken = ""; } } index++; } if (strtoken != "") {//对当前读到的单词进行处理 putIn(strtoken); } } //cout << hhh << endl; f.close(); void putIn(string) 对提取出的词汇进行分析的函数 if (isalpha(s[0])) { 1. void Grammer::putIn(string s) { 2. 3. 4. 5. 6. 7. 8. 9. 10. } else {//是保留字 int id = 0; if ((id = getID(s)) == -1) {//是标识符 id = getID("ID"); Ternary t(id, s, ++sym_num[id]); word.push_back(t); word.push_back(Ternary(id,sym[id], ++sym_num[id]));
分享到:
收藏