资源描述
附件1 小组成员:
程序清单
Main.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void error(int n);
void getsym();
//void enter(enum object k,int *ptx,int lev,int *pdx);
int position(char*idt,int tx);
int constdeclaration(int *ptx,int lev,int *pdx);
int vardeclaration(int *ptx,int lev,int *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;
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,};
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;
//=(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;
case 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:printf("程序的结尾丢了句号\".\"。\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("call后应为标识符。\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;
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");
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单词后应为左括号。\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);
}
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++){
for(j=0;j<k;j++){
if(a[j]==word[i][j]) //搜索当前字符是否为保留字
continue;
else
break;
}
if(j==k&&word[i][j]=='\0'){
sym=wsym[i];
break;
}
if(j==k&&word[i][j]!='\0'){
sym=ident;
break;
}
}
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');//读取数字,并转换为数
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=='='){
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);
*(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=='='){
sym=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;
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";break;
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="lss";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;
case 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="readsym";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++)
printf("%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(sizeof(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;
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<k+1;j++)
table[0].name[j]=*(idt+j);
for(i=tx;i>0;i--){
for(m=0;m<k+1;m++){
if(table[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;
getsym();
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,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==ident||sym==number||sym==lparen) /*循环直到不是因子开始符号*/
{
if(sym==ident) /*因子为常量或变量*/
{
i=position(id,*ptx); /*查找名字*/
if(i==0)
error(11); /*标示符未声明*/
getsym();
}
else if(sym==number) /*因子为数*/
{
if(num>2047) /*数字越界*/
{
error(31);
num=0;
}
getsym();
}
else /*因子为表达式*/
{
getsym();
expression(ptx,lev);
if(sym==rparen)
getsym();
else
error(22); /*缺少右括号*/
}
}
return 0;
} //***********************************************************factor*********************
//项处理
int term(int *ptx,int lev) //**************************************************************term*******************
{
//enum symbol mulop; /*用于保存乘除法符号,定义为全局变量*/
factor(ptx,lev); /*处理因子*/
while(sym==times||sym==slash)
{
getsym();
factor(ptx,lev);
}
return 0;
} //*************************************************************term*********************
/*表达式处理*/
int expression(int *ptx,int lev)//***********************************************************expression*********************
{
enum symbol addop; /*用于保存正负号*/
if(sym==plus||sym==minus) /*开头的正负号,此时当前表达式被看做一个正或负的项*/
{
addop=sym; //保存开头的正负号
getsym();
term(ptx,lev);
}
else
term(ptx,lev); //处理项
while(sym==plus||sym==minus)
{
getsym();
term(ptx,lev);//处理项
}
return 0;
} //****************************************************************expression****************
//条件语句处理
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{
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;
}
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);
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();
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)
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();
}
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");
}
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..end语句\n");
if(sym==endsym){
getsym();
if(sym==procsym)
block();
}
else
error(17);
}
else if(sym==whilesym){
getsym();
condition(ptx,lev);
if(sym==dosym)
getsym();
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){
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);
}
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
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,&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);
}
}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("
展开阅读全文