2024年3月7日发(作者:秦正平)
《编译原理课程设计》报告
MiniC编译器设计与实现
分组序号:13
设计地点:微301、文理楼110
电子邮件:
分组成绩:
任课教师:***
专业班级
姓名
学号
成绩比例(%)
成绩
16
20
计算机 12- 班
17
17
15
15
2014 年 12 月19 日word文档 可自由复制编辑
目录
1
2
3
4
4.1
4.2
4.3
4.4
4.5
课程设计目的 ........................................................................................... 1
课程设计内容 ........................................................................................... 1
课程设计原理 ........................................................................................... 1
系统需求分析 ........................................................................................... 4
MiniC编译器总体流程图 .......................................................................................................... 4
功能需求 ..................................................................................................................................... 4
用到的主要关键词: .................................................................................................................... 5
汇编成可执行文件 ..................................................................................................................... 5
MiniC语言的文法 ..................................................................................................................... 5
5
5.1
5.2
5.3
系统设计与实现 ....................................................................................... 8
BY13编译器的主要功能模块 .................................................................................................. 8
词法分析子程序 ......................................................................................................................... 8
语法语义分析子程序 ................................................................................................................. 8
6
6.1
6. 2
6. 3
6.4
6. 5
6. 6
系统测试与运行结果分析 ....................................................................... 9
测试程序1 .................................................................................................................................. 9
测试程序2 .................................................................................................................................. 9
测试程序3 .................................................................................................................................. 9
测试结果1 ................................................................................................................................ 10
测试结果2 ................................................................................................................................ 13
测试结果3 ................................................................................................................................ 16
7
心得体会 ................................................................................................. 19
word文档 可自由复制编辑
1 课程设计目的
(1)根据所掌握的编译原理课程的基本知识,编写出一个 MiniC 编译器;
(2)增强阅读和编写程序的能力;
(3)理解词法分析、语法分析和语义分析在编译程序中的作用;
(4)掌握词法分析、语法分析和语义分析程序的实现方法;
(5)实现 MiniC 编译器的编辑、编译、连接和运行。
2 课程设计内容
用 MFC 编写一个可视化的 MiniC 编译器,要求界面美观,使用方便,能够实现自定义 MiniC语言的编译。
支持的语句和运算:
(1)数据类型:int,char,void,float
(2)语句:赋值(=),if, while,for
(3)数学运算:+,-,*,/
(4)关系运算:==,>,<,>=,<=,!=
(5)逻辑运算:&&,||,!
(6)支持函数的定义、调用
(7)支持复合语句,即 {} 包含的语句
(8)注释: C 类型的多行注释 /* */ 和 C++ 类型的单行注释 //
3 课程设计原理
MiniC 语言可以看成 C 语言的子集,它的编译程序是一个编译执行环境。
MiniC 的编译程序和目标程序的执行程序都是用 C++ 语言编写的,因此 MiniC 语言可在配备C 语言的任何机器上实现。它的编译过程采用从左到右扫描输入符号串,进行最左推导,再向右看一个符号的方式,以语法分析程序为核心,词法分析和汇编代码生成程序都是独立的过程。当语法分析需要读取输入符号串时就调用词法分析程序;而当语法分析正确后,需要生成相应的目标代码(老师只要求到汇编代码,在本程序中则更进一步,是目标文件 .obj 文件和可执行的目标文件 .exe
文件)时,则调用汇编代码生成程序和创建EXE文件程序。
用表格管理程序建立变量、常量和过程标识符的说明与引用之间的信息联系。当源程序编译正确时,编译程序自动调用执行程序,对目标代码进行执行,并按用户程序的要求输入数据和输出运行结果。
(1)运行BY13程序,打开文件。
word文档 可自由复制编辑
(2)选择菜单 编译(C) -> 生成汇编代码(G)。
word文档 可自由复制编辑
(3)选择菜单 编译(C) -> 创建EXE文件(B),生成可执行的目标文件。
(4)选择菜单 编译(C) -> 运行(R),出现如下图所示的结果。
word文档 可自由复制编辑
4 系统需求分析
MiniC 语言编译过程采用从左到右扫描输入符号串,进行最左推导,再向右看一个符号的方式,对源程序分别进行 词法分析、语法分析、语义分析、中间代码生成、目标代码生成和可执行程序生成,此外,用表格管理程序建立变量、常量和过程标识符的说明与引用之间的信息联系.用出错处理程序对词法和语法分析研究遇到的错误给出在源程序中出错的位置和错误性质,它的工作过程如下所示:
输入源代码 ->
词法分析 ->
语法分析 ->
汇编代码生成 -> exe文件生成 ->
运行
4.1 MiniC 编译程序总体介绍
该编译器的运行过程是编辑源文件保存后,生成汇编代码时使用汇编代码生成程序
CAsmCodeGenerator 类,调用该类的成员函数genCodeSeg() 来生成代码段和genPreSeg() 来生成数据段,最后调用emitCode();当然我们在汇编代码生成时应该使用语义分析子程序 CAnalyzer
类对词法和文法出现的各种情况进行展开分析。
4.2 功能需求
(1)用 C++ 语言实现了类C语言,叫做 MiniC 语言;
(2)使用 LL(1) 文法,从左到右扫描输入符号串,进行最左推导,再向右看一个符号;采用递归子程序法实现语法分析,并用 C++ 语言实现了词法分析器、语法分析器、汇编代码生成器,能直接生成 intel 80x86汇编代码。
(3)在声明中实现了对静态常量、变量和函数声明的支持;赋值语句的 = ,基本的数学运算 +、-、*、/ ;
(4)使用函数实现了对过程的调用;
(5)使用 { } 实现复合语句;
word文档 可自由复制编辑
(6)使用函数 read() 来同时读入一个或多个数据,使用函数 write() 来同时输出一个或多个数据,而函数 printf() 只能用来输出字符串;
(7)在循环分支语句中实现了if语句, if……else……语句, for(…,……,……)…语句,while……语句;
(8)关系表达式包括 ==(等于)、!=(不等于)、<、<=、>、>=。
4.3 用到的主要关键词:
关键字等用枚举类型囊括:
enum TokenType
{
// 关键字
_DOUBLE, _INT, _ELSE, _CASE, _ENUM, _REGISTER, _TYPEDEF, _CHAR, _CONST, _FLOAT,
_FOR, _SIGNED, _VOID, _SIZEOF, _VOLATILE, _IF, _WHILE, _READ, _WRITE, _PRINTF,
// 操作符
ASSIGN, PLUS, MINUS, TIMES, DIV, MOD,
BITWISE_AND, BITWISE_OR, BITWISE_NOT, LOGICAL_NOT, LT, GT,
// 界符
LPARAN, RPARAN, LBRACE, RBRACE, LSQUARE, RSQUARE, COMMA, DOT, SEMI, COLON,
//( ) { } [ ] , . ; :
// 复杂操作符
EQ/* == */, NEQ/* != */, PLUS_PLUS/* ++ */, MINUS_MINUS/* -- */,
PLUS_ASSIGN/* += */, MINUS_ASSIGN/* -= */, TIMES_ASSIGN/* *= */, DIV_ASSIGN/* /=
*/,
NGT/* <= */, NLT/* >= */, LOGICAL_AND/* && */, LOGICAL_OR/* || */,
// 其他
_EOF, _ID, _NUM, _STRING, _CHARACTER, _LABEL, _ERROR, _NONE
};
4.4 汇编成可运行文件
采用 intel 80x86 汇编语言,然后调用 MASM 汇编成可执行文件(.exe),可在相应机型的机器上运行。
4.5 MiniC语言的文法
1. <程序> → <声明列表>
2. <声明列表> → <声明列表> <声明> | <声明>
3. <声明> → <变量声明> | <函数声明>
word文档 可自由复制编辑
4. <变量声明> → <类型分类符> ID(, ...)';' | <类型分类符> ID '[' <数字> ']' (, ...)';'
5. <数字> → 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ...
6. <类型分类符> → "int" | "void" | "char" | "float"
7. <函数声明> → <类型分类符> ID '(' <参数> ')' <复合声明>
8. <参数> → <参数列表> | "void"
9. <参数列表> → <参数列表> ',' <参数> | <参数>
10. <参数> → <类型分类符> ID | <类型分类符> ID '[' ']'
11. <复合声明> → '{' <局部声明> <声明列表> '}' | <表达式声明>
12. <局部声明> → <局部声明> <变量声明> | <变量声明>
13. <输入函数> → "read" '(' <变量> ')' ';'
14. <输出函数> → "write" '(' <表达式> ')' ';'
15. <显示函数> → "printf" '(' `"` <字符串> `"` ')' ';'
16. <表达式声明> → <表达式> ';' | ';'
17. <表达式> → <变量> `=` <表达式> | <逻辑表达式1>
18. <变量> → a | b | c | ... | z | A | B | C | ... | Z ...
19. <逻辑表达式1> → <逻辑表达式1> "||" <逻辑表达式2> | <逻辑表达式2>
20. <逻辑表达式2> → <逻辑表达式2> "&&" <简单表达式> | <简单表达式>
21. <简单表达式> → <添加的表达式> <关系操作> <添加的表达式> | <添加的表达式>
22. <关系操作> → "<=" | '<' | '>' | ">=" | "==" | "!="
23. <添加的表达式> → <添加的表达式> <加法操作>
24. <加法操作> → '+' | '-'
word文档 可自由复制编辑
25.
26. <乘法操作> → '*' | '/' | '%'
27. <逻辑表达式3> → '!' <逻辑表达式3> | <因子>
28. <因子> → '(' <表达式> ')' | <变量> | <调用> | <数字>
29. <变量> → ID | ID '[' <表达式> ']'
30. <调用> → ID '(' <形式参数> ')' ';'
31. <形式参数> → <形式参数表列> | ε
32. <形式参数表列> → <形式参数表列> ',' <表达式> | <表达式>
33: <子复合声明> → ID ':' | <调用> | <表达式声明>
34:
35.
36.
37.
38.
39.
40.
word文档 可自由复制编辑
5 系统设计与实现
5.1 BY13编译程序主要功能模块
(1)功能一:取得输入符号串的下一个有效字符,函数为 CTokenizer::NextToken()
(2)功能二:取得下一个有效字符的相关属性,函数为 CScaner::NextToken()
(3)功能三:构造输入串的语法树,函数为 CParser::BuildSyntaxTree()
(4)功能四:遍历语法树,并设置相应的属性,函数为 CAnalyzer::traverse
(5)功能五:语义分析处理,函数为 CAnalyzer::TraceTypeCheck()
(6)功能六:生成汇编语言代码,函数为 CAsmCodeGenerator::GenerateAsmCode
(7)功能七:调用语义类,生成汇编代码,函数为 CBY13Doc::OnCompileBuildAsm()
(8)功能八:调用汇编程序,生成可执行文件,函数为 CBY13Doc::OnCompileBuildExe()
5.2 词法分析子程序
词法分析类为 CScanner 和 CTokenizer,功能是从源程序中读出一个单词符号,把它的信息放入类中,语法分析器需要单词时,可以直接从这个类中获得。
词法分析器的分析过程:构造CTokenizer时,它通过构造函数从源程序中获得一个字符串。如果这个字符是字母,则继续获取字符或数字,最终可以拼成一个单词,查类CScanner 中的关键字表,如果查到为关键字,则把m_tType变量赋成相应的保留字类型值;如果没有查到,则这个单词应是一个用户自定义的标识符(可能是变量名、常量名或是过程的名字),把m_tType置为相应的关键值,把这个单词存入m_tType变量。查关键字表时使用了二分法查找以提高效率。如果m_tType获得的字符是数字,则继续用NextToken()获取数字,并把它们拼成一个整数,然后把m_tType置为number,并把拼成的数值放入m_dVal变量。如果识别出其它合法的符号(比如:赋值号、大于号、小于等于号等),则把m_tType则成相应的类型。
5.3 语法语义分析子程序
语法分析子程序采用了自顶向下的递归子程序法,语法分析同时也根据程序的语义生成相应的代码,并提供了出错处理的机制。语法及语义分析主要涉及到的函数:
(1)函数声明的分析函数 CParser::fun_declaration()
(2)变量定义的分析函数 CParser::var()
(3)复合语句的分析函数 CParser::compound_stmt()
(4)表达式、项、因子的处理函数 CParser::factor()
(5)if 语句的处理函数 CParser::if_stmt()
(6)for 循环的处理函数 CParser::for_stmt()
(7)while 语句的处理函数 CParser::while_stmt()
(8)函数调用的处理函数 CParser::call()
(9)read 语句的处理函数 CParser::read_stmt()
(10)write 语句的处理函数 CParser::write_stmt()
(11)单词合法性与出错恢复过程的分析函数 CParser::ConsumeUntil( enum TokenType type )
word文档 可自由复制编辑
6 系统测试与运行结果分析
6.1 测试程序1
// 求表达式的值
void main()
{
int x, y;
int z;
printf("Please input x and y :n");
read(x); //相当于scanf(&n)
read(y);
z = ( x + y * 5 ) * 4 / 3;
printf("z = ( x + y * 5 ) * 4 / 3 = ");
write(z);
printf("n"); //相当于printf("%d", sum)
}
6.2 测试程序2
// 用 for 循环求 1+2+3+...+n 的值
void main()
{
int n, i, sum;
sum = 0;
printf("Please input n: ");
read(n); //相当于scanf(&n)
for(i=1; i<=n; i=i+1)
{
sum = sum + i;
}
printf("sum = ");
write(sum); //相当于printf("%d", sum)
printf("n");
}
6.3 测试程序3
// 用 while 循环求 1+2+3+...+n 的值
void main()
{
int n, i, sum;
i = 1;
sum = 0;
printf("Please input n: ");
word文档 可自由复制编辑
read(n); //相当于scanf(&n)
while(i <= n)
{
sum = sum + i;
i = i + 1;
}
printf("sum = ");
write(sum); //相当于printf("%d", sum)
printf("n");
}
6.4 测试结果1
(1)运行BY13程序,打开文件。
(2)选择菜单 编译(C) -> 编译过程(T) -> 扫描单词(S)。
word文档 可自由复制编辑
(3)选择菜单 编译(C) -> 生成汇编代码(G)。
word文档 可自由复制编辑
(4)选择菜单 编译(C) -> 创建EXE文件(B),生成可执行的目标文件。
(5)选择菜单 编译(C) -> 运行(R),出现如下图所示的结果。
word文档 可自由复制编辑
6.5 测试结果2
(1)运行BY13程序,打开文件。
(2)选择菜单 编译(C) -> 编译过程(T) -> 扫描单词(S)。
word文档 可自由复制编辑
(3)选择菜单 编译(C) -> 生成汇编代码(G)。
word文档 可自由复制编辑
(4)选择菜单 编译(C) -> 创建EXE文件(B),生成可执行的目标文件。
(5)选择菜单 编译(C) -> 运行(R),出现如下图所示的结果。
word文档 可自由复制编辑
6.6 测试结果3
(1)运行BY13程序,打开文件。
(2)选择菜单 编译(C) -> 编译过程(T) -> 扫描单词(S)。
word文档 可自由复制编辑
(3)选择菜单 编译(C) -> 生成汇编代码(G)。
word文档 可自由复制编辑
(4)选择菜单 编译(C) -> 创建EXE文件(B),生成可执行的目标文件。
(5)选择菜单 编译(C) -> 运行(R),出现如下图所示的结果。
word文档 可自由复制编辑
7 心得体会
转眼间,这个学期的编译原理课程设计已经接近尾声,虽然时间不是很多,仅仅一周两节课,但是回顾这段时间,我们也可以说是受益匪浅。
这个学期的课程设计是跟编译原理课一起开的,这样的话对于我们而言是一个挑战,因为虽然我们也是按照老师的要求,在我们学习了文法之后就写出所有的文法,学了语句分析,就完成相应的语句分析的部分,但是与此同时,我们面临的一个问题就是不明白做这个编译器的原理步骤,后来经过查找资料,还有我们全组的讨论,最终明白了大致的原理,进而确定了我们要实现的功能,做好了前期的规划。
在我们以前用Visual C++ 的时候,只是感觉它的功能很强大,当然这是我们很羡慕的一个地方,我们虽然不能做的像它那么强大,那么完美,但是我们也是尽量地实现更多的功能。最后是暂定的几个常用的,然后根据时间做了相应的调整。
起步的时候是最难的,起步之后似乎就顺手了很多,当然也不排除在某些地方遇到卡壳,然后花费了很多时间去想解决方案,进而实现。
总结这个学期以来的课程设计,我学到了很多。首先是一个知识面的问题,开始的时候会有很多的问题,但是借助现在发达的网络,还有图书馆的书籍,我们最终解决了问题。而且不仅仅是解决一个问题的事情,在解决问题的过程中,也从各个方面充实了自己,提升了自己。
通过这次课程设计,我们可以将课上学习到的相关的知识应用到这个设计的过程中。以前的学习都是只是一个字面上的理解,尤其是那些抽象的东西,根本就应用不到实践中,然而这次课程设计正好解决了此弊端。虽然一边学习一边应用有一定的难度,但是只要克服了,还是好处多多的。首先,遇到难解的问题,我们会查找相关的资料,或者自学后面的内容,因为这些组合在一起之后,再运用一定的原理方法,就可以实现最终的结果,所以在课程设计提高自己动手实践能力的同时,还巩固提高了我们之前学的理论知识。
我认为学习的一个境界就是学以致用,学会了会用才是关键,我们学习这些知识就是为了运用的,将科学转化为技术。编译原理课程设计正好是一个很好的过渡。比如,我们在学习了文法,语句分析之后,还是不知道怎样用程序来实现语句的分析,我们用得比较少,所以不是用的自动机实现的,所以实现起来比较麻烦,但是这样正好是将我们原来学习的知识用之于实践。
过程中遇到问题是正常的,但是我们相信只要努力,一定会迎刃而解。Any thing is possible!
总之,通过这次编译原理课程设计,我学到了很多,也收获了很多。
word文档 可自由复制编辑
教 师 评 语 专 栏
任
课
教
师
评
语
成
绩
任课教师:
年 月 日
word文档 可自由复制编辑
2024年3月7日发(作者:秦正平)
《编译原理课程设计》报告
MiniC编译器设计与实现
分组序号:13
设计地点:微301、文理楼110
电子邮件:
分组成绩:
任课教师:***
专业班级
姓名
学号
成绩比例(%)
成绩
16
20
计算机 12- 班
17
17
15
15
2014 年 12 月19 日word文档 可自由复制编辑
目录
1
2
3
4
4.1
4.2
4.3
4.4
4.5
课程设计目的 ........................................................................................... 1
课程设计内容 ........................................................................................... 1
课程设计原理 ........................................................................................... 1
系统需求分析 ........................................................................................... 4
MiniC编译器总体流程图 .......................................................................................................... 4
功能需求 ..................................................................................................................................... 4
用到的主要关键词: .................................................................................................................... 5
汇编成可执行文件 ..................................................................................................................... 5
MiniC语言的文法 ..................................................................................................................... 5
5
5.1
5.2
5.3
系统设计与实现 ....................................................................................... 8
BY13编译器的主要功能模块 .................................................................................................. 8
词法分析子程序 ......................................................................................................................... 8
语法语义分析子程序 ................................................................................................................. 8
6
6.1
6. 2
6. 3
6.4
6. 5
6. 6
系统测试与运行结果分析 ....................................................................... 9
测试程序1 .................................................................................................................................. 9
测试程序2 .................................................................................................................................. 9
测试程序3 .................................................................................................................................. 9
测试结果1 ................................................................................................................................ 10
测试结果2 ................................................................................................................................ 13
测试结果3 ................................................................................................................................ 16
7
心得体会 ................................................................................................. 19
word文档 可自由复制编辑
1 课程设计目的
(1)根据所掌握的编译原理课程的基本知识,编写出一个 MiniC 编译器;
(2)增强阅读和编写程序的能力;
(3)理解词法分析、语法分析和语义分析在编译程序中的作用;
(4)掌握词法分析、语法分析和语义分析程序的实现方法;
(5)实现 MiniC 编译器的编辑、编译、连接和运行。
2 课程设计内容
用 MFC 编写一个可视化的 MiniC 编译器,要求界面美观,使用方便,能够实现自定义 MiniC语言的编译。
支持的语句和运算:
(1)数据类型:int,char,void,float
(2)语句:赋值(=),if, while,for
(3)数学运算:+,-,*,/
(4)关系运算:==,>,<,>=,<=,!=
(5)逻辑运算:&&,||,!
(6)支持函数的定义、调用
(7)支持复合语句,即 {} 包含的语句
(8)注释: C 类型的多行注释 /* */ 和 C++ 类型的单行注释 //
3 课程设计原理
MiniC 语言可以看成 C 语言的子集,它的编译程序是一个编译执行环境。
MiniC 的编译程序和目标程序的执行程序都是用 C++ 语言编写的,因此 MiniC 语言可在配备C 语言的任何机器上实现。它的编译过程采用从左到右扫描输入符号串,进行最左推导,再向右看一个符号的方式,以语法分析程序为核心,词法分析和汇编代码生成程序都是独立的过程。当语法分析需要读取输入符号串时就调用词法分析程序;而当语法分析正确后,需要生成相应的目标代码(老师只要求到汇编代码,在本程序中则更进一步,是目标文件 .obj 文件和可执行的目标文件 .exe
文件)时,则调用汇编代码生成程序和创建EXE文件程序。
用表格管理程序建立变量、常量和过程标识符的说明与引用之间的信息联系。当源程序编译正确时,编译程序自动调用执行程序,对目标代码进行执行,并按用户程序的要求输入数据和输出运行结果。
(1)运行BY13程序,打开文件。
word文档 可自由复制编辑
(2)选择菜单 编译(C) -> 生成汇编代码(G)。
word文档 可自由复制编辑
(3)选择菜单 编译(C) -> 创建EXE文件(B),生成可执行的目标文件。
(4)选择菜单 编译(C) -> 运行(R),出现如下图所示的结果。
word文档 可自由复制编辑
4 系统需求分析
MiniC 语言编译过程采用从左到右扫描输入符号串,进行最左推导,再向右看一个符号的方式,对源程序分别进行 词法分析、语法分析、语义分析、中间代码生成、目标代码生成和可执行程序生成,此外,用表格管理程序建立变量、常量和过程标识符的说明与引用之间的信息联系.用出错处理程序对词法和语法分析研究遇到的错误给出在源程序中出错的位置和错误性质,它的工作过程如下所示:
输入源代码 ->
词法分析 ->
语法分析 ->
汇编代码生成 -> exe文件生成 ->
运行
4.1 MiniC 编译程序总体介绍
该编译器的运行过程是编辑源文件保存后,生成汇编代码时使用汇编代码生成程序
CAsmCodeGenerator 类,调用该类的成员函数genCodeSeg() 来生成代码段和genPreSeg() 来生成数据段,最后调用emitCode();当然我们在汇编代码生成时应该使用语义分析子程序 CAnalyzer
类对词法和文法出现的各种情况进行展开分析。
4.2 功能需求
(1)用 C++ 语言实现了类C语言,叫做 MiniC 语言;
(2)使用 LL(1) 文法,从左到右扫描输入符号串,进行最左推导,再向右看一个符号;采用递归子程序法实现语法分析,并用 C++ 语言实现了词法分析器、语法分析器、汇编代码生成器,能直接生成 intel 80x86汇编代码。
(3)在声明中实现了对静态常量、变量和函数声明的支持;赋值语句的 = ,基本的数学运算 +、-、*、/ ;
(4)使用函数实现了对过程的调用;
(5)使用 { } 实现复合语句;
word文档 可自由复制编辑
(6)使用函数 read() 来同时读入一个或多个数据,使用函数 write() 来同时输出一个或多个数据,而函数 printf() 只能用来输出字符串;
(7)在循环分支语句中实现了if语句, if……else……语句, for(…,……,……)…语句,while……语句;
(8)关系表达式包括 ==(等于)、!=(不等于)、<、<=、>、>=。
4.3 用到的主要关键词:
关键字等用枚举类型囊括:
enum TokenType
{
// 关键字
_DOUBLE, _INT, _ELSE, _CASE, _ENUM, _REGISTER, _TYPEDEF, _CHAR, _CONST, _FLOAT,
_FOR, _SIGNED, _VOID, _SIZEOF, _VOLATILE, _IF, _WHILE, _READ, _WRITE, _PRINTF,
// 操作符
ASSIGN, PLUS, MINUS, TIMES, DIV, MOD,
BITWISE_AND, BITWISE_OR, BITWISE_NOT, LOGICAL_NOT, LT, GT,
// 界符
LPARAN, RPARAN, LBRACE, RBRACE, LSQUARE, RSQUARE, COMMA, DOT, SEMI, COLON,
//( ) { } [ ] , . ; :
// 复杂操作符
EQ/* == */, NEQ/* != */, PLUS_PLUS/* ++ */, MINUS_MINUS/* -- */,
PLUS_ASSIGN/* += */, MINUS_ASSIGN/* -= */, TIMES_ASSIGN/* *= */, DIV_ASSIGN/* /=
*/,
NGT/* <= */, NLT/* >= */, LOGICAL_AND/* && */, LOGICAL_OR/* || */,
// 其他
_EOF, _ID, _NUM, _STRING, _CHARACTER, _LABEL, _ERROR, _NONE
};
4.4 汇编成可运行文件
采用 intel 80x86 汇编语言,然后调用 MASM 汇编成可执行文件(.exe),可在相应机型的机器上运行。
4.5 MiniC语言的文法
1. <程序> → <声明列表>
2. <声明列表> → <声明列表> <声明> | <声明>
3. <声明> → <变量声明> | <函数声明>
word文档 可自由复制编辑
4. <变量声明> → <类型分类符> ID(, ...)';' | <类型分类符> ID '[' <数字> ']' (, ...)';'
5. <数字> → 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ...
6. <类型分类符> → "int" | "void" | "char" | "float"
7. <函数声明> → <类型分类符> ID '(' <参数> ')' <复合声明>
8. <参数> → <参数列表> | "void"
9. <参数列表> → <参数列表> ',' <参数> | <参数>
10. <参数> → <类型分类符> ID | <类型分类符> ID '[' ']'
11. <复合声明> → '{' <局部声明> <声明列表> '}' | <表达式声明>
12. <局部声明> → <局部声明> <变量声明> | <变量声明>
13. <输入函数> → "read" '(' <变量> ')' ';'
14. <输出函数> → "write" '(' <表达式> ')' ';'
15. <显示函数> → "printf" '(' `"` <字符串> `"` ')' ';'
16. <表达式声明> → <表达式> ';' | ';'
17. <表达式> → <变量> `=` <表达式> | <逻辑表达式1>
18. <变量> → a | b | c | ... | z | A | B | C | ... | Z ...
19. <逻辑表达式1> → <逻辑表达式1> "||" <逻辑表达式2> | <逻辑表达式2>
20. <逻辑表达式2> → <逻辑表达式2> "&&" <简单表达式> | <简单表达式>
21. <简单表达式> → <添加的表达式> <关系操作> <添加的表达式> | <添加的表达式>
22. <关系操作> → "<=" | '<' | '>' | ">=" | "==" | "!="
23. <添加的表达式> → <添加的表达式> <加法操作>
24. <加法操作> → '+' | '-'
word文档 可自由复制编辑
25.
26. <乘法操作> → '*' | '/' | '%'
27. <逻辑表达式3> → '!' <逻辑表达式3> | <因子>
28. <因子> → '(' <表达式> ')' | <变量> | <调用> | <数字>
29. <变量> → ID | ID '[' <表达式> ']'
30. <调用> → ID '(' <形式参数> ')' ';'
31. <形式参数> → <形式参数表列> | ε
32. <形式参数表列> → <形式参数表列> ',' <表达式> | <表达式>
33: <子复合声明> → ID ':' | <调用> | <表达式声明>
34:
35.
36.
37.
38.
39.
40.
word文档 可自由复制编辑
5 系统设计与实现
5.1 BY13编译程序主要功能模块
(1)功能一:取得输入符号串的下一个有效字符,函数为 CTokenizer::NextToken()
(2)功能二:取得下一个有效字符的相关属性,函数为 CScaner::NextToken()
(3)功能三:构造输入串的语法树,函数为 CParser::BuildSyntaxTree()
(4)功能四:遍历语法树,并设置相应的属性,函数为 CAnalyzer::traverse
(5)功能五:语义分析处理,函数为 CAnalyzer::TraceTypeCheck()
(6)功能六:生成汇编语言代码,函数为 CAsmCodeGenerator::GenerateAsmCode
(7)功能七:调用语义类,生成汇编代码,函数为 CBY13Doc::OnCompileBuildAsm()
(8)功能八:调用汇编程序,生成可执行文件,函数为 CBY13Doc::OnCompileBuildExe()
5.2 词法分析子程序
词法分析类为 CScanner 和 CTokenizer,功能是从源程序中读出一个单词符号,把它的信息放入类中,语法分析器需要单词时,可以直接从这个类中获得。
词法分析器的分析过程:构造CTokenizer时,它通过构造函数从源程序中获得一个字符串。如果这个字符是字母,则继续获取字符或数字,最终可以拼成一个单词,查类CScanner 中的关键字表,如果查到为关键字,则把m_tType变量赋成相应的保留字类型值;如果没有查到,则这个单词应是一个用户自定义的标识符(可能是变量名、常量名或是过程的名字),把m_tType置为相应的关键值,把这个单词存入m_tType变量。查关键字表时使用了二分法查找以提高效率。如果m_tType获得的字符是数字,则继续用NextToken()获取数字,并把它们拼成一个整数,然后把m_tType置为number,并把拼成的数值放入m_dVal变量。如果识别出其它合法的符号(比如:赋值号、大于号、小于等于号等),则把m_tType则成相应的类型。
5.3 语法语义分析子程序
语法分析子程序采用了自顶向下的递归子程序法,语法分析同时也根据程序的语义生成相应的代码,并提供了出错处理的机制。语法及语义分析主要涉及到的函数:
(1)函数声明的分析函数 CParser::fun_declaration()
(2)变量定义的分析函数 CParser::var()
(3)复合语句的分析函数 CParser::compound_stmt()
(4)表达式、项、因子的处理函数 CParser::factor()
(5)if 语句的处理函数 CParser::if_stmt()
(6)for 循环的处理函数 CParser::for_stmt()
(7)while 语句的处理函数 CParser::while_stmt()
(8)函数调用的处理函数 CParser::call()
(9)read 语句的处理函数 CParser::read_stmt()
(10)write 语句的处理函数 CParser::write_stmt()
(11)单词合法性与出错恢复过程的分析函数 CParser::ConsumeUntil( enum TokenType type )
word文档 可自由复制编辑
6 系统测试与运行结果分析
6.1 测试程序1
// 求表达式的值
void main()
{
int x, y;
int z;
printf("Please input x and y :n");
read(x); //相当于scanf(&n)
read(y);
z = ( x + y * 5 ) * 4 / 3;
printf("z = ( x + y * 5 ) * 4 / 3 = ");
write(z);
printf("n"); //相当于printf("%d", sum)
}
6.2 测试程序2
// 用 for 循环求 1+2+3+...+n 的值
void main()
{
int n, i, sum;
sum = 0;
printf("Please input n: ");
read(n); //相当于scanf(&n)
for(i=1; i<=n; i=i+1)
{
sum = sum + i;
}
printf("sum = ");
write(sum); //相当于printf("%d", sum)
printf("n");
}
6.3 测试程序3
// 用 while 循环求 1+2+3+...+n 的值
void main()
{
int n, i, sum;
i = 1;
sum = 0;
printf("Please input n: ");
word文档 可自由复制编辑
read(n); //相当于scanf(&n)
while(i <= n)
{
sum = sum + i;
i = i + 1;
}
printf("sum = ");
write(sum); //相当于printf("%d", sum)
printf("n");
}
6.4 测试结果1
(1)运行BY13程序,打开文件。
(2)选择菜单 编译(C) -> 编译过程(T) -> 扫描单词(S)。
word文档 可自由复制编辑
(3)选择菜单 编译(C) -> 生成汇编代码(G)。
word文档 可自由复制编辑
(4)选择菜单 编译(C) -> 创建EXE文件(B),生成可执行的目标文件。
(5)选择菜单 编译(C) -> 运行(R),出现如下图所示的结果。
word文档 可自由复制编辑
6.5 测试结果2
(1)运行BY13程序,打开文件。
(2)选择菜单 编译(C) -> 编译过程(T) -> 扫描单词(S)。
word文档 可自由复制编辑
(3)选择菜单 编译(C) -> 生成汇编代码(G)。
word文档 可自由复制编辑
(4)选择菜单 编译(C) -> 创建EXE文件(B),生成可执行的目标文件。
(5)选择菜单 编译(C) -> 运行(R),出现如下图所示的结果。
word文档 可自由复制编辑
6.6 测试结果3
(1)运行BY13程序,打开文件。
(2)选择菜单 编译(C) -> 编译过程(T) -> 扫描单词(S)。
word文档 可自由复制编辑
(3)选择菜单 编译(C) -> 生成汇编代码(G)。
word文档 可自由复制编辑
(4)选择菜单 编译(C) -> 创建EXE文件(B),生成可执行的目标文件。
(5)选择菜单 编译(C) -> 运行(R),出现如下图所示的结果。
word文档 可自由复制编辑
7 心得体会
转眼间,这个学期的编译原理课程设计已经接近尾声,虽然时间不是很多,仅仅一周两节课,但是回顾这段时间,我们也可以说是受益匪浅。
这个学期的课程设计是跟编译原理课一起开的,这样的话对于我们而言是一个挑战,因为虽然我们也是按照老师的要求,在我们学习了文法之后就写出所有的文法,学了语句分析,就完成相应的语句分析的部分,但是与此同时,我们面临的一个问题就是不明白做这个编译器的原理步骤,后来经过查找资料,还有我们全组的讨论,最终明白了大致的原理,进而确定了我们要实现的功能,做好了前期的规划。
在我们以前用Visual C++ 的时候,只是感觉它的功能很强大,当然这是我们很羡慕的一个地方,我们虽然不能做的像它那么强大,那么完美,但是我们也是尽量地实现更多的功能。最后是暂定的几个常用的,然后根据时间做了相应的调整。
起步的时候是最难的,起步之后似乎就顺手了很多,当然也不排除在某些地方遇到卡壳,然后花费了很多时间去想解决方案,进而实现。
总结这个学期以来的课程设计,我学到了很多。首先是一个知识面的问题,开始的时候会有很多的问题,但是借助现在发达的网络,还有图书馆的书籍,我们最终解决了问题。而且不仅仅是解决一个问题的事情,在解决问题的过程中,也从各个方面充实了自己,提升了自己。
通过这次课程设计,我们可以将课上学习到的相关的知识应用到这个设计的过程中。以前的学习都是只是一个字面上的理解,尤其是那些抽象的东西,根本就应用不到实践中,然而这次课程设计正好解决了此弊端。虽然一边学习一边应用有一定的难度,但是只要克服了,还是好处多多的。首先,遇到难解的问题,我们会查找相关的资料,或者自学后面的内容,因为这些组合在一起之后,再运用一定的原理方法,就可以实现最终的结果,所以在课程设计提高自己动手实践能力的同时,还巩固提高了我们之前学的理论知识。
我认为学习的一个境界就是学以致用,学会了会用才是关键,我们学习这些知识就是为了运用的,将科学转化为技术。编译原理课程设计正好是一个很好的过渡。比如,我们在学习了文法,语句分析之后,还是不知道怎样用程序来实现语句的分析,我们用得比较少,所以不是用的自动机实现的,所以实现起来比较麻烦,但是这样正好是将我们原来学习的知识用之于实践。
过程中遇到问题是正常的,但是我们相信只要努力,一定会迎刃而解。Any thing is possible!
总之,通过这次编译原理课程设计,我学到了很多,也收获了很多。
word文档 可自由复制编辑
教 师 评 语 专 栏
任
课
教
师
评
语
成
绩
任课教师:
年 月 日
word文档 可自由复制编辑