编译原理实验 词法分析
- 格式:doc
- 大小:86.50 KB
- 文档页数:15
实验一 简单词法分析器构造(4学时)
一 实验目的
1、 掌握正则表达式、有限自动机
2、 构造简单的词法分析器
二 词法规则(C语言分析及状态转换图)
1、C语言说明
C语言有以下记号及单词
(1)标识符:以字母或下划线开头的,后跟字母、数字或下划线组成的符号串。
(2)保留字:标识符的子集。
(3)无符号数:
(4)关系运算符:>、<、>=、 <= 、= = 、!=
(5)标点符号:+、-、*、/、(、)、:、,、;等
(6)赋值号: =
(7)注释标记:以‘/*’开始,以‘*/’结束。
(8)单词符号间的分隔符:空格。
2、记号的正规表达式(学生完成)
(1)标识符:
(2)无符号数:
(3)关系运算符:
(4)赋值号:
(5)标点符号:
3、状态转换图
为每种记号的文法构造出相应的状态转换图,让这些状态转换图共用一个初态,就可以得到词法分析器的状态转换图,如图1所示。(部分)
...
图 1 (a)关系运算符的状态转换图
(b)标识符的状态转换图
(c)数字的状态转换图
三、词法分析器的构造与实现
1、词法分析器的算法框图
在开始状态,首先要读进一个字符。若读入的是一个空格(包括blank,tab,newline)就跳过它,再继续读字符,直到读进一个非空字符为止。
在标识符状态,识别并组合出一个标识符之后,还必须加入一些动作,以便查保留字表,确定识别出的单词符号是保留字,还是用户自定义标识符,并输出相应的记号。
在无符号数状态,可识别出各种常数,包括整数在内。在组数的同时,还要做从十进制数到二进制数的转换。
.2、程序结构图:
Scanner
IsAlpha Isnumber IsOther
OUTPUT ERROR 注:
1 Scanner
功能:完成初始化,并循环调用子模块完成单词的识别
2 IsAlpha
功能:识别保留字和标识符
3 IsNumber
功能:识别数字
4 IsOther
功能:识别其他字符
5 OutPut
功能:输出识别的单词(二元式)
6 Error
功能:出错处理
程序代码(略)
四. 源代码
#include "stdafx.h"
#include "stdio.h"
#include "ctype.h"
#include "string.h"
#include "conio.h"
#include "stdlib.h"
#define KEYWORD_LEN 32
#define STR_MAX_LEN 300
#define PRO_MAX_LEN 20480
#define STB_MAX_LEN 1000
#define CTB_MAX_LEN 1000
#define ERROR 0
#define ID (KEYWORD_LEN+1)
#define CONST (KEYWORD_LEN+2)
#define OPERAT (KEYWORD_LEN+3)
#define DIVIDE (KEYWORD_LEN+4)
int errorLine=0;
char proBuffer[PRO_MAX_LEN] = "";
char ch;
char wordget[STR_MAX_LEN];
int point = 0;
char signTab[STB_MAX_LEN][STR_MAX_LEN];
int pointSTB = 0; char constTab[CTB_MAX_LEN][STR_MAX_LEN];
int pointCTB = 0;
char kwTab[KEYWORD_LEN][10]={ "auto", "break", "case", "char",
"const",
"continue", "default", "do", "double", "else",
"enum", "extern", "float", "for", "goto",
"if", "int", "long", "register", "return",
"short", "signed", "sizeof", "static", "struct",
"switch", "typedef", "union", "unsigned", "void",
"volatile", "while"};
char errorTab[][50]={
/*0*/"未知错误", /*1*/"非法的字符", /*2*/"不正确的字符常量表达",
/*3*/"不正确的字符串表达", /*4*/"不正确的数字表达", /*5*/"注释丢失'*/'"};
typedef struct signDuality
{
int kind;
int value;
}*pDualistic, Dualistic;
void pretreatment();
void ProcError(int id);
bool GetChar();
bool GetBC();
void Concat(char *str);
int Reserve(char *str);
void Retract();
int InsertId(char *str);
int InsertConst(char *str);
bool wordAnalyse(pDualistic pDu);
void pretreatment()
{int lines=0;
char tmp[PRO_MAX_LEN];
int tmpp = 0;
bool flg;
char tmpc;
point = 0;
do
{ flg = GetChar();
if(ch == '/')
{
flg = GetChar();
switch(ch)
{
case '/':
do
{
flg = GetChar();
}while(!(ch == '\n' || flg == false));
if(ch == '\n')
Retract();
break;
case '*':
do
{
flg = GetChar();
tmpc = ch;
if(tmpc == '\n')
tmp[tmpp++] = tmpc;
flg = GetChar();
Retract();
}while(flg && !(flg && tmpc == '*' && ch == '/'));
flg = GetChar();
if (!flg)
{
ProcError(5);
}
break;
default:
Retract();
Retract();
GetChar();
tmp[tmpp++] = ch;
flg = GetChar();
tmp[tmpp++] = ch;
}
}
else
{ tmp[tmpp++] = ch;
}
}while(flg);
tmp[tmpp] = '\0';
strcpy(proBuffer,tmp);//
}
void ProcError(int id)
{
printf("\nError:第%d行,%s\n",errorLine, errorTab[id]);
}
bool GetChar()
{
if(point < PRO_MAX_LEN && proBuffer[point] != '\0')
{
ch = proBuffer[point++];
if (ch == '\n')
errorLine ++;
return true;
}
ch = '\0';
return false;
}
bool GetBC()
{
do
{
if(!GetChar())
{
ch = '\0';
return false;
}
}while(isspace(ch));
return true;
}
void Concat(char *str)