编译原理词法分析器.docx
《编译原理词法分析器.docx》由会员分享,可在线阅读,更多相关《编译原理词法分析器.docx(17页珍藏版)》请在冰豆网上搜索。
![编译原理词法分析器.docx](https://file1.bdocx.com/fileroot1/2022-11/25/d666859f-04c0-49b1-bb62-14387ef1930a/d666859f-04c0-49b1-bb62-14387ef1930a1.gif)
编译原理词法分析器
//LexAnal.cpp:
implementationoftheCLexAnalclass.
//
//////////////////////////////////////////////////////////////////////
#include"stdafx.h"
#include"LexAnal.h"
//////////////////////////////////////////////////////////////////////
//Construction/Destruction
//////////////////////////////////////////////////////////////////////
CLexAnal:
:
CLexAnal()
{
}
CLexAnal:
:
~CLexAnal()
{
result.clear();
symbol.clear();
}
boolCLexAnal:
:
OpenSrcFile(char*szFilename)
{
s=200;
e=0;
fs.open(szFilename,ios_base:
:
in);
if(true==fs.fail())
{
cout<<"Can'topensourcefile!
\n";
returnfalse;
}
buffer[2*BUFFERLEN]=0;//zeroend
for(inti=0;i<30;i++){//appendkeywordstosymbollist
SYMBOLsym;
sym.kind=i;
sym.name=keywords[i];
sym.type='';
sym.value="";
symbol.push_back(sym);
}
row=1;
col=1;
returntrue;
}
voidCLexAnal:
:
CloseSrcFile()
{
fs.close();
}
boolCLexAnal:
:
Fetch()
//向双缓冲区读入源程序代码
{
if(e==2*BUFFERLEN){
fs.read(buffer,BUFFERLEN);
if(fs.eof())buffer[fs.gcount()]=0;
elsebuffer[BUFFERLEN]=0;
}elseif(e==BUFFERLEN){
fs.read(buffer+BUFFERLEN,BUFFERLEN);
if(fs.eof())buffer[BUFFERLEN+fs.gcount()]=0;
elsebuffer[BUFFERLEN*2]=0;
}
if(fs.eof())returnfalse;
returntrue;
}
voidCLexAnal:
:
GetChar()
{
if(e==2*BUFFERLEN){
ch=buffer[0];
e=1;
}else{
ch=buffer[e];
e++;col++;
}
if((e==BUFFERLEN)||(e==2*BUFFERLEN)){//reachtheendsofbuffers
if(!
eosrc){
if(!
Fetch())eosrc=true;
}
}
}
voidCLexAnal:
:
GetBC()
{
while((ch=='')||(ch=='\t')||(ch=='\n')){
if(ch=='\n'){row++;col=1;}
GetChar();
}
}
voidCLexAnal:
:
Concat()
{
strToken[t]=ch;
t++;
strToken[t]=0;
}
boolCLexAnal:
:
IsLetter()
{
if(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))||(ch=='_'))
returntrue;
returnfalse;
}
boolCLexAnal:
:
IsDigit()
{
if((ch>='0')&&(ch<='9'))returntrue;
returnfalse;
}
voidCLexAnal:
:
Retract()
{
if(e>0)e--;
elsee=BUFFERLEN*2-1;
ch='';
col--;
}
intCLexAnal:
:
Reserve()
{
for(inti=0;i<30;i++){
if(!
strcmp(keywords[i],strToken))returni+1;
}
return0;
}
intCLexAnal:
:
InsertId()
{
SYMBOLsym;
for(inti=30;iif(symbol[i].name==strToken)break;
}
if(ielse{
sym.kind=34;
sym.name=strToken;
sym.type='?
';//itstypeneedsfurthersyntaxanalysis
sym.value="";
symbol.push_back(sym);
}
returni;
}
intCLexAnal:
:
InsertConst(chartype)
{
SYMBOLsym;
for(inti=30;iif(symbol[i].value==strToken)break;
}
if(ielse{
sym.kind=(type=='N')?
37:
38;
sym.name="const";
sym.type=type;
sym.value=strToken;
symbol.push_back(sym);
}
returni;
}
//---------------------------------------------------------------------
voidCLexAnal:
:
DoAnal()//添加代码
{
intcode;
intvalue;
boolrunning=true;
eosrc=false;
e=2*BUFFERLEN;
Fetch();
s=e=0;
t=0;
strToken[t]=0;
while(running){
GetChar();
GetBC();
if(ch==0)break;//analysisfinished
s=e-1;
if(IsLetter()){
while(IsLetter()||IsDigit()){
Concat();
GetChar();
}
Retract();
code=Reserve();
if(code==0){
value=InsertId();
OutputId(value);//输出标志符二元式
}else{
OutputKeyword(code);//输出关键字二元式
}
}elseif(IsDigit()){
while(IsDigit()){
Concat();GetChar();
}
if(IsLetter()){
cout<<"Errorat("<":
illegalidentifier"<Retract();
}else{
Retract();
value=InsertConst('N');//numbertype
OutputConstInt(value);//输出整数常量二元式
}
}elseif(ch=='+'){
OutputSD(39);//+
}elseif(ch=='-'){
OutputSD(40);//-
}elseif(ch=='*'){
OutputSD(41);//*
}elseif(ch=='/'){
GetChar();
if(ch=='*'){//跳过注释行
while(ch!
=0){
while((ch!
='*')&&(ch!
=0))GetChar();
GetChar();
if(ch=='/')break;
}
if(ch==0){
cout<<"unexpectedendoffile!
"<running=false;
}
}else{
Retract();
OutputSD(42);///
}
}elseif(ch=='='){
OutputSD(43);//=
}elseif(ch=='<'){
GetChar();
if(ch=='>'){
OutputDD(54);//<>
}elseif(ch=='='){
OutputDD(55);//<=
}else{
Retract();
OutputSD(44);//<
}
}elseif(ch=='>'){
GetChar();
if(ch=='='){
OutputDD(56);//>=
}else{
Retract();
OutputSD(45);//>
}
}elseif(ch=='('){
OutputSD(46);//(
}elseif(ch==')'){
OutputSD(47);//)
}elseif(ch=='['){
OutputSD(48);//[
}elseif(ch==']'){
OutputSD(49);//]
}elseif(ch==':
'){
GetChar();
if(ch=='='){
OutputDD(57);//:
=
}else{
Retract();
OutputSD(50);//:
}
}elseif(ch=='.'){
GetChar();
if(ch=='.'){
OutputDD(58);//..
}else{
Retract();
OutputSD(51);//.
}
}elseif(ch==';'){
OutputSD(52);//;
}elseif(ch==','){
OutputSD(53);//,
}elseif(ch=='"'){
Concat();//寻找字符串末尾
GetChar();
Concat();
while((ch!
='"')&&(ch!
=0)){
GetChar();
Concat();
}
if(ch==0){
cout<<"unexpectedendofstring!
"<running=false;
}else{
value=InsertConst('S');//stringtype
OutputConstStr(value);//输出字符串常量
}
}else{
cout<<"Errorat("<":
illegalcharactor>"<}
t=0;
strToken[t]=0;//resetstrToken
}//endswhile
}
//-------------------------------------------------------------------
voidCLexAnal:
:
OutputKeyword(intcode)
{
RESULTre;
//cout<<"<"<"<re.kind=code;
re.value=code-1;
result.push_back(re);
}
voidCLexAnal:
:
OutputId(intvalue)
{
RESULTre;
//cout<<"<"<<34<<","<"<re.kind=34;
re.value=value;
result.push_back(re);
}
voidCLexAnal:
:
OutputSD(intcode)
{RESULTre;
//cout<<"<"<"<re.kind=code;
re.value=-1;
result.push_back(re);
}
voidCLexAnal:
:
OutputDD(intcode)
{
RESULTre;
//cout<<"<"<"<re.kind=code;
re.value=-1;
result.push_back(re);
}
voidCLexAnal:
:
OutputConstInt(intvalue)
{
RESULTre;
//cout<<"<"<<37<<","<"<re.kind=37;
re.value=value;
result.push_back(re);
}
voidCLexAnal:
:
OutputConstStr(intvalue)
{
RESULTre;
//cout<<"<"<<38<<","<"<re.kind=38;
re.value=value;
result.push_back(re);
}
voidCLexAnal:
:
ShowResult()
{
intkind;
cout<<"---------二元式列表----------"<cout<<"kindvaluetoken"<for(inti=0;ikind=result[i].kind;
cout<<"<"<";
if(result[i].value>=0)cout<else{
if(kind>=39&&kind<=53){
cout<}elseif(kind>=54&&kind<=58){
cout<
}
}
cout<}
}
voidCLexAnal:
:
ShowSymbol()
{
cout<<"---------符号表----------"<cout<<"No.kindnametypevalue"<for(inti=0;icout<
<}
}
intmain(intargc,char*argv[])
{
CLexAnallex;
charfn[180];
strcpy(fn,"source.smp");
if(argc>1)strcpy(fn,argv[1]);
if(lex.OpenSrcFile(fn)){
lex.DoAnal();
lex.ShowResult();
lex.ShowSymbol();
lex.CloseSrcFile();
}
return0;
}
编译原理第一次上机实验要求:
一.上机题目:
1.实验题目:
一种简单语言的词法分析程序的设计与实现
2.简单语言SIMPLE的定义:
l字符集
<字符集>—><字母>|<数字>|<单界符>
<字母>—>A|B|…|Z|a|b|…|z
<数字>—>0|1|2|3|4|5|6|7|8|9
<单界符>—>+|-|*|/|=|<|>|(|)|[|]|:
|.|;|,|“
(注:
程序以.结束,“无种别码。
)
2单词集
<单词集>—><保留字>|<双界符>|<标识符>|<常数>|<单界符>
<保留字>—>and|array|begin|call|case|char|constant|do|else|end|for|if|input|integer|not|of|or|output|procedure|program|read|real|repeat|set|then|to|until|var|while|write
<双界符>—><>|<=|>=|:
=|..|/*|*/|
<常数>—><整数>|<字符常数>
<整数>—><数字>|<整数><数字>
<字符常数>—>用双引号引起来的任意字符串
3.要求
词法分析程序作一遍扫描,采用双缓冲区结构,缓冲区大小为2*64,保留字采用一字一类,其种别码依字典顺序取1至30,标识符的种别码为34,其自身值为该常数在符号表中的行号(位置),字符串常数的种别码为38,其自身值为该常数在符号表中的行号(位置),单界限符采用一符一类,种别码依次为39至53,双界限符采用一符一类,种别码依次取54至58。
输入:
源程序文件
输出:
二元式文件
符号表文件
出错信息文件
附:
(1)源程序:
programtest;/*thisisatestedsimpleprogram
constantp=8;T=256;/*defineconstantp&T*/
vara,b,c,i:
integer;abc,ab:
char;#a:
boolean;
kjh,def:
array[2..10,6..21]ofinteger;
beginabc:
="Iamastudent";
forI:
=2to10dokjh[i]:
=i*2+t/i;
fora:
=6to21do
ifkjh[a/3]>10athendef[a]:
=6elsedef[a]:
=a+6;
b:
=2;while
b<21dobeginc:
=c+def[b;b:
=b+1;
ab:
=abc+"Iamastudent"+"123end;
end
(2)二元式文件
(20,-)(34,1)(52,-)(7,-)(34,2)
(43,-)(36,3)(52,-)(34,4)(43,-)
(36,5)(52,-)(28,-)(34,6)(53,-)
(34,7)(53,-)(34,8)(53,-)(34,9)
(50,-)(14,-)(52,-)(34,10)(53,-)
(34,11)(50,-)(6,-)(52,-)(34,6)
(50,-)(34,12)(52,-)(34,13)(53,-)
(34,14)(50,-)(2,-)(48,-)(36,15)
(58,-)(36,16)(53,-)(36,17)(58,-)
(36,18)(49,-)(16,-)(14,-)(52,-)
(3,-)(34,10)(57,-)(38,19)(52,-)
(11,-)(34,20)(57,-)(36,15)(26,-)
(36,16)(8,-)(34,13)(48,-)(34,9)
(49,-)(57,-)(34,9)(41,-)(36,15)
(39,-)(34,21)
|
|