📄 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 + -