编译原理语法分析器实验报告
编号:
实习 | 一 | 二 | 三 | 四 | 五 | 六 | 七 | 八 | 九 | 十 | 总评 | 教师签名 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
成绩 |
第一部分 语言语法规则
Mini语言包含程序设计所需要的最基本语言成分,包括
程序定义语句 :以 program 开头 end 结尾,中间需要有 main()函数
赋值语句 :var 标识符 = 表达式;
算数表达式:包含 + - * / ()运算
逻辑表达式:包含 II && ! ()运算
if-else 语句:if (逻辑表达式或变量)begin 程序体 end else begin 程序体 end
while 循环语句:while(逻辑表达式或变量)begin 循环体 end
break 语句:break;
第二部分 文法定义
简化后的单词编码表为
单词符号 | 编码 | 单词符号 | 编码 |
---|---|---|---|
main | 1 | + | 15 |
if | 2 | - | 16 |
else | 3 | * | 17 |
while | 4 | / | 18 |
program | 5 | = | 19 |
begin | 6 | && | 20 |
end | 7 | || | 21 |
var | 8 | ! | 22 |
break | 9 | == | 23 |
true | 10 | 整数常量表 | 24 |
false | 11 | 浮点数常量表 | 25 |
( | 12 | 标识符表 | 26 |
) | 13 | ||
; | 14 |
先有词法分析器将程序扫描一遍,得到Token串,例如main转为<1,->,if转为<2,->...!转为<22,->,特别的标识符,整数常量,浮点数常量有两个表分别转换为<23,i>.<24,i>,<25,i>.
但是在语法分析的文法中,为了方便理解,这里依然用main等字符串,而不是使用<1,->进行分析,其中标识符用id表示,整数常量用wholenum表示,浮点数用floatnum表示。
得到如下的上下文无关文法G(S),(小写表示终结符号,大写表示非终结符号)
S ->PROGRAM //PROGRAM为整个语法程序
PROGRAM -> program PROBODY end
//PROBODY为程序体
PROBODY -> main begin PROSTATEMENT end
//PROSTATEMENT为程序语句
PROSTATEMENT -> ASSIGNMENT PROSTATEMENT | CONDITION PROSTATEMENT | LOOP PROSTATEMENT | BREAK PROSTATEMENT | ε //ASSIGNMENT为赋值语句 COUNT 为算数表达式 LOGIC 为逻辑表达式 CONDITION 为if else 分支语句 LOOP 为while循环语句 BREAK 为break语句,用于跳出循环//
ASSIGNMENT -> var id = VALUE ;
//VAlUE 为赋值语句可以赋的值,id为变量,属于词法分析器中单词编码表中的标识符
VALUE -> id | COUNT | LOGIC
COUNT -> TF F -> +T | -T | ε T -> GH H -> *G | /G | ε G -> (COUNT) | wholenum | floatunm | id
//wholenum 为词法分析器中单词编码表中的整数,floatnum为词法分析器中词法编码表中的浮点数,整个算术运算符表达,每个算数单元可以是数字也可以是变量
LOGIC -> IJ J -> ||I | ==I | ε I -> KL L -> &&K |ε K -> !M | M M -> (LOGIC) | true | false | id
//这里是逻辑表达式,每个逻辑单元可以是true false 也可以是变量
CONDITION -> if (LOGIC) begin PROSTATEMENT end ELSE
//ELSE是else语句
ELSE -> begin PROSTATEMENT end | ε
//if else语句中,先进行逻辑语句的判读,然后进入程序语句,else是可空的
LOOP -> while (LOGIC) begin PROSTATEMENT end
//循环语句
BREAK -> break ;
//break跳出语句
第三部分 语法分析算法
使用递归下降算法,结合词法分析器,用get_nexttoken();
函数表示取到下一个token串,用w.nexttoken();表示w后面的token串,用Token数据结构表示token串,所有的终结符号都使用Token进行定义,由于这些字符原本就是c语言的关键字,所以为了区分,将所有Mini文法中的关键字在程序表达中都加上s,边界符使用S+所对应的数字表示,如‘(’用S12表示。
Token mains = new Token(1);
Token ifs = new Token(1);
Token elses = new Token(1);
Token whiles = new Token(1);
.
.
.
Token S12 = new Token(12);
Token S13 = new Token(13);
Token S14 = new Token(14);
Token S15 = new Token(15);
.
.
.
Token id = new Token(26);
Token wholenum = new Token(24);
Token floatnum = new Token(25);
get_nexttoken(w);从词法分析器中取下一个token串,存放在全局变量w中
每个非终结符号都是一个函数,如下所示
void PROGRAM (){if(w==programs) {get_nexttoken(w);PROBODY();if(w==end){print("程序正确!");}else{error(0);}}else error(0);
}
void PROBODY (){if(w==mains){get_nexttoken(w);if(w==begins){get_nexttoken(w);PROSTATEMENT();if(w==ends){get_nexttoken(w);}else error(1);}else error(1);}else error(1);
}
void PROSTATEMENT (){if(w==vars) { ASSIGNMEN();PROSTATEMENT ();}else if(w==ifs) {CONDITION();PROSTATEMENT ();}else if(w==whiles) {LOOP();PROSTATEMENT ();}else if(w==breaks) {BREAK();PROSTATEMENT ();}else if(w==ends);else error(2);
}
void ASSIGNMENT (){if(w==var){get_nexttoken(w);if(w==id){get_nexttoken(w);if(w==S19){get_nexttoken(w);VALUE();if(w==S14)get_nexttoken(w);else error(3);}else error(3);}else error(3);}else error(3);
}
void VALUE (){if(w==wholenum) COUNT();else if(w==floatnum) COUNT();else if(w==trues) LOGIC();else if(w==falses) gLOGIC();else if(w==id&&w.nexttoken==S14) get_nexttoken(w);else if (!(w==id&&w.nexttoken==S14)||w==S12||w==id){if(w==S12&&w.nexttoken==id){if(w.nexttoken.nexttoken==(S15||S16||S17||S18){COUNT();}else if(w.nexttoken.nexttoken==(S20||S21||S23){LOGIC();}else error(4);}else if(w==S12&&(w.nexttoken==(wholenum||floatnum))){COUNT();}else if (w==S12&&(w.nexttoken==(true||false))){LOGIC();}else if(w==id&&(w.nexttoken==(S15||S16||S17||S18)){COUNT();}else if(w==id&&(w.nexttoken==S20||S21||S23)){LOGIC();}else error(4);}else error(4);
}
void COUNT(){T();F();
}
void F(){if(w==S15||w==S16){get_nexttoken(w);T();}}
void T(){G();H();
}
void H(){if(w==S17||w==S18){get_nettoken(w);G();}
}
void G(){if(w==S12){get_nexttoken(w);COUNT();if(w==S13){get_nexttoken(w);}else error(5);}else if(w==(wholenum||floatnum||id)){get_nexttoken(w);}else error(5);
}
void LOGIC(){I();J();
}
void J(){if(w==(S21||23)){get_nexttoken(w);I();}
}
void I(){K();L();
}
void L(){if(w==S20){get_nexttoken(w);K();}
}
void K(){if(w==!){get_nexttoken(w);M();}else{M();}
}
void M(){if(w==S11){get_nexttoken(w);LOGIC();if(w==S12){get_nexttoken(w);}else error(6);}else if(w==(trues||falses||id)){get_nexttoken(w);}else error(6);
}
void CONDITION(){if(w==ifs){get_nexttoken(w);if(w==S12){get_nexttoken(w);LOGIC();if(w==S13){get_nexttoken(w);if(w==begins){get_nexttoken(w);PROSTATEMNT();if(w==ends){get_nexttoken(w);ELSE();}else error(7);}else error(7);}else error(7);}else error(7);}else error(7);
}
void ELSE(){if(w==begins){get_nexttoken(w);PROSTATEMENT();if(w==ends){get_nexttoken(w);}else{error(7);}}
}
void LOOP(){if(w==whiles&&(w.nexttoken==S12)){get_nexttoken(w);get_nexttoken(w);LOGIC();if(w==begins){get_nexttoken(w);PROSTATEMENT();if(w==ends){get_nexttoken(w);}else error(8);}else error(8);}else error(8);
}
void BREAK(){if(w==breaks&&(w.nexttoken==S14)){get_nexttoken(w);get_nexttoken(w);}else{error(9);}
}
第四部分 出错处理出口
程序出错时,其实w记录了出错所在的token串,只需用另一个变量记录token串所在整个程序的位置,在使用get_nettoken()
取到下一个token串时,变量加一,就可以判断程序出错的位置。
错误函数 | 错误产生式 | 错误类型 |
---|---|---|
error(0) | PROGRAM -> program PROBODY end | 程序定义错误 |
error(1) | PROBODY -> main begin PROSTATEMENT end | 程序体定义错误 |
error(2) | PROSTATEMENT -> ASSIGNMENT | CONDITION | LOOP | BREAK | ε | 语句定义不合法 |
error(3) | ASSIGNMENT -> var id = VALUE ; | 赋值语句格式错误 |
error(4) | VALUE -> id | COUNT | LOGIC | 赋值语句右值不正确 |
error(5) | G -> (COUNT) | wholenum | floatunm | id | 算数表达式格式错误 |
error(6) | M -> (LOGIC) | true | false | id | 逻辑表达式格式错误 |
error(7) | CONDITION -> if (LOGIC) begin PROSTATEMENT end ELSE | 条件语句错误 |
error(8) | LOOP -> while (LOGIC) begin PROSTATEMENT end | 循环语句错误 |
error(9) | BREAK -> break ; | 跳出语句错误 |
第五部分 测试计划
测试用例中所包括的语法单位应该尽可能覆盖Mini语言的文法中的所有非终结符,包括程序定义、变量声明、if-else语句、赋值语句、条件语句、循环语句、跳出语句、算数表达式和逻辑表达式。
测试用例如下
program main begin var logic=true;var i=0;while(i<10)beginif(logic&&(!(!true)))begini=i+1;logic=!logic;endelsebeginlogic=!logic;endendend
end
测试结果,无错误!
编译原理语法分析器实验报告相关推荐
- 计算机原理林美华实验,ll1语法分析器实验报告.doc
ll1语法分析器实验报告.doc 南京信息工程大学实验(实习)报告实验(实习)名称LL(1)文法语法分析设计实验(实习)日期11月28日得分指导教师林美华系计算机专业计算机科学与技术年级2011班次计 ...
- 递归下降文法C语言实验报告,递归下降语法分析器实验报告.doc
递归下降语法分析器实验报告 编译原理实验报告 题目: 递归下降语法分析器 学 院 计算机科学与技术 专 业 xxxxxxxxxxxxxxxx 学 号 xxxxxxxxxxxx 姓 名 宁剑 指导教师 ...
- 编译原理——语法分析器(SLR)
编译原理--语法分析器(SLR) 识别语法结构: 变量声明(不含变量初始化) if单条件分支语句以及if else 双条件分支语句 for循环和while循环语句 赋值语句 ,四则运算,逻辑判断复合语 ...
- 算符优先文法编写java语法分析器,编译原理课程设计实验报告——基于算符优先分析方法的表达式语法分析器...
内容简介: 一.设计目的 了解用算符优先法对表达进行语法分析的方法,掌握自顶向下的预测语法分析程序的手工构造方法. 二.设计内容 对简单表达式文法构造算符优先分析器. 三.设计要求 1.对下列简单表达 ...
- 编译原理-语法分析器设计
文章目录 语法分析器设计 实验环境 实验目的 实验内容及要求 实验步骤 用上下文无关文法表达 改写为LL(1)文法 First集与Follow集 预测分析表 结果分析 源代码 语法分析器设计 实验环境 ...
- 编译原理:词法分析实验报告
词法分析实验报告 文章目录 词法分析实验报告 一.实验目的 二.实验原理 三.实验要求 四.实验步骤(利用Java语言来进行词法分析) ① 待分析的语言词法 ② 单词符号对应的种别码 ③ 词法分析程序 ...
- 编译原理—语法分析器(Java)
递归下降语法分析 1. 语法成分说明 <语句块> ::= begin<语句串> end <语句串> ::= <语句>{:<语句>} < ...
- 编译原理------语法分析器C/C++代码实现
一.实验目的 编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析. 二.实验内容 利用C语言编制递归下降分析程序,并对简单语言进行语法分析. 2.1 待分析的简单语言的语 ...
- 编译原理——语法分析器(C/C++代码实现)
0
最新文章
- IDEA 2022.2.1 Beta 2发布:新增支持Java 18、增强JUnit 5的支持
- python 从尾到头打印链表
- iframe 的一点经历
- 计算机电路基础张志良,计算机电路基础
- python自动接收邮件_Python自动发送和收取邮件的方法
- Ambari--告警管理
- 同一个项目的不同的项目工作经验总结--程序员丁
- FMEA软件功能失效矩阵-交叉表 vs 树形矩阵
- png在线转换icns
- Office | Word中插入参考文献
- C语言程序确定闰月,怎样计算闰月
- 拯救win10系统,如何开机进入DOS等删除恶意软件
- 计算机网络中速率和带宽的区别
- 情侣积分微信小程序零基础开发教程(附代码及开发指南)
- matlab 判定空值NaN
- matplotlib 绘制折现图
- 【CSS】如何实现价格文字中间划一条线
- 开票软件3.0模拟练习
- php百度网盘解析源码,【教程】php实现百度网盘视频解析
- 金蝶ERP二次开发笔记(二)----ID相关处理
热门文章
- 华科计算机杰出青年科学基金,喜报!曾小勤教授获得2018年度国家杰出青年科学基金资助...
- 手机打开网页显示500服务器错误,win10打开网页提示http 500 内部服务器错误怎么办...
- 听听周报-全球Q2耳戴式设备出货量增250%|物联网蓝牙设备的下一代可能没有电池
- 下载国家自然科学基金结题报告的免费工具
- 张老师的生日究竟是哪天(经典推理题[转载])
- vscode remote permission denied
- hog+svm图像检测流程 --python
- 因式分解法解一元二次方程
- 如何明晰定位与责任_找准定位 明晰责任 激发活力 发挥作用
- Billu_b0x 靶机