littlec递归下降的语法分析及词法分析解读.docx
- 文档编号:17026622
- 上传时间:2023-07-21
- 格式:DOCX
- 页数:28
- 大小:225.42KB
littlec递归下降的语法分析及词法分析解读.docx
《littlec递归下降的语法分析及词法分析解读.docx》由会员分享,可在线阅读,更多相关《littlec递归下降的语法分析及词法分析解读.docx(28页珍藏版)》请在冰点文库上搜索。
littlec递归下降的语法分析及词法分析解读
Littlec递归下降的语法分析实验报告
一.语法分析对应littlec文法
<小c程序>:
:
=<主函数>#|<外部定义><主函数>#
注:
其中‘#’为语法分析时分析结束的标志,无实际意义
<主函数>:
:
=main()<函数体>
<外部定义>:
:
=<变量声明><外部函数定义>
<变量声明>:
:
=null|<类型区分符><标识符>{;<类型区分符><标识符>}
注:
大括号内为一个循环体,表示可出现多次,下同。
<外部函数定义>:
:
=<类型区分符><函数说明符><函数体>
<类型区分符>:
:
=int|char
<函数说明符>:
:
=<函数名>()
<函数名>:
:
=<标识符>
<函数体>:
:
={<变量声明><语句表>}
<语句表>:
:
=<语句>{;<语句>}
<语句>:
:
=<赋值语句>|<条件语句>|<循环语句>|<函数调用语句>|;
<赋值语句>:
:
=<左部>=<右部>
<左部>:
:
=<变量名>
<右部>:
:
=<算术表达式>
<算术表达式>:
:
=<项>{+<项>|-<项>}
<项>:
:
=<因子>{*<因子>|/<因子>
<因子>:
:
=ID|NUM|(<算术表达式>)
<条件语句>:
:
=if(<关系表达式>)<语句>|if(<关系表达式>)<语句>else<语句>
<关系表达式>→〈算术表达式〉〈关系运算符〉〈算术表达式〉
<变量名>:
:
=<标识符>
<关系运算符>:
:
=<|>|!
=|==|>=|<=
<加运算符>:
:
=+|-
<乘运算符>:
:
=*|/
<循环语句>:
:
=while(<关系表达式>)<语句>
二.实验简介
本实验采用递归子程序法完成了上述语言文法的语法分析,正确的程序经过分析显示“分析完毕,正确”,错误的程序经过分析,对其进行报错,虽不能准确定位错误,但是大致可以确定错误类型。
因上次词法分析被误删,所以本程序结合词法分析与语法分析于一体,同时对源程序进行词法与语法分析。
但由于个人能力有限,故没有生成语法树,也没有错误恢复处理。
本程序只是完成了对含有外部数据定义,外部函数,main函数的c程序的语法分析,并且对if语句,while语句,函数调用语句,空语句(;),表达式进行了相应的分析。
三.函数功能及全局变量简介
Syn:
经词法分析后,每个单词对应的标识
Kk:
出错的标识,有错置一
mainfunc();main函数处理程序。
funcbody();函数体处理程序。
outdef();外部定义处理函数
vardef();变量声明处理函数
outfunc();外部函数处理函数
yjc();语句串处理函数
statement();语句处理函数
assignstmt();赋值语句处理函数
funcall();函数调用处理语句
conditstmt();条件语句处理函数
loopstmt();循环语句处理函数
relexp();关系表达式处理函数
expression();算术表达式处理函数
factor();因子处理函数
term();项处理函数
parser();语法分析
scaner();读取下一个单词
四.符号表
单词符号
种别码
单词符号
种别码
main
1
:
17
If
2
==
18
else
3
<
20
wile
4
!
=
21
int
5
<=
22
char
6
>
23
标识符
10
>=
24
数字
11
=
25
+
13
;
26
—
14
(
27
*
15
)
28
/
16
#
0
{
29
}
30
五.结果测试:
正确结果测试:
1.只含main函数:
main(){
inty;
intx;
x=3;
y=1;
if(x>y)
x=x-y;
elsex=y-x;
while(x>y)
x=x-y;
;
}#
2.含外部函数
intcal(){
inta;
intb;
intc;
a=0;
b=3;
c=a+b;
}
main(){
inty;
intx;
x=3;
y=1;
if(x>y)
x=x-y;
elsex=y-x;
while(x>y)
x=x-y;
cal();
;
}#
3.含外部数据说明以及外部函数
intm;
intn;
intcal(){
inta;
intb;
intc;
a=0;
b=3;
c=a+b;
}
main(){
inty;
intx;
x=3;
y=1;
if(x>y)
x=x-y;
elsex=y-x;
while(x>y)
x=x-y;
cal();
;
}#
错误结果测试:
1.main后缺‘{’:
main()
inty;
intx;
x=3;
y=1;
if(x>y)
x=x-y;
elsex=y-x;
while(x>y)
x=x-y;
;
}#
2.声明变量缺少“int”
main(){
y;
intx;
x=3;
y=1;
if(x>y)
x=x-y;
elsex=y-x;
while(x>y)
x=x-y;
;
}#
3.赋值符号‘=’误写成‘==’
main(){
inty;
intx;
x==3;
y=1;
if(x>y)
x=x-y;
elsex=y-x;
while(x>y)
x=x-y;
;
}#
4.关键字写错
源代码:
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"windows.h"
charprog[2000],token[8],ch;
char*rwtab[6]={"main","if","else","while","int","char"};
intsyn,p,m,n,sum;
intkk;
mainfunc();
funcbody();
outdef();
vardef();
outfunc();
yjc();
assignstmt();
funcall();
conditstmt();
loopstmt();
factor();
relexp();
expression();
term();
statement();
parser();
scaner();
main()
{FILE*fp1;
charfilename[10];
p=kk=0;
printf("请输入文件名(含路径):
");
gets(filename);
if((fp1=fopen(filename,"r"))==NULL)
{
printf("无法打开此文件");
exit(0);
}
elsewhile(!
feof(fp1)){
prog[p++]=fgetc(fp1);
}
puts(prog);
fclose(fp1);
p=0;
scaner();
parser();
getchar();
}
/*========================语法分析=======================*/
parser()
{
if(syn==1){
mainfunc();
}
else{
if(syn==5||syn==6)
{
outdef();
mainfunc();
}
else{
printf("无效的littleC程序\n");
kk=1;
}
}
if((syn==0)&&(kk==0))
printf("成功!
\n");
return;
}
/*===============主函数处理函数====================*/
mainfunc(){
if(syn==1)
scaner();
else{
printf("没有main函数\n");
kk=1;
scaner();
}
if(syn==27)
scaner();
else
{printf("main后需要一个‘(’\n");
kk=1;
scaner();
}
if(syn==28)
scaner();
else{
printf("main函数中‘(’后需要一个‘)’\n");
kk=1;
scaner();
}
funcbody();
return;
}
/*===============函数体处理函数==================*/
funcbody(){
if(syn==29)
scaner();
else{
printf("函数需要一个‘{’\n");
kk=1;
scaner();
}
vardef();
yjc();
if(syn==30){
scaner();
if(syn==0)
{printf("分析完\n");
return;}
}
else
{
printf("函数后未匹配的‘{’\n");
kk=1;
}
return;
}
/*===============外部定义处理函数==================*/
outdef(){
vardef();
outfunc();
return;}
/*================变量声明处理函数==================*/
vardef(){
if(syn==5||syn==6){
scaner();
if(syn==10)
{
scaner();
while(syn==26)
{scaner();
if(syn==5||syn==6)
{
scaner();
if(syn==10)
scaner();
}
elsebreak;
}
}
else{
printf("datatype后需要一个标识符\n");
kk=1;
}
}
elseif(syn==2||syn==4||syn==10||syn==26)
{
return;
}
else{
printf("未声明的变量\n");
kk=1;
}
return;
}
/*===================外部函数处理函数=======================*/
outfunc(){
if(syn==27)
scaner();
else
{printf("外部函数名后需要一个‘(’\n");
kk=1;
scaner();}
if(syn==28)
scaner();
else{
printf("外部函数中未匹配的‘(’\n");
kk=1;
scaner();
}
funcbody();
return;
}
/*======语句串处理程序========*/
yjc()
{
statement();/*调用函数statement();*/
while(syn==26)
{
scaner();/*读下一个单词符号*/
if(syn!
=30)
statement();/*调用函数statement();*/
}
return;
}
/*==========语句处理程序===================*/
statement()
{
if(syn==10)
{
scaner();
if(syn==25)
assignstmt();
elseif(syn==27)
funcall();
else{
printf("期待一个‘=’或‘(’\n");
kk=1;
}
}
elseif(syn==2){
conditstmt();
}
elseif(syn==4)
{
loopstmt();
}
elseif(syn=26)
{return;}
else
{printf("非法的语句!
\n");
kk=1;
}
return;
}
/*===================赋值语句处理函数=====================*/
assignstmt(){
scaner();/*读下一个单词符号*/
expression();/*调用函数statement();*/
return;
}
/*============函数调用语句处理函数==============*/
funcall(){
scaner();
if(syn==28)
scaner();
else
{
printf("函数调用语句需要一个‘(’\n");
kk=1;
scaner();
}
return;
}
/*============条件语句处理函数============*/
conditstmt(){
scaner();
if(syn==27)
{
scaner();
relexp();
if(syn==28)
scaner();
else{
printf("if语句中未匹配的‘(’\n");
kk=1;
scaner();
}
statement();
if(syn==26)
{
scaner();
if(syn==3)
{
scaner();
statement();
}
else{
if((syn==10)||(syn==2)||(syn==4)||(syn==26))
{
return;
}
else{
printf("if后非法的的语句\n");
kk=1;
}
}
}
else{
printf("if语句中需要一个‘;’\n");
kk=1;
}
}
else{
printf("if语句中需要一个‘(’\n");
kk=1;
}
return;
}
/*==============循环语句处理函数===============*/
loopstmt(){
scaner();
if(syn==27){
scaner();
relexp();
if(syn==28)
scaner();
else{
printf("while语句中需要一个‘)’\n");
kk=1;
scaner();
}
statement();
}
else{
printf("while语句中需要一个‘(’\n");
kk=1;
}
return;
}
/*=====================关系表达式处理函数========================*/
relexp(){
expression();
if((syn==18)||(syn==20)||(syn==22)||(syn==21)||(syn==23)||(syn==24))
scaner();
else{
printf("关系表达式中需要一个关系运算符\n");
kk=1;
scaner();
}
expression();
return;
}
/*============算术表达式处理程序=============*/
expression()
{term();
while((syn==13)||(syn==14))
{scaner();/*读下一个单词符号*/
term();/*调用函数term();*/
}
return;
}
/*==============项处理程序================*/
term()
{factor();
while((syn==15)||(syn==16))
{scaner();/*读下一个单词符号*/
factor();/*调用函数factor();*/
}
return;
}
/*===============因子处理程序=================*/
factor()
{if((syn==10)||(syn==11))scaner();
elseif(syn==27)
{scaner();/*读下一个单词符号*/
expression();/*调用函数statement();*/
if(syn==28)
scaner();/*读下一个单词符号*/
else{printf("theerroron'('\n");
kk=1;
}
}
else{printf("theexpressionerror!
\n");
kk=1;
}
return;
}
/*==================读下一个字符进行词法分析=================*/
scaner()
{sum=0;
for(m=0;m<8;m++)
token[m]=NULL;
m=0;
ch=prog[p++];
while((ch=='')||(ch=='\n'))ch=prog[p++];
if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))
{while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&
(ch<='9')))
{token[m++]=ch;
ch=prog[p++];
}
p--;
syn=10;
token[m++]='\0';
for(n=0;n<6;n++)
if(strcmp(token,rwtab[n])==0)
{syn=n+1;
break;
}
}
elseif((ch>='0')&&(ch<='9'))
{while((ch>='0')&&(ch<='9'))
{sum=sum*10+ch-'0';
ch=prog[p++];
}
p--;
syn=11;
}
elseswitch(ch)
{
case'<':
m=0;
ch=prog[p++];
if(ch=='=')
{syn=22;
}
else
{syn=20;
p--;
}
break;
case'>':
m=0;
ch=prog[p++];
if(ch=='=')
{syn=24;
}
else
{syn=23;
p--;
}
break;
case'=':
m=0;
ch=prog[p++];
if(ch=='='){syn=18;}
else{syn=25;
p--;}
break;
case'!
':
m=0;
ch=prog[p++];
if(ch=='='){syn=21;}
break;
case'+':
syn=13;break;
case'-':
syn=14;break;
case'*':
syn=15;break;
case':
':
syn=17;break;
case'(':
syn=27;break;
case')':
syn=28;break;
case';':
syn=26;break;
case'#':
syn=0;break;
case'{':
syn=29;break;
case'}':
syn=30;break;
case'/':
syn=16;break;
default:
syn=-1;break;
}
}
测试代码:
正确
intcal(){
inta;
intb;
intc;
a=0;
b=3;
c=a+b;
}
main(){
inty;
intx;
x=3;
y=1;
if(x>y)
x=x-y;
elsex=y-x;
while(x>y)
x=x-y;
cal();
;
}#
错误
main(){
inty;
intx;
x=3;
y=1;
if(x>y)
x=x-y;
elsx=y-x;
while(x>y)
x=x-y;
;
}#
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- littlec 递归 下降 语法分析 词法 分析 解读