实验一 词法分析程序实现
一、实验目的与要求
通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程
中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。
二、实验内容
选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出
来。
输入:由无符号数和+,-,*,/, ( , ) 构成的算术表达式,如 1.5E+2-100。
输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。
三、实现方法与环境
1、首先设计识别各类单词的状态转换图。
描述无符号常数的确定、最小化状态转换图如图 1 所示。其中编号 0,1,2,…,6 代
表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<
整指数>及<余留整指数>, 1,2 和 6 为终态,分别代表整数、小数和科学计数的识别结束
状态。
图 1 文法 G[<无符号数>]的状态转换图
其中编号 0,1,2,…,6 代表非终结符号<无符号数>、<余留无符号数>、<十进小数>、
<小数部分>、<指数部分>、<整指数>及<余留整指数>, 1,2 和 6 为终态,分别代表整数、
小数和科学计数的识别结束状态。
四、参考资料
实现无符号数识别的参考方法:将设计的状态转换图直接转化为一张程序流程图,并在
外层再增加一个以 EOF 为循环终止条件的 while 循环,即形成能连续识别各类单词的词法
分析程序。
各类单词的编码建议如表 1。
表 1 单词的内部编码
单词符号
无符号数
+
-
*
/
(
)
五、流程图
类别码(CLASS)
1
2
3
4
5
6
7
单词值(VALUE)
数字值
无值
无值
无值
无值
无值
无值
Saomiao 子程序流程图:
变量初始化
运算符
数字
其他
符号
出错
syn=-1
对不同符号给
出相应的 syn 值
主程序流程:
无符号数
syn=1
返回
输入待测字符串
调用扫描子程序
输出单词二元组
结束
六、源代码
#include
#include
#include
#include
#include
char pr[80],shib[8],ch;
//数组 pr 存放待测的字符串,数组 shib 存放已识别字符
int s,p,m,n;
//s 为字符的类型码,p 为数组 pr 的指针,m 为数组 shib 的指针
saomiao()//扫描子程序
{
m=0;
ch=pr[p++];
if((ch>='0')&&(ch<='9')) //识别无符号数
{
while((ch>='0')&&(ch<='9'))
{
shib[m++]=ch;
ch=pr[p++];
if(ch=='.')
{
//遇到小数情况
shib[m++]=ch;
ch=pr[p++];
while((ch>='0')&&(ch<='9'))
{
shib[m++]=ch;
ch=pr[p++];}
}
if(ch=='E')
{
//遇到科学计数情况
shib[m++]=ch;
ch=pr[p++];
if(ch=='+'||ch=='-')
{
shib[m++]=ch;
ch=pr[p++];
while((ch>='0')&&(ch<='9'))
shib[m++]=ch;
ch=pr[p++];
{
}
}
}
}
p--;
s=1;
}
else switch(ch)
{
//识别运算符号
case '+':
s=2;
shib[m++]=ch;
break;
case '-': s=3;
shib[m++]=ch;
break;
case '*': s=4;
shib[m++]=ch;
break;
case '/': s=5;
shib[m++]=ch;
break;
case '(': s=6;
shib[m++]=ch;
break;
case ')': s=7;
shib[m++]=ch;
break;
case '\n': s=0;
shib[m++]=ch;
break;
default: s=-1;
break;
}
shib[m++]='\0';
//主函数
}
main()
{p=0;
printf("\n 请输入字符串:\n");
do{
//输入待测字符串并放在数组 pr 中
scanf("%c",&ch);
pr[p++]=ch;
}while(ch!='\n');
p=0;
do{
saomiao();
switch(s)
//调用 saomiao 函数
//不同情况的输出
{case 1:printf("(%s%5d )\n",shib,s);
break;
case -1:printf("输入了一个错误字符\n");
getch();
exit(0);
case 0: break;
default: printf("( %s%5d )\n",shib,s);
break;
}
}while(s!=0);
getch();
}
出 错 时
间
编
号
1 实 验 一
第 1 课
时
2 实 验 一
第 2 课
时
3 实 验 一
第 2 课
时
出错代码
错误提示
出错原因分析
修改方法 修改结果
exit(0);
error C2065:
'exit'
undeclared identifier
:
exit() 包 含 在
winsock.h 库函数中
else switch(ch)
error C2181:
illegal
else without matching
if
If 语句中丢了最后
一个大括号
if(ch='+'||ch='-')
error C2106: '=' : left
operand
be
l-value
must
将赋值与内容判断
弄混
消 除 了 1
个错误
消 除 了 3
个错误
消 除 了 1
个错误
在 程 序 开
头 添 加
#include
在 If 语句
的 最 后 添
加 一 个 大
括号
将 原 语 句
改
为
if(ch=='+'||
ch=='-')