📄 1.cpp
字号:
/*
PLX语义分析程序
2007.11.24
*/
//头文件
#include <stdio.h>
#include <string.h>
//全局变量
//输入格式
struct in
{
int type1;//关键字1 数字2 标识符3 运算符4
int type2;//小类
char name[12];//数字以外的(字符串形式)
int value;//数字的值
int lineno;//行号
//int column;
};
struct symbol//符号表
{
char name[12];
int position;
int type;//aident 1 bident 2
}sym[64];
struct output
{
int type;
int opnum;
int line;
};
output out[100];
int symcount=0;
int outno=0;
in input1;//保存当前分析的token
FILE *fp1,//源程序
*fp2;//生成程序
//函数申明
void getsym();//从文件中读一个token
bool match(char type1,int type2,in token);//匹配token
bool prog();//识别prog
bool ds();//完成
bool ss();
bool d();
bool s();
bool ae();
bool be();
bool at();
bool af();
bool bt();
bool bf();
bool re();
bool insert(in token,int type);
int check(in token);
void gen(int com,int opnum);
int findpos(in token);
//主函数
int main()
{
if((fp1=fopen("词法分析结果.txt","r"))==NULL)
{
printf("不能打开源文件\n");
return 0;
}//if
if((fp2=fopen("target code.txt","w"))==NULL)
{
printf("不能打开源文件\n");
return 0;
}//if
getsym();
if(!prog())printf("this is not prog\n");
printf("no error \n");
for(int i=0;i<outno;i++)
{
printf("%d %d %d \n",out[i].type,out[i].opnum,out[i].line);
fprintf(fp2,"%d %d %d ",out[i].type,out[i].opnum,out[i].line);
}
return 0;
}
void getsym()
{
fread(&input1,sizeof(input1),1,fp1);
fgetc(fp1);
}
bool match(char type1,int type2,in token)
{
if(type1==token.type1&&type2==token.type2)return true;
//printf("此处未匹配 行%d \n",token.lineno);
return false;
}
bool prog()// prog = "program" ds "begin" ss "end" ".". //done
{
if(!match(1,11,input1))//program
{
printf("程序应该以program关键字开始 行%d",input1.lineno);
return false;
}
ds();
//插入语句生成部分
gen(5,symcount);
printf("\n");
//
if(!match(1,1,input1))//begin
{
printf("程序应该以begin关键字开始程序段 行%d \n",input1.lineno);
return false;
}
getsym();
ss();
if(!match(1,4,input1))//end
{
printf("程序应该以end关键字结束程序段 行%d \n",input1.lineno);
return false;
}
getsym();
if(!match(5,10,input1))//"."
{
printf("程序应该以.结束 行%d \n",input1.lineno);
return false;
}
gen(10,0);
return true;
}
bool ds()// ds = d {";" d }. //done
{
getsym();
d();
while( match(5,11,input1) )//;
{
getsym();
d();
}
return true;
}
bool d()// d = "integer" aident {"," aident} | "logical" bident {"," bident} //done
{
if(match(1,7,input1))// "integer" aident {"," aident}
{
getsym();
match(3,1,input1);//aident
//插入符号表
insert(input1,1);
getsym();
while(match(5,7,input1))// ","
{
getsym();
match(3,1,input1);//aident
//插入符号表
insert(input1,1);
getsym();
}
}
else //if(match(1,8,input1))// "logical" bident {"," bident}
{
getsym();
match(3,1,input1);//bident
//插入符号表
insert(input1,2);
getsym();
while(match(5,7,input1))// ","
{
getsym();
match(3,1,input1);//bident
//插入符号表
insert(input1,2);
getsym();
}
}
return true;
}
bool ss()//done
{
/*
if(match(3,1,input1)||//aident bident
match(1,6,input1)||//if
match(1,16,input1)||//while write
match(1,12,input1)||//repeat
match(1,17,input1)//write
)*/
s();
while( match(5,11,input1) )//;
{
getsym();
s();
}
return true;
}
bool insert(in token,int type)//done
{
if(symcount<63)
{
sym[symcount].type=type;
strcpy(sym[symcount++].name,token.name);
return true;
}
else return false;//符号表满
}
int check(in token)//done
{
for(int i=0;i<symcount;i++)
{
if(strcmp(token.name,sym[i].name)==0)return sym[i].type;
}
return -1;
}
int findpos(in token)//done
{
for(int i=0;i<symcount;i++)
{
if(strcmp(token.name,sym[i].name)==0)return i;
}
return -1;
}
bool ae()// ae= ["-"] at {("-"|"+") at }. //done
{
int optype=-1;
if(match(5,5,input1))
{
getsym();//["-"]
optype=1;
}
at();
if(1==optype)
gen(8,optype);
while(match(5,5,input1)||match(5,4,input1))//{("-"|"+") at }
{
if(match(5,5,input1))optype=3;
else optype=2;
getsym();
at();
gen(8,optype);
}
return true;
}
bool at()// at = af {("*"|"/") af}. //done
{
int optype=-1;
af();
while(match(5,0,input1)||match(5,1,input1))//("*"|"/") ???
{
if(match(5,0,input1))optype=4;
else optype=5;
getsym();
af();
gen(8,optype);
}
return true;
}
bool be()// bt {"or" bt} //done yuyi yet
{
bt();
while(match(1,10,input1))//"or"
{
getsym();
bt();
}
return true;
}
bool af()// af = aident | number | "(" ae ")" . //done
{
int pos=-1;
if(match(3,1,input1))
{//判断是aident
if(check(input1)!=1)
{
printf("变量类型错误 行%d \n",input1.lineno);
return false;
}
pos=findpos(input1);
gen(2,pos);
getsym();
return true;
}
else if(match(2,1,input1)) //number
{
gen(1,input1.value);
getsym();
return true;
}
else if(match(5,2,input1)) // "(" ae ")"
{
getsym();
ae();
match(5,3,input1);
getsym();
return true;
}
return true;
}
bool bt()// bt = bf {"and" bf } . //done yuyi yet
{
bf();
while(match(1,0,input1))//and
{
getsym();
bf();
}
return true;
}
bool bf()//bf = bident | "true" | "false" |"not" bf |"(" be ")" | re . //done
{
int pos=-1;
if( match(3,1,input1) && (check(input1)==2) )//bident
{
pos=findpos(input1);
gen(2,pos);
getsym();
return true;
}
if(match(1,14,input1)||match(1,5,input1))//true false
{
if(match(1,14,input1)) gen(1,1);
else gen(1,0);
getsym();
return true;
}
if(match(1,9,input1))//not yuyi yet
{
getsym();
bf();
return true;
}
if(match(5,2,input1))//"(" be ")"
{
getsym();
be();
match(5,3,input1);// ")"
}
else
{
re();
return true;
}
return false;
}
bool re()// re = (aident | number )( "=" | ">=" | "<" | "<=" | "/=" ) ae . //yet
{
if(match(3,1,input1))//aident
{//判断aident
int pos=-1;
int optype=-1;
if(check(input1)!=1)
{
printf("变量的类型不正确 行%d",input1.lineno);
return false;
}
pos=findpos(input1);
gen(2,pos);
getsym();
//( "=" | ">=" | "<=" | "/="| "<" )
if(match(5,6,input1)||match(4,1,input1)||match(4,0,input1)||match(4,2,input1)||match(5,8,input1))
{
if( match(5,6,input1) )optype=8;
if( match(4,1,input1) )optype=11;
if( match(4,0,input1) )optype=13;
if( match(4,2,input1) )optype=9;
if( match(5,8,input1) )optype=10;
getsym();
ae();
gen(8,optype);
return true;
}
else printf("赋值的表达式不正确 行%d \n",input1.lineno);
}
if(match(2,1,input1)) //number yuyi yet
{
getsym();
//( "=" | ">=" | "<" | "<=" | "/=" )
if(match(5,6,input1)||match(4,1,input1)||match(4,0,input1)||match(4,2,input1))
{
getsym();
ae();
return true;
}
else printf("赋值的表达式不正确 行%d \n",input1.lineno);
}
return false;
}
bool s()//yet
/*
aident " := " ae |
bident " := " be |
"if" be "then" ss ["else" ss] "end" |
"while" be "do" ss "end" |
"repeat" ss "until" be |
"write" ae .
*/
{
int type=0;
if(match(3,1,input1))//aident " := " ae | bident " := " be
{
//参考符号表
int pos=-1;
pos=findpos(input1);
type=check(input1);
getsym();
match(4,3,input1);// ":="
getsym();
if(type==1) ae();
else if(type==2) be();
else printf("变量的类型不正确 行%d\n",input1.lineno);
gen(3,pos);
printf("\n");
return true;
}
if( match(1,6,input1) )//"if" be "then" ss ["else" ss] "end"
{
int ifend=-1;
int elsebegin=-1;
int waitline1=-1;//else begin
int waitline2=-1;//if end
getsym();
be();
printf("\n");
waitline1=outno;
gen(7,-1);//else begin
match(1,13,input1);//then
getsym();
ss();
waitline2=outno;
gen(6,-1);//if end
printf("\n");
elsebegin=outno;
out[waitline1].opnum=elsebegin;
if(match(1,3,input1))//else
{
getsym();
ss();
}
printf("\n");
ifend=outno;
out[waitline2].opnum=ifend;
match(1,4,input1);//end
getsym();
return true;
}
if( match(1,16,input1) )//"while" be "do" ss "end"
{
int whilebegin=outno;
int waitline=-1;
getsym();
be();
printf("\n");
waitline=outno;//等待回填
gen(7,-1);
match(1,2,input1);//do
getsym();
ss();
printf("\n");
gen(6,whilebegin);
//huitian
out[waitline].opnum=outno;
//huitian
match(1,4,input1);//end
getsym();
return true;
}
if( match(1,12,input1) )//"repeat" ss "until" be
{
getsym();
ss();
printf("\n");
match(1,15,input1);//until
getsym();
be();
return true;
}
if( match(1,17,input1) )//write" ae
{
getsym();
ae();
gen(9,0);
}
return true;
}
void gen(int com,int opnum)
{
//printf("%d %d %d \n",com,opnum,outno++);
out[outno].line=outno;
out[outno].opnum=opnum;
out[outno].type=com;
outno++;
//printf("%d %d \n",com,opnum);
}
/*
fread(p,sizeof(*p),1,fp1);写成fread(p,sizeof(p),1,fp1);其中in *p,导致读入的信息不正确
*/
/*
//关键字表
char keywords[KEYNUM][KEYNUM]={
"and",
"begin",
"do",
"else",
"end",
"false",
"if",
"integer",
"logical",
"not",
"or",
"program",
"repeat",
"then",
"true",
"until",
"while",
"write",
};
//符号表(单个)
char symbol1[SYMBOLNUM]={'*' , '/' , '(' , ')' ,
'+' , '-' , '=' , ',' ,
'<' , '>' , '.' , ';' ,
};
//符号表(组合)
char symbol2[10][3]={ "<=" , ">=" , "/=" ,":=" };
*/
/*
对于多次重复的未想出处理方法 11.14
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -