实验1.1 根据状态转换图手工构造词法分析程序

发布时间:2024-11-17

编译原理 实验报告

实验类型 : 单元实验

实验名称 :

基础实验 / 选做实验 实验1.1 根据状态转换图手工构造词法分析程序

姓名: ______________ 学号: ____________ 班级: _________________

一、原创性声明

参考代码:

参考了两处代码,第一部分是关键字的定义,自己想的没有这位学长写的全面,所以就直接拿过来用了;第二部分是参考学长的文件读写操作部分。

代码来源:百度文库《编译原理课程设计词法分析器文档》作者是烟大张金荣学长。

二、实验要求

1. 手工构造一个简单的词法分析程序。

- 能够识别标识符、整数、关键字、算符、界符 - 可输出至文件,也可输出至屏幕

★ 1. 使用缓冲技术(单缓冲或双缓冲)

2. 词法分析器作为一个子程序被语法分析器调用。 每次调用返回一个单词

同时将单词及属性存入符号表

★★ 根据状态转换图手工构造词法分析程序。从以下方法中选一:

直接转向法 表驱动法

三、完成情况

功能1 : 基本内容

功能描述:

- 能够识别标识符、整数、关键字、算符、界符 - 可输出至文件,也可输出至屏幕

完成情况: 基本完成

Bug:能发现的bug都已修改,

备注: 标识符、整数、关键字、算符、界符都是自定义的,并不能识别所有的标识符、整

数、关键字、算符、界符

功能2 : 选做内容

功能描述: 使用缓冲技术(双缓冲)

根据状态转换图手工构造词法分析程序:直接转向法

完成情况: 基本完成

Bug: 能发现的bug都已修改,

备注: 代码中有几个方法是多余的:

bool isIdentifier(char *s)/*是否是标识符*/ bool isNumber(char *s)/*是否为数字*/

原本是想在main函数中调用这两个函数,使main函数结构更加简单明了,结果发现加不进去,会破坏代码的逻辑。

四、实现方案

状态转换图:

五、创新和亮点

创新之处:并没什么创新之处,

亮点:用了GOTO语句,使代码易读性增强。

底层的操作都在最基本的函数中,其他函数再调用这些函数来实现自己的功能,这 些函数又供其他函数调用。使代码逻辑性,易读性增强。

Main函数中不写多余代码,调用其他方法,结构清晰。

六、运行结果

输入内容:

输出结果(部分):

七、源码

/*********************************************************/

#include <iostream> #include <fstream> #include <string> using namespace std; /*各种变量的定义*/

String keywords[36] ={"char","short","int","unsigned","long","float","double",

char delimiters[] = { '[', ']', '(', ')', '{', '}', '\'', '\"', ',', ';', ':'}; char operators[5] = {'+','-','*','/','='};

"struct","union","void","enum","const","typedef","auto", "static","break","case","continue","default","do","else", "for","if","return","switch","while","sizeof","printf", "FILE","fopen","NULL","fclose","exit","read","close", "fprintf"};

ifstream infile; /*输入文件*/ ofstream outfile; /*输出文件*/ char buffer1 [64]; /*缓冲数组1*/ char buffer2 [64]; /*缓冲数组2*/

char *pointer; /*扫描指针*/

/*各种函数的声明*/

bool isChar(char c);/*是否是字母*/ bool isDigit(char c);/*是否是0-9*/ bool isUnderline(char c);/*是否是下划线*/ bool isEnter(char c);/*是否是换行*/ bool isDelimiter(char c);/*是否是界符*/ bool isOperator(char c);/*是否是运算符*/ int getLength(char *s);/*求一个字符串的长度*/ bool isIdentifier(char *s);/*是否是标识符*/ bool isNumber(char *s);/*是否为数字*/ bool isKeyword(char *s);/*是否是关键字*/ char getChar();/*实现双缓冲扫描文件*/

void write(string str1,string str2);/*写入文件,并且在屏幕上打印*/

