实验内容
对一个简单语言的子集编制一个一遍扫描的词法分析程序。
实验目的
(1)理解词法分析在编译程序中的作用
(2)加深对有穷自动机模型的理解
(3)掌握词法分析程序的实现方法和技术
实验要求
(1)待分析的简单语言的词法
-
关键字
begin if then while do end -
运算符和界符
:= + - * / < <= > >= <> = ; ( ) # -
其他单词是标识符(ID)和整形常数(NUM),通过以下正规式定义:
ID=letter(letter|digit)*
NUM=digitdigit* -
空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。
(2)各种单词符号对应的种别编码
(3)词法分析程序的功能
输入:所给文法的源程序字符串
输出:二元组(syn,token或sum)构成的序列。
syn为单词种别码;
token为存放的单词自身字符串;
sum为整形常数。
例如:对源程序begin x:=9;if x>0 then x:=2*x+1/3;end# 经词法分析后输出如下序列:(1,begin)(10,’x’) (18,:=) (11,9) (26, ; ) (2,if)……
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define _KEY_WORD_END "waiting fou your expanding"/*定义关键字的结束标志*/
using namespace std;
typedef struct
{
int typenum; /*种别码*/
char *word;
}WORD;
char input[255]; /*源程序缓字符冲区*/
char token[255] = ""; /*单词缓冲区*/
int p_input; /*源程序字符指针*/
int p_token; /*单词缓冲区指针*/
char ch;
char *rwtab[] = {
"begin","if","then","while","do","end",_KEY_WORD_END };
WORD *scaner(); /*词法扫描函数,获得一个单词*/
void main()
{
int over = 1;
int count = 0;
WORD *oneword = new WORD;
printf("Enter Your words(end with #):");
scanf("%[^#]s", input); /*输入源程序字符串到缓冲区,以#结束*/
p_input = 0;
printf("词法分析结果是:\n\n");
while (over < 1000 && over != -1)
{
oneword = scaner();
if (oneword->word == "OVER")
break;
else if (oneword->typenum < 1000)
printf("(%d,%s) ", oneword->typenum, oneword->word);
over = oneword->typenum;
count++;
if (count % 6 == 0) printf("\n");//每六行输出
}
system("pause");
}
char m_getch() /*从输入源读一个字符到CH中*/
{
ch = input[p_input];
p_input = p_input + 1;
return ch;
}
void getbc() /*去掉空白字符*/
{
while (ch == ' ' || ch == 10)
{
ch = input[p_input];
p_input = p_input + 1;
}
}
void concat() /*拼接单词*/
{
token[p_token] = ch;
p_token = p_token + 1;
token[p_token] = '\0';
}
int letter()/*判断是否是字母*/
{
if (ch >= 'a' && ch <= 'z' || ch >= 'A'&& ch <= 'Z')
return 1;
else return 0;
}
int digit()/*判断是否是数字*/
{
if (ch >= '0'&& ch <= '9')
return 1;
else return 0;
}
int reserve()/*检索关键字表格*/
{
int i = 0;
while (strcmp(rwtab[i], _KEY_WORD_END))
{
if (!strcmp(rwtab[i], token))
{
return i + 1;
}
i = i + 1;
}
return 10;
}
void retract()/*回退一个字符*/
{
p_input = p_input - 1;
}
char *dtb()
{
return NULL;
}
WORD *scaner()/*词法扫描程序*/
{
WORD *myword = new WORD;
myword->typenum = 10;
myword->word = " ";
p_token = 0;
m_getch();
getbc();
if (letter())
{
while (letter() || digit())
{
concat();
m_getch();
}
retract();
myword->typenum = reserve();
myword->word = token;
return myword;
}
else if (digit())
{
while (digit())
{
concat();
m_getch();
}
retract();
myword->typenum = 11;
myword->word = token;
return myword;
}
else switch (ch)
{
case'=': m_getch();
if (ch == '=')
{
myword-