直接粘实验报告,debug的时间较少,估计还有很多错儿,有些情况没考虑到。不过状态机的基本思路就是这样,其他的部分可以自行删改。
一、实验概述
1.1、实验要求
选择计算机高级语言之一-----C语言,运用恰当的此法分析技术线路,设计和实现其对应的词法分析器。
建议:编程语言,选择《计算机程序设计》课程所采用的语言。
提示:技术线路选择如下两种之一:
正则式→NFA→DFA→minDFA→程序设计
或正则文法→NFA→DFA→minDFA→程序设计。
要求:分析器输出结果存入到磁盘文件中,具有出错处理功能。
1.2、实验目的
1)加深对编译原理及其构造词法分析器的原理和技术理解与应用,进一步提高学生编程能力;
2)培养、提高学生分析问题、解决问题的综合能力;
3)整理资料,撰写规范的实验报告;
二、系统分析
2.1、系统需求
根据C语言语法,待分析的词可以分为如下几类:
(1) 关键字
如if, else, whlile, int 等。
(2) 标示符
开头只能为字母,后面可以接数字或者字母,用来表示各种名字,如变量名、常量名和过程名等
(3) 常数
各种类型的常数,如整型(1, 30),浮点型(2.16),字符串型(”AHD”),字符型(’A’)
(4) 运算符与界符
如+, *, <= , 逗号等。
2.2、系统功能
读入一个C语言源程序(经过预处理的),对每一个单词输出一些三元组的集合。
2.3、系统实现步骤
按照如下顺序构造词法分析器:
(1) 设计出各类单词的正规式,画出有限状态自动机。
(2) 将各类单词的正规式转换成相应的NFA M,并将其合并成一个NFA M`
(3) 将NFA M`转换成对应的DFA M``
(4) 将DFA M``最小化为DFA M```
(5) 根据DFA M```用C语言设计出相应的词法分析器。
三、系统设计
3.1、有限状态自动机设计
状态机说明:由于单词的构成较为复杂,所以再设计时,边的变迁不再是一个字符,而是一个函数。若当前输入串满足该函数,则当前状态可以变迁到该边连接的下一状态。
根据终态可以看出自动机可以分离的状态有:
INT |
整数 |
FLOAT |
浮点数 |
CHAR |
字符型 |
CHARS |
字符串型 |
IDENT |
标识符(包括关键字) |
SYMBOL |
符号 |
其中,关键字的分离在辅助程序中进行。
3.2、单词符号对应的种别码
种别码 |
单词符号及说明 |
种别码 |
单词符号及说明 |
0 |
INT(整数) |
30 |
>= |
1 |
FLOAT(浮点数) |
31 |
<= |
2 |
CHAR(字符型) |
32 |
> |
3 |
CHAR(字符串型) |
33 |
< |
4 |
IDENT(标识符) |
34 |
== |
5 |
if |
35 |
= |
6 |
else |
36 |
!= |
7 |
int |
37 |
++ |
8 |
char |
38 |
+= |
9 |
float |
39 |
+ |
10 |
double |
40 |
/ |
11 |
long |
41 |
- |
12 |
short |
42 |
\ |
13 |
return |
43 |
; |
14 |
while |
44 |
( |
15 |
break |
45 |
) |
16 |
|
46 |
{ |
17 |
|
47 |
} |
18 |
|
48 |
[ |
19 |
|
49 |
] |
20 |
|
50 |
: |
21 |
|
51 |
-> |
22 |
|
52 |
? |
23 |
|
53 |
, |
24 |
|
54 |
. |
25 |
|
55 |
* |
26 |
|
56 |
|
27 |
|
57 |
|
28 |
|
58 |
|
29 |
|
59 |
|
3.3、基本数据结构及代码设计
代码是用C++完成的。为状态机定义了两个基本的结构体,分别为STATE和LIST。其中STATE是LIST的友元,STATE表示的是状态机中的一个状态,包括error和start等状态。LIST的实例是依附于一个STATE的实例存在的,他表示一条边,边的值是一个函数指针,该边指向一个满足该函数的另一状态。
另外用到了STL库中的MAP模板,定义为map
程序的输出为三元组的集合,其中三元组定义为<单词名, 单词含义 ,种别码>。如一个标识符abc的三元组为
四、系统实现
4.1 系统运行
l 在命令行里直接输入待翻译的文件和输出的文件名。如果没有给参数,缺省为输入”input.txt”,输出”output.txt”。
l 输出的结果。
4.2 系统结果
l input.txt
其中,第六行为错误行。
int main()
{
freopen("input.txt","r",stdin);
char input[255],*s = input;
int t = 1;
floatp = 12.4;
int 0a = 2;
init();
while(gets(s))
{
curn = 0;
printf("Line %d:\n",t++);
while((*s)!= 0)
{
while((*s) == ' ') s++;
curn = 0;
curtype = 0;
print(s,start->start(s));
s += curn;
}
}
return 0;
}
l output.txt
********Line 1*********:
<(, (, 34>
<), ), 35>
********Line 2*********:
<{, {, 36>
********Line 3*********:
<(, (, 34>
<"input.txt",CHARS, 2>
<,, ,, 43>
<"r", CHARS, 2>
<,, ,, 43>
<), ), 35>
<;, ;, 33>
********Line 4*********:
<[, [, 38>
<255, INT, 0>
<], ], 39>
<,, ,, 43>
<*, *, 45>
<=, =, 25>
<;, ;, 33>
********Line 5*********:
<=, =, 25>
<1, INT, 0>
<;, ;, 33>
********Line 6*********:
<=, =, 25>
<12.4, FLOAT, 1>
<;, ;, 33>
********Line 7*********:
error: 0a
<=, =, 25>
<2, INT, 0>
<;, ;, 33>
********Line 8*********:
********Line 9*********:
<(, (, 34>
<), ), 35>
<;, ;, 33>
********Line 10*********:
********Line 11*********:
<(, (, 34>
<(, (, 34>
<), ), 35>
<), ), 35>
********Line 12*********:
<{, {, 36>
********Line 13*********:
<=, =, 25>
<0, INT, 0>
<;, ;, 33>
********Line 14*********:
<(, (, 34>
<"Line %d:\n",CHARS, 2>
<,, ,, 43>
<++, ++, 27>
<), ), 35>
<;, ;, 33>
********Line 15*********:
<(, (, 34>
<(, (, 34>
<*, *, 45>
<), ), 35>
<0, INT, 0>
<), ), 35>
********Line 16*********:
<{, {, 36>
********Line 17*********:
<(, (, 34>
<(, (, 34>
<*, *, 45>
<), ), 35>
<==, ==, 24>
<' ', CHAR, 2>
<), ), 35>
<++, ++, 27>
<;, ;, 33>
********Line 18*********:
<=, =, 25>
<0, INT, 0>
<;, ;, 33>
********Line 19*********:
<=, =, 25>
<0, INT, 0>
<;, ;, 33>
********Line 20*********:
<(, (, 34>
<,, ,, 43>
<-, -, 31>
<>, >, 23>
<(, (, 34>
<), ), 35>
<), ), 35>
<;, ;, 33>
********Line 21*********:
<+=, +=, 28>
<;, ;, 33>
********Line 22*********:
<}, }, 37>
********Line 23*********:
<}, }, 37>
********Line 24*********:
********Line 25*********:
<0, INT, 0>
<;, ;, 33>
********Line 26*********:
<}, }, 37>
*******************************
1 error!
116 Word Have Been Found Out!
源代码:
#include
#include
#include