叨叨游戏网
您的当前位置:首页实验1实验报告

实验1实验报告

来源:叨叨游戏网


实验一词法分析

班级:计科12-3 学号:08123282 姓名:樊鑫 实验目的

学会针对DFA转换图实现相应的高级语言源程序。 深刻领会状态转换图的含义,逐步理解有限自动机。

掌握手工生成词法分析器的方法,了解词法分析器的内部工作原理。 实验内容

TINY计算机语言的编译程序的词法分析部分实现。

从左到右扫描每行该语言源程序的符号,拼成单词,换成统一的内部表示(token)送给语法分析程序。

为了简化程序的编写,有具体的要求如下: 数仅仅是整数。

空白符仅仅是空格、回车符、制表符。 代码是自由格式。

注释应放在花括号之内,并且不允许嵌套

实验要求

要求实现编译器的以下功能:

按规则拼单词,并转换成二元式形式 删除注释行

删除空白符 (空格、回车符、制表符)

列表打印源程序,按照源程序的行打印,在每行的前面加上行号,并且打印出每行包含的记号的二元形式 发现并定位错误

,词法分析进行具体的要求:

记号的二元式形式中种类采用枚举方法定义;其中保留字和特殊字符是每个都一个种类,标示符自己是一类,数字是一类;单词的属性就是表示的字符串值。

词法分析的具体功能实现是一个函数GetToken(),每次调用都对剩余的字符串分析得到一个单词或记号识别其种类,收集该记号的符号串属性,当识别一个单词完毕,采用返回值的形式返回符号的种类,同时采用程序变量的形式提供当前识别出记号的属性值。这样配合语法分析程序的分析需要的记号及其属性,生成一个语法树。

标示符和保留字的词法构成相同,为了更好的实现,把语言的保留字建立一个表格存储,这样可以把保留字的识别放在标示符之后,用识别出的标示符对比该表格,如果存在该表格中则是保留字,否则是一般标示符。 实验程序

#include #include #include #include #include using namespace std;

enum WordType {WRONG, NUMBER, BIAOSHI, IF, THEN, ELSE, END, REPEAT, UNTIL, //9

READ, WRITE, PLUS, SUBTRACT, MULTIPLY, DIVIDEY, EQUAL, LESSTHAN, COLON,//18 ASSIGNMENT, LINE_FEED, SPACE, TAB, BRACKET_L, BRACKET_R}; //24 enum CharType {ALPHABET, OTHER};

enum WrongType {ZERO, ALP_NUM, NUM_ALP, UNLEAGL_S, NO_MATCH, UNKNOW};

char *Words [] = {\"wrong\\"read\\":=\\ typedef struct { char *str; int wordtype; }Two;

char ArrayChar[100], cbuffer; int i=-1, numline = 1, wordtype; string LineChar; Two T;

ifstream fp(\"source.txt\int main () { void HandleAlphabet(); void HandleNumber (); void HandleOther (); if (!fp) cout<<\"文件打开错误!\"<if(cbuffer == '\\n')//忽略换行符 { cout << \"第\" << numline << \" 行所有字符:\" << LineChar << endl; numline++; LineChar = \"\"; fp.get(cbuffer); }

else if (cbuffer == ' ')//忽略空字符 { LineChar += \" \"; fp.get(cbuffer); }

else if (cbuffer == ' ')//忽略制表符 { LineChar += \" \"; fp.get(cbuffer); }

else if (isalpha(cbuffer))//判断是否是字母 { HandleAlphabet (); }

else if (isdigit(cbuffer))//判断是否是数字 { HandleNumber (); }

else //其他字符 HandleOther (); i = -1; } }

cout << \"第\" << numline << \" 行所有字符:\" << LineChar << endl; fp.close (); system (\"pause\"); return 0; }

int Match(char str[], int chartype)//查找匹配的字符 { int i; switch (chartype) { case ALPHABET: for (i = IF; i <= WRITE; i++) { if (strcmp(Words[i],str) == 0) return i; } case OTHER: for (i = PLUS; i <= ASSIGNMENT; i++) { if (strcmp(Words[i],str) == 0) return i; } } return WRONG; }

void TypeWrong (int wrongtype, int line)

{

switch (wrongtype) {

case ZERO: break; case ALP_NUM: cout << \"字母后面不能紧跟数字!\"; break; case NUM_ALP:

cout << \"数字后面不能紧跟字母!\"; case UNLEAGL_S: break;

cout << \"非法特殊符号!\"; break; case NO_MATCH: cout << \"没有与第\" << line << \"行\"\"匹配的\"\"!\"; break; default: cout << \"其它类型错误!\"; break; } }

Two ConvertTwo (char str[], int wordtype, int wrongtype, int numline, int line)//进行二元转换 { Two T; T.wordtype = wordtype; T.str = str; cout << setiosflags (ios::left) << setw (6) << numline << \"(\"; cout << setiosflags (ios::left) << setw (10) << T.wordtype << \ cout << setiosflags (ios::left) << setw (20) << T.str << \")\"; if (T.wordtype == WRONG) TypeWrong (wrongtype, line); cout << endl; return T; }

void HandleAlphabet ()//首字符为字母时的处理 { bool mark = true; while(!fp.eof() && isalpha(cbuffer)) { ArrayChar[++i]=cbuffer; fp.get(cbuffer); } if (isdigit (cbuffer))

{ mark = false; while(!fp.eof() && (isalpha(cbuffer)||isdigit(cbuffer))) { ArrayChar[++i]=cbuffer; fp.get(cbuffer); } } ArrayChar[i+1]='\\0'; LineChar += ArrayChar; if (mark) { wordtype = Match(ArrayChar, ALPHABET); T = ConvertTwo(ArrayChar,(BIAOSHI > wordtype ? BIAOSHI : numline, numline); } else T = ConvertTwo(ArrayChar,WRONG, ALP_NUM, numline, numline); }

void HandleNumber ()//首字符为数字时的处理 { bool mark = true; while (!fp.eof() && isdigit(cbuffer)) { ArrayChar[++i]=cbuffer; fp.get(cbuffer); } if (isalpha(cbuffer)) { mark = false; while(!fp.eof() && (isalpha(cbuffer)||isdigit(cbuffer))) { ArrayChar[++i]=cbuffer; fp.get(cbuffer); } } ArrayChar[i+1]='\\0'; LineChar += ArrayChar; if (mark) T = ConvertTwo(ArrayChar, NUMBER, ZERO, numline, numline); else T = ConvertTwo(ArrayChar,WRONG, NUM_ALP, numline, numline); }

void DeleteNote ()//删除注释

wordtype), ZERO, { { }

int record = numline;

while (!fp.eof() && cbuffer != '}') { fp.get(cbuffer); while (!fp.eof() && cbuffer != '}') { if (cbuffer == '\\n') ArrayChar [i + 1] = '\\0'; LineChar += ArrayChar; cout << \"第\" << numline << \" 行所有字符:\" << LineChar << endl; LineChar = \"\"; numline++; i = -1; fp.get(cbuffer); } ArrayChar[++i]=cbuffer; fp.get(cbuffer); } ArrayChar[i + 1]='\\0'; if (cbuffer == '}') { ArrayChar [++i] = '}'; ArrayChar[i + 1]='\\0'; T = ConvertTwo(\BRACKET_R, ZERO, numline, numline); } else { T = ConvertTwo(\"\ } }

LineChar += ArrayChar; fp.get(cbuffer);

void HandleOther ()//字符为特殊字符时的处理 { ArrayChar [++i] = cbuffer; if (ArrayChar [i] == '{')//删除注释 { ConvertTwo(\"{\ DeleteNote (); } else//其他字符

{ fp.get(cbuffer); while (!fp.eof() && cbuffer != '\\n' && cbuffer != ' ' && cbuffer != ' ' && !isalpha(cbuffer) && !isdigit(cbuffer)) { ArrayChar [++i] = cbuffer; fp.get(cbuffer); } ArrayChar[i + 1]='\\0'; wordtype = Match(ArrayChar, OTHER); LineChar += ArrayChar; T = ConvertTwo(ArrayChar, wordtype, (wordtype > 0 ? 0: UNLEAGL_S), numline, numline); } }

实验结果

实验体会

通过本次实验学会了针对DFA转换图实现相应的高级语言源程序,并且深刻领会了状态转换图的含义,逐步理解有限自动机,同时掌握手工生成词法分析器的方法,了解词法分析器的内部工作原理。

因篇幅问题不能全部显示,请点此查看更多更全内容