c语言词法分析程序:PL/0语言词法分析程序



要求:
1、读入用PL/0语言编写正确进行词法分析并输出 2元式序列
2、若源有词法能够给出出错准确位置
3、词法代号如下
(++);
(--);
(**);
(//);
((;
));
(,,);
(;;);
(..);
(##);
(==);
(>>);
(<<);
(:=,a);
(>=,b);
(<=,c);
(数字,d);
(标识符,e);
关键字代号:
(beginf);
(callg);
(consth);
(doi);
(endj);
(k);
(oddl);
(procedurem);
(readn);
(theno);
(varp);
(whileq);
(writer);
4、等于运算符号为个=
测试:
A.C

CONSTA=10;
VARB,C;
PROCEDUREP;
VARD;
PROCEDUREQ;
VARX;
BEGIN
READ(X);
D:=X;
WHILEX<0
DOCALLP;
END;
BEGIN
WRITE(D);
CALLQ;
END;
BEGIN
CALLP;
END.

*/
/*programname:chufenxi*/
/*作者:小万qq:421404493*/
/*date:2004.10.11*/
#<stdio.h>
#<stdlib.h>
#<conio.h>
#<ctype.h>
#<.h>

#N256//每数不能超过256个

charbuffer[N];//用作存放
charword[20];//用作存放经过分析单词
char*kword[13]={"begin","call","const","do","end","","odd","procedure","read","then","var","while","write"};
charktype[13]={’f’,’g’,’h’,’i’,’j’,’k’,’l’,’m’,’n’,’o’,’p’,’q’,’r’};
len;//记录每长度
count=0;//用来记录行数
voidwrite(char*wstr,charwc,FILE*wout)//将分析结果按照规则写入到文件
{
fputc(’(’,wout);
fputs(wstr,wout);
fputc(’,’,wout);
fputc(wc,wout);
fputc(’)’,wout);
}
readbuffer(FILE*fp)
{
charch;
len=0;
ch=fgetc(fp);
while(!feof(fp)&&ch!=’\\n’)//读取到缓冲区
{
buffer[len]=ch;
ch=fgetc(fp);
len;
}

len--;//用来控制词法分析时行分析中字母个数



(feof(fp))//标志文件是否结束
0;

1;
}
voiderror(type)
{

(type1)
prf("为无效,第%d行词法出错,标志符不能以数字开头\\n",count);
(type2)
prf("第%d行词法出错赋值符应为\\:\\=\\n",count);

prf("为无效第%d行词法出错\\n",count);
}
voidcheck(char*str,FILE*out);//声明用来分类单词
voidfenxi(char*row,FILE*op)//此用来对每单词进行语法分析
{
//prf("%d\\n",count);
k=0;//用作控制临时存放单词变量str0
i=0;//定义两个变量用作控制每行是否结束
ferror=0;//用作出错标志
charstr0[20];//临时存放单词变量
while(i<=len)
{
k=0;//将k置0
strcpy(word,"\\0");//将存放单词变量清空
/*去除空格*/
(isspace(row[i]))//去出空格跳格符换行符
{
i;
continue;
}
/*去出无效*/
while(!isalpha(row[i])&&!isdigit(row[i])&&i<=len&&!isspace(row[i])&&!(row[i]’\\0’||row[i]’:’||row[i]’>’||row[i]’<’||row[i]’+’||row[i]’-’||row[i]’*’||row[i]’/’||row[i]’(’||row[i]’)’||row[i]’,’||row[i]’;’||row[i]’.’||row[i]’#’||row[i]’=’))
{
putchar(row[i]);
i;
ferror=1;//设置标志符

}
(ferror1)
{
error(3);//出错处理
ferror=0;
}
/*对注释进行处理,假设此语言注释只能单行注释以双斜杠“//”为注释开始标志*/
(row[i]’/’)
{
i;
(row[i]’/’)
{
i=len+1;//忽略注释符后面单词
continue;
}

i--;
}
/*判断是否为数字*/
(isdigit(row[i]))
{
while(i<=len&&!isspace(row[i])&&!(row[i]’\\0’||row[i]’:’||row[i]’>’||row[i]’<’||row[i]’+’||row[i]’-’||row[i]’*’||row[i]’/’||row[i]’(’||row[i]’)’||row[i]’,’||row[i]’;’||row[i]’.’||row[i]’#’||row[i]’=’))
//当不到行尾是数字或字母当然有可能是无效
{

(isdigit(row[i]))//是数字则将逐个存入临时
{
str0[k]=row[i];
i;
k;
//putchar(’e’);
}
//数字中加有字母或无效则报错
{
//putchar(’x’);
ferror=1;;//已经出错设置标志并退出循环

}
}
(ferror1)//检测是否出错
{/*将刚刚那个单词后面数字和字母
清空如123abc123或则123$$23等当出现
要消除abc123和$$23 以免误作为下个标志符*/
for(j=0;j<k;j)
putchar(str0[j]);
while(i<=len&&!isspace(row[i])&&!(row[i]’\\0’||row[i]’:’||row[i]’>’||row[i]’<’||row[i]’+’||row[i]’-’||row[i]’*’||row[i]’/’||row[i]’(’||row[i]’)’||row[i]’,’||row[i]’;’||row[i]’.’||row[i]’#’||row[i]’=’))


{
putchar(row[i]);
i;

}
error(1);//putchar(’e’);//出错处理
ferror=0;//重新设置标志位
//i--;//strcpy(word,"");
}
//未出错照常处理
{
str0[k]=’\\0’;
strcpy(word,str0);
i--;//减是为了使最后取出那个不在被下面判断
//str0[0]=’\\0’;

}
}
/*判断是否为标志符和关键字即由字母开头并且不含标点符号用ispunct(ch)判断标点符号*/
(isalpha(row[i]))//标志符或关键字由字母开头
{

k=0;
while(i<=len&&row[i]!=32&&!(row[i]’\\0’||row[i]’:’||row[i]’>’||row[i]’<’||row[i]’+’||row[i]’-’||row[i]’*’||row[i]’/’||row[i]’(’||row[i]’)’||row[i]’,’||row[i]’;’||row[i]’.’||row[i]’#’||row[i]’=’))//关键字和标志符由数字和字母组成
{
(isalpha(row[i])||isdigit(row[i]))//由数字和字母组成
{
str0[k]=row[i];
i;
k;
}
//出错原因可能是出现了不可识别
{


ferror=1;;
}

}
(ferror)
{
for(j=0;j<k;j)
putchar(str0[j]);
while(i<=len&&!isspace(row[i])&&!(row[i]’\\0’||row[i]’:’||row[i]’>’||row[i]’<’||row[i]’+’||row[i]’-’||row[i]’*’||row[i]’/’||row[i]’(’||row[i]’)’||row[i]’,’||row[i]’;’||row[i]’.’||row[i]’#’||row[i]’=’))
{
putchar(row[i]);//消除整个非法单词
i;
}
ferror=0;
error(3);
//i--;
}

{
str0[k]=’\\0’;
strcpy(word,str0);
str0[0]=’\\0’;
i--;
}
}
/*判断运算符*/
(row[i]’+’||row[i]’-’||row[i]’*’||row[i]’/’||row[i]’(’||row[i]’)’||row[i]’,’||row[i]’;’||row[i]’.’||row[i]’#’||row[i]’=’)
{
str0[0]=row[i];
str0[1]=’\\0’;
strcpy(word,str0);
str0[0]=’\\0’;
}//要先判断单个运算符以避免诸如>=运算符后面=再次被判断
(row[i]’:’)
{
i;
(row[i]’=’)
{
//word[0]=’:’;
//word[1]=’=’;
//word[2]=’\\0’;
strcpy(word,">=");


}

{
error(2);//出错后处理
i--;
}
}

(row[i]’>’)
{
i;
(row[i]’=’)
{

strcpy(word,">=");
}

{
strcpy(word,">");
i--;
}
}
(row[i]’<’)
{
i;
(row[i]’=’)
{
strcpy(word,"<=");

}

{strcpy(word,"<");i--;}
}

//puts(word);


check(word,op);/*
分类辨别每个单词类别要求
输入个单词必须符合词法规则*/
//word[0]=’\\0’;
i;//使指针后移取出下个字母
}
}
voidcheck(char*str,FILE*out)
{


(isdigit(str[0]))/*如果第是数字那么整个单词都是数字组成即为常数*/
{
write(str,’d’,out);//将分好类单词写入文件
}

(isalpha(str[0]))/*如果第是字母那么这个单词是标志符或关键字*/
{
fyiyong=0;//用作标记这个单词是否已被分类
/*以下判别是否是关键字*/
for(ct=0;ct<13;ct)
{
(!strcmp(str,kword[ct]))
{
write(str,ktype[ct],out);
fyiyong=1;
}
}
/*经过以上判别可以判别是否是关键字不是即为标志符*/
(fyiyong!=1)
{
write(str,’e’,out);
}
}
/*以下对运算符分类*/
(str[0]’>’)
{
(str[1]’=’)
{
write(str,’b’,out);
}

{
write(str,’>’,out);
}
}
(str[0]’<’)
{
(str[1]’=’)
{
write(str,’c’,out);
}

{
write(str,’<’,out);
}
}

(!strcmp(str,":="))
{
write(str,’a’,out);


}


(str[0]’+’||str[0]’-’||str[0]’*’||str[0]’/’||str[0]’(’||str[0]’)’||str[0]’,’||str[0]’;’||str[0]’.’||str[0]’#’||str[0]’=’)
{
write(str,str[0],out);
}


}
void
{
count=1;
charscfilename[20],rsfilename[20];//定义用来存放输入源文件和输出目标文件名字
prf("Pleaseinputyoursourcefilename:");
gets(scfilename);
prf("Pleaseinputyourresultfilename:");
gets(rsfilename);
FILE*fp,*op;
fp=fopen(scfilename,"r");
op=fopen(rsfilename,"w");
(fp)//打开文件成功后对源文件进行词法分析
{
while(readbuffer(fp))
{
fenxi(buffer,op);
count;//行加
}
}
//whilethefilenotexist
{
prf("Yoursoucefilenotexist!!!\\n");
exit(0);
}
fclose(fp);//clohefiles
fclose(op);
prf("ok!");//outputthemarkofend
getchar;
}
Tags:  词法分析器程序 c语言词法分析器 词法分析程序 c语言词法分析程序

延伸阅读

最新评论

发表评论