编译原理实验 词法分析

  • 格式: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)