📄 yufa.cpp
字号:
#include "yufa.h"//新建了一个头文件yufa.h 我把函数的申明,以及经常要用的getsym(FILE *fim)函数,以及此程序
//要用到的变量都放到了这个头文件先读头文件。 里面都是一些简单的定义和实现以及函数申明部分
//很容易理解的。
#include <stdlib.h>
#define stacksize 500
int cx=0;
int p,b,t;
int s[stacksize];
instruction i1;
int isdefine(char *id)
{
for(int i=ptx;i>=0;i--)
{
if(strcmp(table[i].name,id)==0&&table[i].level==Lev)
return 1;
}
return 0;
}
void enter(object k,int *ptx,int lev, int *pdx)//k表示声名的单词类型,ptx指示table数组的当前值
{//k表示标识符的类型,ptx表示当前table数组的下标,lev表示当前引用层与定义层的层差
if(lev>3)
printf("过程嵌套超过了最大值");
else
{
switch(k)
{
case constant:{
table[(*ptx)].kind=constant;
(*ptx)++;
break;
}
case variable:{
table[(*ptx)].kind=variable;
table[(*ptx)].level=lev;
table[(*ptx)].adr=(*pdx);
varcount++;//...................
(*ptx)++;
(*pdx)++;
break;
}
case procedur:{
table[(*ptx)].kind=procedur;
table[(*ptx)].level=Lev;
table[(*ptx)].size=3;//..................
varcount=0;
(*pdx)=3;
(*ptx)++;
break;
}
}
}
}
//////////////////////////////////////
void gen(fct fct1,int lev,int a1)
{
code[cx].f=fct1;
code[cx].l=lev;
code[cx].a=a1;
cx++;
}
//////////////////////////////////////////
int position(char *id)
{
for(int i=ptx-1;i>=0;i--)
{
if(strcmp(table[i].name,id)==0)
{
if(table[i].level<=Lev)
return i;
}
}
return -1;
}
////////////////////////////////////////////////
void printblank(int k)//输出k个空格,这个函数没有特别的目的,只是为了便于以后的修改而写的
{
for(int i=1;i<=k;i++)
printf(" ");
}
void endfunc(char *end)
{
//调用完某个函数后给出的信息 end 为传递进来的输出信息这个函数也没有特别的目的,只是为了使程序清楚而且
//能够避免重复的代码要写多遍,这个就相当于一个小的模块。读程序时不需要读这个
printblank(k);
printf("}\n");
printblank(k);
k=k-m;
printf("%s\n",end);
}
void beginfunc(char *begin)
{
//这个函数的功能和效果都跟endfunc 差不多的,不过这个是对函数调用时给出的头信息
//begin 为要给出的头输出信息
printblank(k);
printf("%s\n",begin);
printblank(k);
printf("{\n");
}
void errorby(int errornum,FILE *fin,char *line)
{
//这个函数同上面两个函数一样都是为了是程序修改更方便,即若发现问题只需要在这个模块里面改就可以了
//这样修改起来会容易些。errornum 为了把错误出现的次数记录下来,做为错误数组(error[])的下标
//函数中还用到了strcat() 这个函数为字符串连接函数。
flag=0;
strcpy(error[errortotal],errortype[errornum]);
//注释掉下面这两行后测试 与不注释时的区别 就可以知道用这个函数的目的了。
strcat(error[errortotal]," error in (pl0.txt) on line ");
strcat(error[errortotal],line);
errortotal++;
}
void program(FILE *fin)
{
beginfunc("程序开始");
k=k+m;//每调用一次函数,k就加 m,即输出的空格数加m
block(fin);
if(sym!=dot)
{
//errorby(8,fin,lineno);
}
endfunc("程序结束");
}
void block(FILE *fin)
{
int tx0,cx0;//Lev++;
beginfunc("分程序开始");
tx0=ptx-1;
table[tx0].adr=cx;
gen(jmp,0,0);
if(sym==constsym)
{
k=k+m;
constsymh(fin);
}
if(sym==varsym)
{
k=k+m;
varsymh(fin);
}
table[tx0].size=varcount+3;//...........................
if(sym==proceduresym)
{
k=k+m;
proceduresymh(fin);
}
////////////////////////////////////////
cx0=cx;
code[table[tx0].adr].a=cx0;
code[0].a=cx0;
gen(inte,0,table[tx0].size);
//////////////////////////////////////
if(sym!=(symbol)0)
{
k=k+m;
sentence(fin);
}
gen(opr,0,0);
//Lev--;
endfunc("分程序结束");
}
void constsymh(FILE *fin)//实现 常量说明部分
{
beginfunc("常量说明部分");
if(sym==constsym)
{
sym=getsym(fin);
k=k+m;
constdefin(fin);
}
while(sym==comma)
{
sym=getsym(fin);
k=k+m;
constdefin(fin);
}
if(sym!=semicolon)
{
errorby(4,fin,lineno);//错误处理先不用管它
}
else sym=getsym(fin);//向下读单词为以后的程序执行提供识别字符
endfunc("常量说明部分结束");
}
void constdefin(FILE *fin)//实现 常量定义
{
int flag=0;
beginfunc("常量定义:");
if(sym!=ident)
{
errorby(3,fin,lineno);//错误处理
}
else
{
if((flag=isdefine(id))!=1)
strcpy(table[ptx].name,id);//..................................
else errorby(26,fin,lineno);
sym=getsym(fin);
if(sym!=eql)
{
errorby(0,fin,lineno);//错误处理
}
else
{
sym=getsym(fin);
if(sym!=number)
{
errorby(1,fin,lineno);//错误处理
}
else
{
if(flag!=1)
{
table[ptx].val=num;//.........................................
enter(constant,&ptx,Lev,&pdx);//..............................
}
sym=getsym(fin);//<常量定义>规则 识别成功向下读单词为以后判断提供新的识别字符
}
}
}
endfunc("常量定义结束");
}
void varsymh(FILE *fin)//实现 变量说明部分
{
beginfunc("变量说明部分:");//模块化,可先不看他,此函数定义在前面了。
if(sym==varsym)
{
sym=getsym(fin);
if(sym!=ident)
{
errorby(3,fin,lineno);
}
else
{
strcpy(table[ptx].name,id);//.................................
enter(variable,&ptx,Lev,&pdx);//....................................
sym=getsym(fin);
while(sym==comma)
{
sym=getsym(fin);
if(sym!=ident)
{
errorby(3,fin,lineno);
if(sym==comma) break;
}
else
{
strcpy(table[ptx].name,id);//.......................................
enter(variable,&ptx,Lev,&pdx);//..........................................
sym=getsym(fin);
}
}
if(sym!=semicolon)
{
errorby(4,fin,lineno);
}
else sym=getsym(fin);
}
}
endfunc("变量说明部分结束");//同beginfunc(" ");用法和功能
}
void proceduresymh(FILE *fin)//实现 过程说明部分
{
int count=1;
beginfunc("过程说明部分");
if(sym==proceduresym)
{
sym=getsym(fin);
if(sym!=ident)
{
errorby(3,fin,lineno);
}
else
{
strcpy(table[ptx].name,id);//新舔加
enter(procedur,&ptx,Lev,&pdx);//新舔加
sym=getsym(fin);
if(sym!=semicolon)
{
errorby(4,fin,lineno);
}
else sym=getsym(fin);
k=k+m;
Lev++;
block(fin);
Lev--;
while(sym==semicolon)
{
sym=getsym(fin);
k=k+m;
proceduresymh(fin);
count++;
}
if(count==1)
{
if(sym!=semicolon&&sym!=(symbol)0)
{
errorby(4,fin,lineno);
}
}
}
}
endfunc("过程说明部分结束");
}
void sentence(FILE *fin)//语句的实现
{
beginfunc("语句开始");
if(sym==ident)
{
k=k+m;
statement(fin);
}
else if(sym==beginsym)
{
k=k+m;
beginsymh(fin);
}
else if(sym==ifsym)
{
k=k+m;
condition(fin);
}
else if(sym==whilesym)
{
k=k+m;
whilesymh(fin);
}
else if(sym==writesym)
{
writesymh(fin);
}
else if(sym==readsym)
{
k=k+m;
readsymh(fin);
}
else if(sym==callsym)
{
k=k+m;
callsymh(fin);
}
else
{
errorby(6,fin,lineno);
endfunc("语句结束");
return;
}
}
void statement(FILE *fin)// 赋值语句的实现
{
int p;//用来记录变量在符号表中的位置
beginfunc("赋值语句:");
if(sym==ident)
{
///////////////////////////////////
p=position(id);
if(p==-1)
{
errorby(10,fin,lineno);
}
else if(table[p].kind!=variable)
errorby(11,fin,lineno);
/////////////////////////////////
sym=getsym(fin);
if(sym==becomes)
{
sym=getsym(fin);
expression(fin);
}
else
{
errorby(12,fin,lineno);
}
if(p!=-1)
gen(sto,Lev-table[p].level,table[p].adr);
}
else sym=getsym(fin);
endfunc("赋值语句结束");
}
void tiaojian(FILE *fin)
{
symbol relop;//..........................................
if(sym==oddsym)
{
sym=getsym(fin);
expression(fin);
gen(opr,0,6);
}
else
{
expression(fin);
if(sym!=eql&&sym!=lss&&sym!=leq&&sym!=gtr&&sym!=geq&&sym!=neq)
{
errorby(19,fin,lineno);
}
else
{
relop=sym;//...................................
sym=getsym(fin);
expression(fin);
///////////////////////////////////
switch(relop)
{
case eql:{gen(opr,0,8); break;}
case neq:{gen(opr,0,9); break;}
case lss:{gen(opr,0,10);break;}
case geq:{gen(opr,0,11);break;}
case gtr:{gen(opr,0,12);break;}
case leq:{gen(opr,0,13);break;}
}
///////////////////////////////
}
}
}
void expression(FILE *fin)//定义表达式函数
{
symbol addop;//................................
if(sym==plus||sym==minus)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -