编译原理实验一词法分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《编译原理》(2014-2015学年第1学期)
实
验
报
告
学号:2012329620058
姓名:胡冰倩
班级:12计科3班
实验一:词法分析程序
一、实验目的
1、构造一个《科学计算器》的词法分析程序,程序要求能对输入的字符串流进行词法分析。
2、在实验的过程中,学会应用词法分析的方法——构造NFA和DFA。
二、实验内容和要求
1、科学计算器的功能
作为一个科学计算器,最重要的自然是能够计算,以下是罗列的一些可以实现的功能:
1)基本四则运算
2)三角函数计算
3)指幂运算
4)表达式求值
5)log运算
6)提供一些基本常数,如PI、e等
7)进制转换
8)变量存储
2、要实现该科学计算器,本次实验首先需要完成词法分析,下面列举4个输入的表达式,:
1.0+2*3=
1.0+(2*3+cos3)/3.6-6=
tg(1.0+(sin2*3+cos3)/3.6-6)=
4.0log(1.0+(sin2*3+cos3)/3.6-6)=
期望程序能根据实现的DFA对任给的一个输入串进行词法分析,程序的输出为单词的token序列$(CLASS, V ALUE) 。CLASS中存放类别,V ALUE中存放token的值,如第一个算式,其输出为:
$(CLASS,V ALUE)
$( number, 1.0)
$( plus, + )
$(number, 2)
$(mul, * )
$(number, 3)
关于TOKEN的分类(CLASS),可将所有标识符归为一类;将常数归为另一类;保留字和分隔符则可采取一词一类。
对于变量标识符和常数,CLASS字段为相应的类别码,V ALUE字段则是该标识符、常数在其符号表中登记项的序号。
3、程序应通过DFA来完成词法分析。可参考的DFA如下图:
图中每一个箭头表明一个字符的输入,由于这个输入,自动机从一个状态变为另一个状态。同学们可以根据自己的理解自行设计DFA。该DFA需能够识别
本实验中要实现的科学计算器的所有TOKEN。
采用有限自动机(DFA)进行分析,对于特定符号如+、-、*、/、%、(、)、!、^、=,为每一个符号提供一个状态、而其他的一些由字母组成的符号,如ans、pi、sto、clr等,则作为是一个词,之后再对词进行分类处理。
(提示:可以参考教材中lex部分的章节,DFA的实现同学们可以使用lex 实现(自行搜索下载),也可以自已编码实现。)
三、分析过程及源代码
1.token的分类
将一些由字母组成的函数及常数,如:PI、e、sin、cos、tan、log等归为一
2.有限状态机状态图
3.词法分析器的数据结构与算法
1 2 3 4 5 6 7 8 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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 #include
#include
#include
using namespace std;
char prog[80],token[8];
char ch;
string CLASS;
int p,m=0,n;
char*word[6]={"PI","e","log","sin","cos","tg"};
void scaner()
{
for(n=0;n<8;n++)
token[n]=NULL;//把token数组初始化
ch=prog[p++];
while(ch==' ')
{
ch=prog[p];
p++;
}
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))//如果是字母,则这个token是词
{
m=0;
while((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{
token[m++]=ch;
ch=prog[p++];
}
p--;
CLASS="word";
}
else if((ch>='0'&&ch<='9'))//数字
{
{
m=0;
while((ch>='0'&&ch<='9')||(ch=='.'))
{
token[m++]=ch;
ch=prog[p++];
}
}//把数字由字符类型转化为整数类型
CLASS="number";
p--;
}
else switch(ch)//其他字符
{
case'*':CLASS="mul";token[0]=ch;break;
case'/':CLASS="div";token[0]=ch;break;
case'+':CLASS="plus";token[0]=ch;break;
case'-':CLASS="minus";token[0]=ch;break;
case'=':CLASS="equ";token[0]=ch;break;
case'(':CLASS="lf";token[0]=ch;break;
case')':CLASS="rg";token[0]=ch;break;
case'^':CLASS="pow";token[0]=ch;break;
case'%':CLASS="mod";token[0]=ch;break;