词法分析器C语言编译原理
院(系): 信息技术学院 专业:
学生姓名:,
班级:,, 学号:
题目: 词法分析器 ,,,,,
起迄日期: ,2012-11-21 ,,,
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
地点: 指 导 教 师:
完成日期: 2012 年 11 月21 日
C(1词法分析器 C(1.1 实验目的
设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 C(1.2实验要求
C(1.2.1待分析的简单语言的词法
(1)关键字:
bengin if then while do end start for
所有的关键字都是小写。
(2)运算符和界符:
:= + - * / < <= <> > >= = ; ( ) # ! @ &
(3)其他单词是标志符(ID)和整形常数(NUM),通过以下正规式定义:
ID=letter(letter|digit)*
NUM=digit digit*
(4)空格由空白、制
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
符和换行符组成。空格一般用来分隔ID、NUM、运算符、界符
和关键字,词法分析阶段通常被忽略。
C(1.2.2各种单词符号对应的种别码
单词符号 种别码 单词符号 种别码
begin 1 : 17
if 2 := 18
then 3 < 20
while 4 <> 21
do 5 <= 22
end 6 > 23
Letter(letter|digit) 10 >= 24
digit digit * 11 = 25
+ 13 ; 26
- 14 ( 27
* 15 ) 28
/ 16 # 0
! 29 @ 30
^ 30 & 30
C(1.2.3词法分析程序的功能
输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;
token为存放的单词自身字符串;
sum为整形常数。
功能测试:
(1) 程序调试界面如下:
1
(2) 输入字符串begin x:=9; for x>0 then x:= 2*x@1/3; end #
其结果如下图所示:
2
(3) 输入字符串:!@^& #其结果如下图所示:
(4) 输入字符串where#其输出结果如下图所示:
3
(5) 输入字符串1234# 其结果显示如下:
(6) 输入字符串 @# 其结果显示如下:
4
(7) 输入字符串 ^^^^^^# 其结果显示如下:
C(1.3 词法分析程序的基本思想
算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想示根据扫描到单词符号的第一字符的种类,拼出相应的单词符号。
1. 主程序示意图
主程序示意图如图C。1所示。其中初值包括如下两个方面:
(1) 关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫
描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否
则为一般标识符。关键字表为一个字符串数组,其描述如下:
char * rwtab[6]{“begin ”,”if”,”then”,”while”,”do”,”end” ,“start”, “for” };
5
图C.1 词法分析主程序示意图
(2) 程序中需要用到的主要变量为syn,token和sum。
2. 扫描子程序的算法思想
首先设置3个变量:a.token用来存放构成单词符号的字符串;b.sum用来存放整形单词;c.syn用来存放单词符号的种别码。扫描子程序主要部分流程如图C.2所示。
图C.2 词法分析程序流程
C.1.4 词法分析程序源代码
#include
#include
char prog[80],token[6];
6
char ch;
int syn,p,m,n,sum;
char * rwtab[8]={"begin","if","then","while","do","end","start","for"};
main()
{
p=0;
printf("\n你好,请输入:");
do
{
ch=getchar();
prog[p++]=ch;
}while(ch!='#');
p=0;
do
{
scaner();
switch(syn)
{
case 11:printf("(%d,%d)",syn,sum);break;
case -1:printf("input error\n"); break;
default:printf("(%d,%s)",syn,token);
}
}while(syn!=0);
getch();
}
/*词法扫描程序:*/
scaner()
{
for(n=0;n<8;n++)
token[n]=NULL;
m=0;
ch=prog[p++];
while(ch==' ')ch=prog[p++];
if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A'))
{
while((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')||(ch<='9'&&ch>='0'))
{
token[m++]=ch;
ch=prog[p++];
}
token[m++]='\0';
ch=prog[--p];
syn=10;
7
for(n=0;n<8;n++)
if(strcmp(token,rwtab[n])==0)
{
syn=n+1;
break;
}
}
else
if((ch<='9'&&ch>='0'))
{
sum=0;
while((ch<='9'&&ch>='0'))
{
sum=sum*10+ch-'0';
ch=prog[p++];
}
ch=prog[--p];
syn=11;
}
else
switch(ch)
{
case '<':m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='>')
{
syn=21;
token[m++]=ch;
}
else
if(ch=='=')
{
syn=22;
token[m++]=ch;
}
else
{
syn=20;
ch=prog[--p];
}
break;
case '>':token[m++]=ch;
ch=prog[p++];
if(ch=='=')
8
{
syn=24;
token[m++]=ch;
}
else
{
syn=23;
ch=prog[--p];
}
break;
case ':':token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=18;
token[m++]=ch;
}
else
{
syn=17;
ch=prog[--p];
}
break;
case '+':syn=13;token[0]=ch;break;
case '-':syn=14;token[0]=ch;break;
case '*':syn=15;token[0]=ch;break;
case '/':syn=16;token[0]=ch;break;
case ':=':syn=18;token[0]=ch;break;
case '<>':syn=21;token[0]=ch;break;
case '<=':syn=22;token[0]=ch;break;
case '>=':syn=24;token[0]=ch;break;
case '=':syn=25;token[0]=ch;break;
case ';':syn=26;token[0]=ch;break;
case '(':syn=27;token[0]=ch;break;
case ')':syn=28;token[0]=ch;break;
case '#':syn=0;token[0]=ch;break;
case '!':syn=29;token[0]=ch;break;
case '@':syn=30;token[0]=ch;break;
case '^':syn=30;token[0]=ch;break;
case '&':syn=30;token[0]=ch;break;
default:syn=-1;
}
}
9