/*程序入口:main函数*/ int main() {

char cc= '\0'; string str = "";

pointer=buffer1;

buffer1 [63]=buffer2 [63]=-1; //数组尾数值为-1

infile.open ("in.txt",ios::binary);//二进制文件

outfile.open ("out.txt",ios::trunc);//再次写入覆盖文件已有内容

for (int i=0;i<=62;i++)

buffer1 [i]=infile.get ();//将文件中字符放入第一缓冲区 for (;;) { str = ""; cc = getChar(); str += cc; AAA: if (isDelimiter(cc))/*是否是界符*/

{ write("界符",str);

}

else if (isOperator(cc))/*是否是操作符*/

} write("操作符",str);

else if (isEnter(cc))/*是否是换行符*/

{ write("换行", "\\n");

}

else if (isUnderline(cc) || isChar(cc))/*是否是标识符*/ { for (;;) { cc = getChar();

if (!(isChar(cc) || isDigit(cc) || isUnderline(cc))) { write("标识符",str); str = cc; goto AAA;

}

str += cc;

}

}

else if (isDigit(cc))/*是否是数字*/ { for (;;) { cc = getChar();

if (!(isDigit(cc)) && cc != '.') {

write("数字",str); str = cc; goto AAA;

}

str += cc;

}

}

}

return 0; }

/**********************************************************************/

/*双缓冲扫描文件*/ char getChar() {

if (*pointer == -1) /*当前指针在缓冲区(不知是那个缓冲区)末尾*/

if (pointer==buffer1+63)/*在第一buffer尾,向第二buffer读入数据*/ { for (int i=0;i<=62;i++) { buffer2 [i]=infile.get ();

}

pointer=buffer2;

return getChar();

}

else if (pointer==buffer2+63)/*在第二buffer尾,向第一buffer读入数据*/ { for (int i=0;i<=62;i++) { buffer1 [i]=infile.get (); }

pointer=buffer1; return getChar();

}

else/*在不是buffer尾的位置读到了EOF,说明完成了分析*/ { infile.close (); outfile.close (); ofstream out;

cout<<"\n\n\t词法分析完毕!"<<endl; system ("pause"); exit (-1);

}

}

return *pointer++; }

/*是否是字母*/

bool isChar(char c) {

if ((c>='a' && c<='z') || (c>='A' && c<='Z') ) { return true;

} else { return false; }

}

/*是否是0-9*/

bool isDigit(char c) {

if (c>='0' && c<='9') { return true;

} else { return false; } }

/*是否是下划线*/

bool isUnderline(char c) {

if (c == '_') { return true; } else { return false; } }

/*是否是换行*/

bool isEnter(char c) {

if (c == '\n') { return true; } else { return false; } }

/*是否是界符*/

bool isDelimiter(char c) {

for (int i=0;i<10;i++) {

{ return true;

}

}

return false; }

/*是否是运算符*/

bool isOperator(char c) {

for (int i=0;i<5;i++) { if (c == operators[i]) { return true;

}

}

return false; }

/*求一个字符串的长度*/ int getLength(char *s) {

int len=0;

for (int i=0;;i++) { if (s[i] != '\0') { len++;

} else { return len; }

} }

/*是否是标识符*/

bool isIdentifier(char *s) {

int len = getLength(s);

if (isChar(s[0]) || isUnderline(s[0])) { for (int i=1;i<len;i++)

if (!(isDigit(s[i]) || isDigit(s[i]) || isUnderline(s[i]))) { return false;

}

}

return true;

}

else { return false;

} }

/*是否为数字*/

bool isNumber(char *s) {

int len = getLength(s); if (s[0]>=1 && s[0]<=9) { for (int i=0;i<len;i++) { if (!isDigit(s[i]) && s[i]!='.') { return false;

}

}

return true;

} else { return false;

} }

/*是否是关键字*/

bool isKeyword(char *s) {

for (int i=0;i<keywords->length();i++) { if (s == keywords[i]) { return true; }

}

return false; }

/*写入文件,并且在屏幕上打印*/

void write(string str1,string str2) {

cout<<str1<<" :"<<str2<<endl;

outfile<<"[ <"<<str1<<"> : \""<<str2<<"\" ]"<<endl; }

实验1.1 根据状态转换图手工构造词法分析程序.doc 将本文的Word文档下载到电脑

    精彩图片

    热门精选

    大家正在看

    × 游客快捷下载通道(下载后可以自由复制和排版)

    限时特价:7 元/份 原价:20元

    支付方式:

    开通VIP包月会员 特价:29元/月

    注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
    微信:fanwen365 QQ:370150219