?? sentence.cpp
字號:
#include "sentence.h"
#include "fstream.h"
#include "iostream.h"
#include "stdlib.h"
#include "string.h"
#include "keyword.h"
#include "stdio.h"
#include "conio.h"
/*詞法分析結果文件中的非法信息在語法分析中,在給出錯誤信息后,自動跳過,繼續進行分析*/
sentence::sentence()//構造函數初始化各個變量
{
ErrorFile.open("error.txt",ios::nocreate|ios::out);
if(ErrorFile.fail())
{
cout<<"程序初始化失敗!程序將退出!"<<endl;
exit(0);
}
ResultFile.open("result.txt",ios::nocreate|ios::in);
if(ResultFile.fail())
{
cout<<"程序初始化失敗!程序將退出!"<<endl;
ErrorFile.close();
exit(0);
}
CodeFile.open("code.txt",ios::nocreate|ios::out);
if(CodeFile.fail())
{
cout<<"程序初始化失敗,程序將退出!"<<endl;
ErrorFile.close();
ResultFile.close();
exit(0);
}
line=1;
errornum=0;
depth=0;
varnum=0;
constnum=0;
dspnum=1;
varlength=constlength=100;
dpstack[0].depth=0;
dpstack[0].varstart=0;
dpstack[0].varend=0;
dpstack[0].conststart=0;
dpstack[0].constend=0;
codenum=0;
ErrorFile<<" "<<endl;
varptr=(varnode *)malloc(sizeof(varnode)*100);
if(varptr==NULL)
{
cout<<"初始化失敗,程序將退出!"<<endl;
exit(0);
}
constptr=(constnode *)malloc(sizeof(constnode)*100);
if(constptr==NULL)
{
free(varptr);
cout<<"初始化失敗,程序將退出!"<<endl;
exit(0);
}
update_data.head=(back_info *)malloc(sizeof(back_info)*100);
if(update_data.head==NULL)
{
free(varptr);
free(constptr);
cout<<"初始化失敗,程序將退出!"<<endl;
exit(0);
}
update_data.sum=0;
update_data.length=100;
}
sentence::~sentence()//析構函數釋放變量和常量占用的存儲空間
{
// cout<<depth<<endl;getch();
ErrorFile.seekp(0L,ios::beg);
ErrorFile<<"程序有"<<errornum<<"個錯誤!";
ErrorFile.close();
ResultFile.close();
CodeFile.close();
free(varptr); //釋放變量表存儲空間
free(constptr); //釋放常量表存儲空間
if(errornum==0)
{
cout<<"\n您的程序沒有錯誤,語法分析通過!"<<endl;
cout<<"\n下面將進行信息回填,請稍等............"<<endl;
UpdateFile();
cout<<"\n本程序虛擬機指令共有 "<<codenum<<" 條,詳細信息見 code.txt"<<endl;
}
else
{
cout<<"\n您輸入的程序有"<<errornum<<"個錯誤,詳細信息見 error.txt !"<<endl;
}
free(update_data.head); //釋放回填表占用的內存
}
int sentence::Insert(int index,int number,int endnum,char * data)//向回填表中插入一個回填信息
//index表示要插入的回填信息在回填表中的位置,number表示回填信息的代碼編號
//endnum表示回填信息要跳轉到的代碼的編號,data回填的其他信息
{
if(update_data.sum>=update_data.length)
{
update_data.length=update_data.sum+50;
update_data.head=(back_info *)realloc(update_data.head,sizeof(back_info)*update_data.length);
if(update_data.head==NULL)
{
cout<<"內存不足,將退出程序!"<<endl;
free(varptr);
free(constptr);
}
}
update_data.head[index].number=number;
update_data.head[index].endnum=endnum;
strcpy(update_data.head[index].data,data);
return 1;
}
int NumberLen(int number)
//返回數字的長度
{
int i=0;
do
{
i++;
number/=10;
}while(number);
return i;
}
void sentence::UpdateFile()
{
char code[300];
int i,num,j;
if(update_data.sum==0)
{
cout<<"\n代碼回填成功!"<<endl;
return ;
}
CodeFile.open("code.txt",ios::in|ios::out|ios::nocreate);
if(CodeFile.fail())
{
cout<<"代碼回填失敗,程序分析失敗!"<<endl;
return;
}
for(i=0,j=0;i<update_data.head[update_data.sum-1].number;i++)
{
CodeFile.getline(code,299,'\n');
if(i==update_data.head[j].number-1)
{
CodeFile.seekp(-strlen(code)-1,ios::cur);
CodeFile<<"code"<<update_data.head[j].number<<update_data.head[j].data<<update_data.head[j].endnum;
CodeFile.seekp(strlen(code)-12-NumberLen(update_data.head[j].number)-NumberLen(update_data.head[j].endnum)+1,ios::cur);
j++;
}
}
CodeFile.close();
cout<<"\n信息回填成功!"<<endl;
}
int sentence::GetWord()
//從文件中讀取一個單詞及其標號,單詞的組成保存在 name,單詞的編號保存number中
{
if(!ResultFile.eof())
{
name[0]='\0';
ResultFile.getline(name,10,' ');
if(ResultFile.eof())
return 0;
ResultFile>>number;
ResultFile.get();
if(number==ENTER)
{
line++;
// cout<<endl;//////////////
return GetWord();
}
else if(number==ERROR)
{
errornum++;
ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum<<":標識符 "<<name<<" 定義非法!"<<endl;
return GetWord();
}
// cout<<" "<<name;///////////
// getch();
return 1;
}
else
return 0;
}
void sentence::BackWord()
//使讀指針回退一個單位
{
int length=0,number=this->number;
while(number)
{
number/=10;
length++;
}
length+=strlen(name)+3;
ResultFile.seekg(-length,ios::cur);
}
void sentence::Error()
//基礎錯誤處理, 向下讀單詞知道遇到關鍵字或者專用符號為止
{
int type;
errornum++;
if(number>=PROGRAM&&number<=ODD)
{
BackWord();
return;
}
while(1)
{
type=GetWord();
if(type==0||number==29||number==35)
break;
else if(number>=PROGRAM&&number<=ODD)
{
// BackWord();
break;
}
}
}
int sentence::Insert(char *name)
//插入一個變量結點
{
int index,i;
index=varnum;
if(varnum==varlength)
{
varlength+=100;
varptr=(varnode *)realloc(varptr,sizeof(varnode)*(varlength));
if(varptr==0)
{
cout<<"內存不足,程序將退出!"<<endl;
exit(1);
}
}
varnum++;
for(i=dpstack[dspnum-1].varstart;i<index;i++)
{
if(strcmp(name,varptr[i].name)==0)
{
errornum++;
ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum<<":標識符 "<<name<<" 在變量中重復定義!"<<endl;
return 0;
}
}
for(i=dpstack[dspnum-1].conststart;i<constnum;i++)
{
if(strcmp(name,constptr[i].name)==0)
{
errornum++;
ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum<<":標識符 "<<name<<" 已經在常量中定義!"<<endl;
return 0;
}
}
dpstack[dspnum-1].varend=varnum;
strcpy(varptr[index].name,name);
cout<<"Insert var "<<name<<endl;/////////////////////////
return 1;
}
int sentence::IsVar(char *name)
//判斷一個標識符是否為變量,若不是變量返回-1,否則返回單詞的層次,其他信息存儲在var_con_info中
{
int i,j;
for(i=varnum-1;i>-1;i--)
{
if(strcmp(name,varptr[i].name)==0)
break;
}
// cout<<i<<' '<<name<<' '<<varnum<<endl;getch();
if(i==-1)
return -1;
else
{
for(j=dspnum-1;j>-1;j--)
{
if(i>=dpstack[j].varstart)
break;
}
var_con_info.level=j;
var_con_info.address=i-dpstack[j].varstart;
return j;
}
}
int sentence::Insert(char *name,char *value)
//插入一個常量結點
{
int index,i;
index=constnum;
if(constnum==constlength)
{
constlength+=100;
constptr=(constnode *)realloc(constptr,sizeof(constnode)*constlength);
if(constptr==NULL)
{
cout<<"內存不足,程序將退出!"<<endl;
exit(0);
}
}
constnum++;
for(i=dpstack[dspnum-1].conststart;i<index;i++)
{
if(strcmp(name,constptr[i].name)==0)
{
errornum++;
ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum<<":標識符 "<<name<<" 在常量中重復定義!"<<endl;
return 0;
}
}
dpstack[dspnum-1].constend=constnum-1;
strcpy(constptr[index].name,name);
strcpy(constptr[index].value,value);
cout<<"Insert const "<<name<<" value:"<<value<<endl;/////////////////////////*/
return 1;
}
int sentence::IsConst(char *name)
//判斷一個標識符是否為常量,返回值同IsVar
{
int i,j;
for(i=constnum-1;i>-1;i--)
{
if(strcmp(name,constptr[i].name)==0)
break;
}
if(i==-1)
return -1;
else
{
for(j=dspnum-1;j>-1;j--)
{
if(i>=dpstack[j].conststart)
break;
}
var_con_info.level=j;
var_con_info.address=i;
return j;
}
}
int sentence::constanalyse()//常量分析
{
int type,tag=0;
char constname[10];
while(1)
{
type=GetWord();
if(type==0)
{
ConstError(4);
errornum++;
break;
}
switch(tag)
{
case 0:if(number==ID)
{
strcpy(constname,name);
tag=1;
}
else
{
ConstError(0);
Error();//error
cout<<"const finish error"<<endl;///////////////////
return 0;
}
break;
case 1:if(number==16)
tag=2;
else
{
ConstError(1);
Error();//error
cout<<"const finish error"<<endl;////////////////////////
// cout<<name<<" "<<number<<endl;
return 0;
}
break;
case 2:if(number==NUMBER)
{
Insert(constname,name);
tag=3;
}
else
{
ConstError(3);
Error();//error
cout<<"const finish error"<<endl;//////////////////
return 0;
}
break;
case 3:if(number==29)
{
cout<<"const finish"<<endl;/////////////
return 1;
}
else if(number==30)
tag=0;
else
{
ConstError(3);
Error();//error
cout<<"const finish error"<<endl;////////////////////////////
return 0;
}
}
}
cout<<"const finish"<<endl;
return 1;
}
void sentence::ConstError(int tag)
{
switch(tag)
{
case 0:
case 2:
case 3:ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum+1<<":標識符 "<<name<<" 在常量定義中非法!"<<endl;
break;
case 4:ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum+1<<":常量定義缺少符號 ; "<<endl;
break;
case 1:ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum+1<<":標識符 "<<name<<" 前缺少 = 在常量定義中!"<<endl;
break;
}
}
int sentence::varanalyse()//變量分析
{
int type,tag=0;
while(1)
{
type=GetWord();
if(type==0)
break;
else
{
switch(tag)
{
case 0:if(number==ID)
{
Insert(name);
tag=1;
}
else
{
VarError(0);
Error();
return 0;
}
break;
case 1:if(number==29)
{
cout<<"var finish"<<endl;///////////////////////////
return 1;
}
else if(number==30)
tag=0;
else
{
VarError(1);
Error();
cout<<"var finish error"<<endl;///////////////////
return 0;
}
}
}
}
return 1;
}
void sentence::VarError(int tag)//變量定義錯誤處理
{
if(tag==0)
{
ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum+1<<":標識符 "<<name<<" 在變量定義中非法!"<<endl;
}
else
{
ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum+1<<":變量定義結束符號';'未在正確位置!"<<endl;
}
}
int sentence::Proganalyse()
{
int tag=0,type;
while(1)
{
type=GetWord();
if(type==0)
{
if(tag!=4)
{
errornum++;
ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum<<":編輯的程序缺少文件尾!"<<endl;
}
return 0;
}
if(tag==4)
{
ProgError(0);
GetWord();
continue;
}
switch(number)
{
case PROGRAM:if(tag==0)
{
tag=1;
}
else
{
ProgError(0);//error
}
break;
case ID:if(tag==0)
{
ProgError(PROGRAM);//error
tag=2;
}
else if(tag==1)
{
tag=2;
}
else
{
ProgError(0);//error
}
break;
case 29:if(tag==0)
{
ProgError(PROGRAM);//error
tag=3;
}
else if(tag==1)
{
ProgError(ID);//error
tag=3;
}
else if(tag==2)
{
tag=3;
Blockanalyse();
if(number==35)
{
tag=4;
cout<<"prog finish"<<endl;
return 1;
}
}
else
{
ProgError(0);//error
}
break;
case 35:tag=4;
break;
default:ProgError(0);
}
}
cout<<"prog finish"<<endl;
return 1;
}
void sentence::ProgError(int tag)
{
errornum++;
switch(tag)
{
case PROGRAM:ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum<<":程序缺少一個程序開始標識符 program!"<<endl;
break;
case ID:ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum<<":程序未進行命名!"<<endl;
break;
case 29:ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum<<":程序名后缺少符號 ; "<<endl;
break;
default:ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum<<":標識符 "<<name<<" 在該處使用非法!"<<endl;
}
}
int sentence::Blockanalyse()//block部分分析
{
int tag=0,type=0,success;
type=GetWord();
while(1)
{
if(type==0||number==35)
return 0;
switch(number)
{
case CONST:if(tag==0)
{
tag=1;
success=constanalyse();
if(success==1)
{
type=GetWord();
/// cout<<number<<endl;
}
}
else
{
BlockError(CONST);//error
Error();
}
break;
case VAR:if(tag<2)
{
tag=2;
success=varanalyse();
if(success==1)
{
type=GetWord();
}
// cout<<"var"<<endl;/////////////
}
else
{
BlockError(VAR);
Error();//error
}
break;
case PROCEDURE:if(tag<3)
{
tag=3;
success=procanalyse();
if(success==0)
{
type=GetWord();
}
;//proanalyse
}
else
{
BlockError(PROCEDURE);//error
GetWord();
GetWord();
// Error();//error
}
break;
case BEGIN:return bodyanalyse();
default:GetWord();break;
}
}
return 1;
}
void sentence::BlockError(int tag)//block分析出錯處理
{
switch(tag)
{
case CONST:ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum+1<<":進行常量定義的位置非法!"<<endl;
break;
case VAR:ErrorFile<<"行:"<<line<<"\t錯誤"<<errornum+1<<":進行變量定義的位置非法!"<<endl;
break;
case PROCEDURE:ErrorFile<<"行:"<<line<<"\t錯誤"<<++errornum<<":過程定義的位置非法!"<<endl;
break;
}
}
int sentence::procanalyse()//新過程分析
{
int value,type,tag=0;
depth++;
dpstack[dspnum].varstart=dpstack[dspnum-1].varend;
dpstack[dspnum].conststart=dpstack[dspnum-1].constend;
dspnum++;
while(tag!=5)
{
type=GetWord();
if(type==0)
return 0;
switch(tag)
{
case 0:if(number==ID)
{
tag=1;
}
else
{
ProcError(ID);//error
}
break;
case 1:if(number==27)//符號 (
{
tag=2;
}
else
{
ProcError(27);//error
}
break;
case 2:if(number==ID)
{
tag=3;
Insert(name);//插入形參變量
}
else
{
if(number==28)
tag=4;
else if(number==29)
tag=5;
ProcError(ID+1);//error
}
break;
case 3:if(number==30)//符號 ,
{
tag=2;
}
else if(number==28)// 符號 )
{
tag=4;
}
else
{
if(number==29)
tag=5;
ProcError(29);//error
}
break;
case 4:if(number==29)//符號 ;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -