📄 1.cpp
字号:
/*
PLX语法分析程序
2007.11.14
*/
//头文件
#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];
int symcount=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 type);
//主函数
int main()
{
if((fp1=fopen("词法分析结果.txt","r"))==NULL)
{
printf("不能打开源文件\n");
return 0;
}//if
getsym();
// printf("%d %d %s %d %d",input1.type1,input1.type2,input1.name,input1.value,input1.lineno);
// printf("\n");
if(!prog())printf("this is not prog\n");
printf("no error \n");
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();
//插入语句生成部分
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;
}
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;
}
bool ae()// ae= ["-"] at {("-"|"+") at }. //done
{
if(match(5,5,input1)) getsym();//["-"]
at();
while(match(5,5,input1)||match(5,4,input1))//{("-"|"+") at }
{
getsym();
at();
}
return true;
}
bool at()// at = af {("*"|"/") af}. //done
{
af();
while(match(5,0,input1)||match(5,1,input1))//("*"|"/") ???
{
getsym();
af();
}
return true;
}
bool be()// bt {"or" bt} //done
{
bt();
while(match(1,10,input1))//"or"
{
getsym();
bt();
}
return true;
}
bool af()// af = aident | number | "(" ae ")" . //done
{
if(match(3,1,input1))
{//判断是aident
if(check(input1)!=1)
{
printf("变量类型错误 行%d \n",input1.lineno);
return false;
}
getsym();
return true;
}
else if(match(2,1,input1)) //number
{
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
{
bf();
while(match(1,0,input1))//and
{
getsym();
bf();
}
return true;
}
bool bf()//bf = bident | "true" | "false" |"not" bf |"(" be ")" | re . //done
{
if( match(3,1,input1) && (check(input1)==2) )//bident
{
getsym();
return true;
}
if(match(1,14,input1)||match(1,5,input1))//true false
{
getsym();
return true;
}
if(match(1,9,input1))//not
{
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
if(check(input1)!=1)
{
printf("变量的类型不正确 行%d",input1.lineno);
return false;
}
getsym();
//( "=" | ">=" | "<" | "<=" | "/=" )
if(match(5,6,input1)||match(4,1,input1)||match(4,0,input1)||match(4,2,input1)||match(5,8,input1))
{
getsym();
ae();
return true;
}
else printf("赋值的表达式不正确 行%d \n",input1.lineno);
}
if(match(2,1,input1)) //number
{
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
{
//参考符号表
type=check(input1);
getsym();
match(4,3,input1);// ":="
getsym();
if(type==1) ae();
else if(type==2) be();
else printf("变量的类型不正确 行%d\n",input1.lineno);
return true;
}
if( match(1,6,input1) )//"if" be "then" ss ["else" ss] "end"
{
getsym();
be();
match(1,13,input1);//then
getsym();
ss();
if(match(1,3,input1))//else
{
getsym();
ss();
}
match(1,4,input1);//end
getsym();
return true;
}
if( match(1,16,input1) )//"while" be "do" ss "end"
{
getsym();
be();
match(1,2,input1);//do
getsym();
ss();
match(1,4,input1);//end
getsym();
return true;
}
if( match(1,12,input1) )//"repeat" ss "until" be
{
getsym();
ss();
match(1,15,input1);//until
getsym();
be();
return true;
}
if( match(1,17,input1) )//write" ae
{
getsym();
ae();
}
return true;
}
void gen(int com,int type)
{
}
/*
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 + -