实验一(词法分析)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验一词法分析
一.实验目的
1、学会针对DFA转换图实现相应的高级语言源程序。

2、深刻领会状态转换图的含义,逐步理解有限自动机。

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

二.实验内容
TINY计算机语言的编译程序的词法分析部分实现。

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

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

(2)空白符仅仅是空格、回车符、制表符。

(3)代码是自由格式。

(4)注释应放在花括号之内,并且不允许嵌套
三.实验要求
要求实现编译器的以下功能:
(1)按规则拼单词,并转换成二元式形式
(2)删除注释行
(3)删除空白符(空格、回车符、制表符)
(4)列表打印源程序,按照源程序的行打印,在每行的前面加上行号,并且打印出每行包含的记号的二元形式
(5)发现并定位错误
,词法分析进行具体的要求:
(1)记号的二元式形式中种类采用枚举方法定义;其中保留字和特殊字符是每个都一个种类,标示符自己是一类,数字是一类;单词的属性就是表示的字符串值。

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

这样配合语法分析程序的分析需要的记号及其属性,生成一个语法树。

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

源程序:
/*
注意:
测试时把测试的源程序存入当前目录中,并改名为source.txt
*/
#include<iostream>
#include<iomanip>
#include<ctype.h>
#include<fstream>
#include<string>
usingnamespacestd;
enumWordType {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
enumCharType {ALPHABET, OTHER};
enumWrongType {ZERO, ALP_NUM, NUM_ALP, UNLEAGL_S, NO_MATCH, UNKNOW};
char*Words [] = {"wrong","number","biaoshi","if","then","else","end","repeat","until",//9
"read","write","+","-","*","/","=","<",":
",//18
":
=","\n"," ","","{","}"};//24
typedefstruct {charArrayChar[100], cbuffer;
inti=-1, numline = 1, wordtype;
string LineChar;
Two T;
ifstream fp("source.txt",ios:
:in);
intmain ()
{char*str;
intwordtype;
}Two;
voidHandleAlphabet();
voidHandleNumber ();
voidHandleOther ();
if(!fp){cout << setiosflags (ios:
:left) << setw
(6) <<"行数"<<"(";
cout << setiosflags (ios:
:left) << setw
(10)<<"类别编码"<<", ";
cout << setiosflags (ios:
:left) << setw
(20) <<"字符"<<")"<< endl;
fp.get (cbuffer);
while(!fp.eof ()){}if(cbuffer =='\n')//忽略换行符{} elseif(cbuffer ==' ')//忽略空字符{}
elseif(cbuffer =='')//忽略制表符{}
elseif(isalpha(cbuffer))//判断是否是字母{} elseif(isdigit(cbuffer))//判断是否是数字{}
else//其他字符
HandleOther ();
HandleNumber ();
HandleAlphabet ();
LineChar +=" ";
fp.get(cbuffer);
LineChar +=" ";
fp.get(cbuffer);
cout <<"第"<< numline <<"行所有字符:
"<< LineChar << endl;numline++;
LineChar ="";
fp.get(cbuffer);
cout<<"文件打开错误!!"<<endl;
else
i = -1;
}}
cout <<"第"<< numline <<"行所有字符:
"<< LineChar << endl;
fp.close ();
system ("pause");
return0;
intMatch(charstr[],intchartype)//查找匹配的字符{} voidTypeWrong (intwrongtype,intline){switch(wrongtype){caseZERO:
cout <<"字母后面不能紧跟数字!";
break;
cout <<"数字后面不能紧跟字母!";
break;
cout <<"非法特殊符号!";
break;
caseALP_NUM:
inti;
switch(chartype){caseALPHABET:
}returnWRONG;
for(i = IF; i <= WRITE; i++){}
for(i = PLUS; i <= ASSIGNMENT; i++){}if(strcmp(Words[i],str) == 0) returni;
if(strcmp(Words[i],str) == 0)
returni;
caseOTHER:
caseNUM_ALP:
caseUNLEAGL_S:
}caseNO_MATCH:
}cout <<"没有与第"<< line <<"行“{”匹配的“}”!";
cout <<"其它类型错误!";
break;
default:
Two ConvertTwo (charstr[],intwordtype,intwrongtype,intnumline,intline)//进行二元转换{}voidHandleAlphabet ()//首字符为字母时的处理{ArrayChar[i+1]='\0';
boolmark =true;
while(!fp.eof() && isalpha(cbuffer)){}
if(isdigit (cbuffer)){}mark =false;
while(!fp.eof() && (isalpha(cbuffer)||isdigit(cbuffer))){}ArrayChar[++i]=cbuffer;
fp.get(cbuffer);
ArrayChar[++i]=cbuffer;
fp.get(cbuffer);
returnT;
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;
Two T;
T.wordtype = wordtype;
T.str = str;
}LineChar += ArrayChar;
if(mark){}
else
T = ConvertTwo(ArrayChar,WRONG, ALP_NUM, numline, numline); wordtype = Match(ArrayChar, ALPHABET);
T = ConvertTwo(ArrayChar,(BIAOSHI > wordtype ? BIAOSHI : wordtype), ZERO, numline,numline);
voidHandleNumber ()//首字符为数字时的处理{} voidDeleteNote ()//删除注释{intrecord = numline;
while(!fp.eof() && cbuffer !='}'){fp.get(cbuffer);
while(!fp.eof() && cbuffer !='}')
boolmark =true;
while(!fp.eof() && isdigit(cbuffer)){}
if(isalpha(cbuffer)){}
ArrayChar[i+1]='\0';
LineChar += ArrayChar;
if(mark)
T = ConvertTwo(ArrayChar, NUMBER, ZERO, numline, numline);
T = ConvertTwo(ArrayChar,WRONG, NUM_ALP, numline, numline);
else mark =false;
while(!fp.eof() && (isalpha(cbuffer)||isdigit(cbuffer))){}ArrayChar[++i]=cbuffer; fp.get(cbuffer);
ArrayChar[++i]=cbuffer;
fp.get(cbuffer);
}}{}ArrayChar[i + 1]='\0';
if(cbuffer =='}'){}
else{}T = ConvertTwo("", WRONG, NO_MATCH, numline, record); ArrayChar [++i] ='}';
ArrayChar[i + 1]='\0';
T = ConvertTwo("}",BRACKET_R, ZERO, numline, numline);
if(cbuffer =='\n'){}
ArrayChar[++i]=cbuffer;
fp.get(cbuffer);ArrayChar [i + 1] ='\0';
LineChar += ArrayChar;
cout <<"第"<< numline <<"行所有字符:
"<< LineChar << endl;LineChar ="";
numline++;
i = -1;
fp.get(cbuffer);
LineChar += ArrayChar;
fp.get(cbuffer);
voidHandleOther ()//字符为特殊字符时的处理{if(ArrayChar [i] =='{')//删除注释{}
else//其他字符{fp.get(cbuffer);
while(!fp.eof() && cbuffer !='\n'&& cbuffer !=' '&& cbuffer !=''ConvertTwo("{", BRACKET_L, ZERO, numline, numline);
DeleteNote ();
ArrayChar [++i] = cbuffer;
&& !isalpha(cbuffer) && !isdigit(cbuffer))
}}{}ArrayChar[i + 1]='\0';
wordtype = Match(ArrayChar, OTHER);
LineChar += ArrayChar;
T = ConvertTwo(ArrayChar, wordtype, (wordtype > 0 ? 0: UNLEAGL_S), numline, numline);ArrayChar [++i] = cbuffer;
fp.get(cbuffer);
实验结果:。

相关文档
最新文档