1、附件1 小组成员:
程序清单
Main.c
#include
2、pdx); int factor(int*ptx,int lev); int term(int *ptx,int lev); int expression(int *ptx,int lev); int statement(int *ptx,int lev); int block(); enum object{constant,variable,procedure}; struct tab{char name[14]; enum object kind; int val; int level;
3、 int adr; int size; }table[100]; enum symbol{ nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon, period,becomes,beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym,constsym,varsym, procsym,progsym,};
4、enum symbol sym=nul; enum symbol mulop; enum symbol wsym[14]; enum symbol ssym[256]; char ch=' '; char *str; char word[14][10]={"begin","call","const","do","end","if","odd","procedure","program","read","then","var","while","write"};//设置保留字名字 int num; int lev=0; int tx=0; int k; int *mm;
5、//=(int *)malloc(sizeof(int)); char *id,sign[14]; char a[14]; FILE *fp1,*fp2,*fp3; void error(int n){ switch(n){ case 1:printf("常数说明中的\"=\"写成了\":=\"。\n"); break; case 2:printf("常数说明中\"=\"后应是数字。\n"); break; case 3:printf("常数说明中的标识符后应是\"=\"。\n"); break; cas
6、e 4:printf("program,const,var,procedure后应为标识符。\n"); break; case 5:printf("漏掉了\",\"或\";\"。\n"); break; case 6:printf("过程说明的符号不正确。\n"); break; case 7:printf("应该是语句的开始符。\n"); break; case 8:printf("程序体内语句部分的后跟符不正确。\n"); break; case 9:print
7、f("程序的结尾丢了句号\".\"。\n"); break; case 10:printf("语句之间漏了\";\"。\n"); break; case 11:printf("标识符未说明。\n"); break; case 12:printf("赋值语句中,赋值号左部标识符属性应是变量。\n"); break; case 13:printf("赋值语句左部标识符后应是赋值号\":=\"。\n"); break; case 14:printf("cal
8、l后应为标识符。\n"); break; case 15:printf("call后标识符属性应为过程。\n"); break; case 16:printf("条件语句中丢了\"then\"。\n"); break; case 17:printf("丢了\"end\"或\";\"。\n"); break; case 18:printf("while型循环语句中丢了\"do\"。\n"); break; case 19:printf("语句后的符号不正确。\n"); break;
9、 case 20:printf("应为关系运算符。\n"); break; case 21:printf("表达式内标识符属性不能是过程。\n"); break; case 22:printf("表达式中漏掉右括号\")\"。\n"); break; case 23:printf("因子后的非法符号。\n"); break; case 24:printf("表达式的开始符不能是此符号。\n"); break; case 25:printf("不能识别的符号。\n");
10、 break; case 26:printf("程序的层次越界。\n"); break; case 27:printf("程序应该以program保留字开始。\n"); break; case 28:printf("程序没有程序主体。\n"); break; case 31:printf("数越界。\n"); break; case 32:printf("read语句括号中的标识符不是变量。\n"); break; case 33:printf("read/write单词
11、后应为左括号。\n"); break; case 34:printf("read/write语句括号中的标识符应是申明过的变量。\n"); break; case 35:printf("read/write语句没有右括号。\n"); } } void getsym(){ int i,n=1,l=0; int j,m; do{ while(ch==' '||ch==10||ch==9){ if(ch==10) n++; ch=fgetc(fp1)
12、 } if(ch>='a'&&ch<='z'){ //名字或保留字以字母开头 k=0; do{ if(k<10){ a[k]=ch; k+=1; } ch=fgetc(fp1); }while(ch>='a'&&ch<='z'||ch>='0'&&ch<='9');//读取一串字符 a[k]='\0'; //字符串最后置结束符 id=a; //单词自身值赋给id for(i=0;i<14;i++){
13、 for(j=0;j 14、 }
}
if(i>13)
sym=ident; //将字符串类别值赋给sym
}
else if(ch>='0'&&ch<='9') { //检测是否为数字:以0..9开头
k=0;
num=0;
sym=number;
do{
a[k]=ch;
num=10*num+(ch-'0');
k+=1;
ch=fgetc(fp1);
}while(ch>='0'&&ch<='9');//读取数字,并转换为数
15、
k--;
id=a;
if(k>14){
num=0;
error(31); //数字位数超过14位出错
printf("第%d行出错\n",n);
k=0;
*(id+k)='0';
a[k]='0';
}
}
else if(ch==':') { //检测赋值符号
k=0;
ch=fgetc(fp1);
*(id+k)=':';
a[k]=':';
if(ch==' 16、'){
sym=becomes;
k=k+1;
*(id+k)='=';
a[k]='=';
ch=fgetc(fp1);
}
else{
error(25);
sym=nul; //不能识别的符号
printf("第%d行出错\n",n);
}
}
else if (ch=='<'){ //检测小于或小于等于符号
k=0;
ch=fgetc(fp1);
17、id+k)='<';
a[k]='<';
if(ch=='='){
sym=leq;
k+=1;
*(id+k)='=';
a[k]='=';
ch=fgetc(fp1);
}
else
sym=lss;
}
else if(ch=='>'){ //检测大于或大于等于符号
k=0;
ch=fgetc(fp1);
*(id+k)='>';
a[k]='>';
if(ch=='='){
sy 18、m=geq;
k+=1;
*(id+k)='=';
a[k]='=';
ch=fgetc(fp1);
}
else
sym=gtr;
}
else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch==','||ch=='.'||ch=='#'||ch==';'||ch=='=') {//单字符符号处理
sym=ssym[ch];
k=0;
a[k]=ch; 19、
id=a;
ch=fgetc(fp1);
}
else{ //当符号不能满足上述条件时,全部按不能识别的符号处理
sym=nul;
k=0;
a[k]=ch;
id=a;
error(25);
printf("第%d行出错\n",n);
ch=fgetc(fp1);
}
switch(sym){
case nul:str="nul";break;
case ident:str="ident";br 20、eak;
case number:str="number";break;
case plus:str="plus";break;
case minus:str="minus";break;
case times:str="times";break;
case slash:str="slash";break;
case oddsym:str="oddsym";break;
case eql:str="eql";break;
case neq:str="neq";break;
case lss:str="ls 21、s";break;
case leq:str="leq";break;
case gtr:str="gtr";break;
case geq:str="geq";break;
case lparen:str="lparen";break;
case rparen:str="rparen";break;
case comma:str="comma";break;
case semicolon:str="semicolon";break;
case period:str="period";break;
cas 22、e becomes:str="becomes";break;
case beginsym:str="beginsym";break;
case endsym:str="endsym";break;
case ifsym:str="ifsym";break;
case thensym:str="thensym";break;
case whilesym:str="whilesym";break;
case writesym:str="writesym";break;
case readsym:str="rea 23、dsym";break;
case dosym:str="dosym";break;
case callsym:str="callsym";break;
case constsym:str="constsym";break;
case varsym:str="varsym";break;
case procsym:str="procsym";break;
case progsym:str="progsym";break;
}
printf("(");
for(m=0;m<=k;m++)
pri 24、ntf("%c",*(id+m));
*(id+k+1)='\0';
printf("\t");
printf("%s)",str);
printf("\n");
fprintf(fp2,"(%s %s)",id,str);
fprintf(fp2,"\n");
l++;
}while(sym==nul && l<10);
}
void enter(enum object k,int *ptx,int lev,int *pdx)
{
//mm=(int *)malloc(si 25、zeof(int));
int mmm;
(*ptx)++;
*table[(*ptx)].name=*sign;
table[(*ptx)].kind=k;
switch(k){
case constant:
table[(*ptx)].val=num;
break;
case variable:
table[(*ptx)].level=lev;
table[(*ptx)].adr=(*pdx);
(*pdx)++;
break;
26、 case procedure:
table[(*ptx)].level=lev;
break;
}
mmm=*ptx;
//printf("11111111 %d 2222222\n",mmm);
*mm=mmm;
}
int position(char *idt,int tx){
int i,j,m;
for(j=0;j 27、le[i].name[m]!=*(idt+m))
break;
else
continue;
}
if(m==k+1 && table[i].name[m]=='\0'){
return i;
break;
}
else
continue;
}
if(i==0)
return 0;
}
/*常量声明处理*/
int constdeclaration(int *ptx,int lev,int *pdx){
if(sym==ident){
*sign=*a;
ge 28、tsym();
if(sym==eql||sym==becomes){
if(sym==becomes)
error(1);
getsym();
if(sym==number)
{
enter(constant,ptx,lev,pdx);
}
else
error(2);
}
else
error(3);
}
else
error(4);
getsym();
return 0;
}
/*变量声明处理*/
int vardeclaration(int *ptx 29、int lev,int *pdx){
if(sym==ident){
*sign=*a;
enter(variable,ptx,lev,pdx);
getsym();
}
else
error(4);
return 0;
}
//因子处理
int factor(int *ptx,int lev){ //******************************************************************factor*************
int i;
while(sym==ide 30、nt||sym==number||sym==lparen) /*循环直到不是因子开始符号*/
{
if(sym==ident) /*因子为常量或变量*/
{
i=position(id,*ptx); /*查找名字*/
if(i==0)
error(11); /*标示符未声明*/
getsym();
}
else if(sym==number) /*因子为数*/
{
if(num>2047) /*数字越界*/
31、 {
error(31);
num=0;
}
getsym();
}
else /*因子为表达式*/
{
getsym();
expression(ptx,lev);
if(sym==rparen)
getsym();
else
32、 error(22); /*缺少右括号*/
}
}
return 0;
} //***********************************************************factor*********************
//项处理
int term(int *ptx,int lev) //**************************************************************term* 33、
{
//enum symbol mulop; /*用于保存乘除法符号,定义为全局变量*/
factor(ptx,lev); /*处理因子*/
while(sym==times||sym==slash)
{
getsym();
factor(ptx,lev);
}
return 0;
} //*************************************** 34、term*********************
/*表达式处理*/
int expression(int *ptx,int lev)//***********************************************************expression*********************
{
enum symbol addop; /*用于保存正负号*/
if(sym==plus||sym==minus) /*开头的正负号,此时当前表达式被看做一个正或负的项*/
{ 35、
addop=sym; //保存开头的正负号
getsym();
term(ptx,lev);
}
else
term(ptx,lev); //处理项
while(sym==plus||sym==minus)
{
getsym();
term(ptx,lev);//处理项
}
return 0;
} //****************************************************************expre 36、ssion****************
//条件语句处理
int condition(int *ptx,int lev){
enum symbol relop;
if(sym==oddsym){
getsym();
expression(ptx,lev);
}
else{
expression(ptx,lev);
if(sym!=eql && sym!=neq && sym!=lss &&sym!=leq && sym!=gtr &&sym!=geq)
error(20);
else 37、{
relop=sym;
getsym();
expression(ptx,lev);
}
}
return 0;
}
//语句处理
int statement(int *ptx,int lev){
int i;
if(sym==ident){
i=position(id,*ptx);
if(i==0)
error(11);
else{
if(table[i].kind!=variable){
error(12);
i=0; 38、
}
else{
getsym();
if(sym==becomes)
getsym();
else
error(13);
expression(ptx,lev);
printf("赋值语句\n");
fprintf(fp2,"赋值语句\n");
}
}
}
else if(sym==readsym){
getsym();
if(sym!=lparen)
error(33) 39、
else{
do{
getsym();
if(sym==ident)
i=position(id,*ptx);
else
i=0;
if(i==0)
error(34);
getsym();
}while(sym==comma);
}
if(sym!=rparen)
error(35);
else
getsym();
40、 printf("Read语句\n");
fprintf(fp2,"Read语句\n");
}
else if(sym==writesym){
getsym();
if(sym==lparen){
do{
getsym();
expression(ptx,lev);
}while(sym==comma);
printf("write语句\n");
fprintf(fp2,"write语句\n");
if(sym!=rparen)
41、 error(35);
else
getsym();
}
}
else if(sym==callsym){
getsym();
if(sym!=ident)
error(14);
else{
i=position(id,*ptx);
if(i==0)
error(11);
else{
if(table[i].kind!=procedure)
error(15);
}
getsym();
42、
}
printf("call语句\n");
fprintf(fp2,"call语句\n");
}
else if(sym==ifsym){
getsym();
condition(ptx,lev);
if(sym==thensym)
getsym();
else
error(16);
statement(ptx,lev);
printf("if语句\n");
fprintf(fp2,"if语句\n");
}
43、 else if(sym==beginsym){
getsym();
statement(ptx,lev);
do{
if(sym==semicolon)
getsym();
else
error(10);
statement(ptx,lev);
}while(sym==semicolon);
printf("Begin..end语句\n");
fprintf(fp2,"Begin..en 44、d语句\n");
if(sym==endsym){
getsym();
if(sym==procsym)
block();
}
else
error(17);
}
else if(sym==whilesym){
getsym();
condition(ptx,lev);
if(sym==dosym)
getsym();
45、else
error(18);
statement(ptx,lev);
printf("while语句\n");
fprintf(fp2,"while循环\n");
}
return 0;
}
int block(){
int dx=3,tx0;
tx0=tx;
if(lev>3)
error(26);
do{
if(sym==constsym){
getsym();
if(sym==ident){
46、constdeclaration(&tx,lev,&dx);
while(sym==comma){
getsym();
if(sym==ident)
constdeclaration(&tx,lev,&dx);
else
error(4);
}
if(sym==semicolon)
getsym();
else
error(5);
}
47、 else
error(4);
}
if(sym==varsym){
getsym();
if(sym==ident){
vardeclaration(&tx,lev,&dx);
while(sym==comma){
getsym();
if(sym==ident)
vardeclaration(&tx,lev,&dx);
else
48、 error(4);
}
if(sym==semicolon)
getsym();
else
error(5);
}
else
error(4);
}
if(sym==procsym){
lev++;
do{
getsym();
*sign=*a;
if(sym==ident){
enter(procedure,&tx,lev, 49、dx);
getsym();
}
else
error(4);
if(sym==semicolon)
getsym();
else
error(5);
if(-1==block())
return -1;
if(sym==semicolon)
getsym();
else
error(5);
}while(sym==procsym);
50、
}
}while(sym!=beginsym);
statement(&tx,lev);
table[tx0].size=dx;
return 0;
}
void main(){
//freopen("in.txt","r",stdin);
int i,j,n;
char nn[14];
char file1name[10],file2name[10],file3name[10];
mm=(int *)malloc(sizeof(int));
printf("输入源程序的文件名:\t");
scanf("