农林大学 编译原理课程设计Word文件下载.docx
- 文档编号:17178273
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:33
- 大小:152.08KB
农林大学 编译原理课程设计Word文件下载.docx
《农林大学 编译原理课程设计Word文件下载.docx》由会员分享,可在线阅读,更多相关《农林大学 编译原理课程设计Word文件下载.docx(33页珍藏版)》请在冰豆网上搜索。
printf("
----------------------------------------------------------\n"
请输入字符串:
charch;
inti,j,t,flag;
i=0;
t=1;
//判断输入是否正确
flag=0;
//判断句子是否正确
while((ch=getchar())!
='
\n'
)
{if(ch=='
a'
)j=0;
if(ch=='
b'
)j=1;
if(ch!
&
ch!
{t=0;
//输入有误
break;
}i=s[i][j];
}
flag=i;
if(flag>
=3&
t)//flag>
2时可终结
\n输入字符串正确!
\n\n"
else
\n输入字符串错误!
}
1.4程序运行截图
1、输入正确的字符串:
2、输入错误的字符串:
1.5小结
在这次课程设计,对正则文法和状态转换图和有限自动机的理论有了更深的了解,将理论应用于实际应用中。
2、LL
(1)分析
2.1LL
(1)文法
E→TE'
(注:
该文法为示例,可更改)
E'
→+TE'
|ε
T→FT'
T'
→*FT'
F→(E)|i
2.2LL
(1)预测分析表
i
+
*
(
#
E
E→TE'
E'
→ε
T
T→FT'
T'
F
F→i
F→(E)
2.3分析程序代码
#include<
iostream>
cstdio>
cstdlib>
cstring>
stack>
usingnamespacestd;
//存储分析预测表每个位置对应的终结符,非终结符,产生式
structNode1
{charvn;
charvt;
chars[10];
}MAP[20];
intk;
//用R代表E'
W代表T'
e代表空
charG[10][10]={"
E->
TR"
"
R->
+TR"
e"
T->
FW"
W->
*FW"
F->
(E)"
i"
};
//存储文法中的产生式
charVN[6]={'
'
R'
W'
F'
//存储非终结符
charVT[6]={'
i'
+'
*'
('
)'
#'
//存储终结符
charSELECT[10][10]={"
(,i"
+"
),#"
*"
+,),#"
("
//存储文法中每个产生式对应的SELECT集
charRight[10][8]={"
->
stack<
char>
stak,stak1,stak2;
boolcompare(char*a,char*b)//比较字符
{inti,la=strlen(a),j,lb=strlen(b);
for(i=0;
i<
la;
i++)
for(j=0;
j<
lb;
j++)
{if(a[i]==b[j])
return1;
}return0;
char*Find(charvn,charvt)
{inti;
k;
{if(MAP[i].vn==vn&
MAP[i].vt==vt)
returnMAP[i].s;
}return"
error"
;
char*Analyse(char*word)
{charp,action[10],output[10];
inti=1,j,l=strlen(word),k=0,l_act,m;
while(!
stak.empty())
stak.pop();
stak.push('
________________________________________________________________________________\n"
\n对符号串%s的分析过程\n"
word);
步骤栈顶元素剩余输入串推到所用产生式或匹配\n"
p=stak.top();
while(p!
{printf("
%7d"
i++);
%6c"
p);
for(j=k,m=0;
l;
output[m++]=word[j];
//推导出相同字符,出栈
output[m]='
\0'
%10s"
output);
if(p==word[k])//在输入的字符串在首尾加#是用于判断否结束
{if(p=='
接受\n"
return"
成功"
%c匹配\n"
k++;
}else
{strcpy(action,Find(p,word[k]));
if(strcmp(action,"
)==0)
没有可用的产生式\n"
ERROR"
%c%s\n"
p,action);
intl_act=strlen(action);
if(action[l_act-1]=='
e'
continue;
for(j=l_act-1;
j>
1;
j--)
stak.push(action[j]);
}}
if(strcmp(output,"
#"
)!
=0)
错误"
}
intmain()
{charsource[100];
inti,j,flag,l,m;
LL
(1)文法\n"
\n★★★★★★为了区分E'
和后面的”,用R表示E'
W表示T'
e表示空字符串★★★★★★\n\n"
该文法的产生式如下:
8;
%s\n"
G[i]);
---------------------------------------------------------------\n"
//判断是否是LL
(1)文法
flag=1;
{for(j=i+1;
{if(G[i][0]==G[j][0])
{if(compare(SELECT[i],SELECT[j]))
{flag=0;
break;
}}}
if(j!
=8)
break;
if(flag)
\n有相同左部产生式的SELECT集合的交集为空,所以文法是LL
(1)文法。
\n有相同左部产生式的SELECT集合的交集不为空,所以文法不是LL
(1)文法。
//预测分析表
for(i=0,k=0;
{l=strlen(SELECT[i]);
j+=2)
{MAP[k].vn=G[i][0];
MAP[k].vt=SELECT[i][j];
strcpy(MAP[k].s,Right[i]);
}}
\nLL
(1)文法的预测分析表如下:
"
6;
%10c"
VT[i]);
5;
---------------------------------------------------------------\n"
VN[i]);
for(j=0;
{for(m=0;
m<
m++)
{if(VN[i]==MAP[m].vn&
VT[j]==MAP[m].vt)
MAP[m].s);
if(m==k)
/*预测分析程序Analyse函数*/
在输入字符串时要在后面加一个#,否则程序将无法正常运行!
请输入一个测试的字符串:
while(cin>
>
source)
\n分析结果:
%s\n\n"
Analyse(source));
while
(1)
{chard;
cout<
<
"
是否继续?
(Y/N)"
cin>
d;
if(d=='
Y'
||d=='
y'
{printf("
n'
N'
{return0;
}}}return0;
2.4程序运行截图
1、初始界面:
2、成功的字符串:
(i)#
成功的字符串:
i+i*i#
3、不成功的字符串:
ii*#
2.5小结
在这次课程设计中,对LL
(1)算法中基础理论和基本知识的有了更深的理解,能更灵活应用的所学的知识。
不仅学会程序实现文法判断、结构体和数组的使用等多种问题的基本方法,能将所学的理论知识应用于实践中。
3算符优先分析
3.1算符优先文法
E→T|E+T|E-T(注:
T→F|T*F|T/F
F→(E)|i
3.2算符优先关系表
-
/
>
<
=
3.3分析程序代码
#include<
iostream.h>
stdlib.h>
fstream.h>
#definerow50
#definecol50
#defineSIZE50
//两个重要结构体的定义
//FIRSTVT表或LASTVT表中一个表项(A,a)结构体的初始化
typedefstruct
{charnonterm;
//非终结符
charterm;
//终结符
}StackElement;
//存放(A,a)的栈的初始化
typedefstruct
{StackElement*top;
StackElement*bottom;
intstacksize;
}stack;
//初始化(A,a)栈
voidInitStack(stack&
S)
{S.bottom=newStackElement[SIZE];
if(!
S.bottom)
cout<
存储空间分配失败!
endl;
S.top=S.bottom;
S.stacksize=SIZE;
//判断(A,a)栈是否为空
boolifEmpty(stackS)
{if(S.top==S.bottom)returntrue;
//如果栈为空,则返回true
elsereturnfalse;
//否则不为空,返回false
//插入栈顶(A,a)元素
voidInsert(stack&
S,StackElemente)
{if(S.top-S.bottom>
=S.stacksize)
栈已满,无法插入!
{S.top->
nonterm=e.nonterm;
S.top->
term=e.term;
S.top++;
}}
//弹出栈顶(A,a)元素
StackElementPop(stack&
{StackElemente;
e.nonterm='
e.term='
if(S.top==S.bottom)
{cout<
栈为空,无法进行删除操作!
returne;
else{S.top--;
e.nonterm=S.top->
nonterm;
e.term=S.top->
term;
//终结符与非终结符的判断函数(布尔类型)
boolTerminalJud(charc)
{if(c>
A'
c<
Z'
)returnfalse;
//非终结符返回false
elsereturntrue;
//终结符返回true
//判断非终结符在first表中是否已存在
boolItemJud(charfirst[][col],intfrist_len,charC)
{for(inti=0;
frist_len;
{if(first[i][0]==C)
returntrue;
//如果first表中已存在此非终结符,则返回true
}returnfalse;
//读文件函数
intreadfile(charsen[][col])
{charaddr[50];
请输入算符优先文法的描述的地址:
cin>
addr;
ifstreamfin;
fin.open(addr,ios:
:
in);
fin)
Cannotopenfile!
for(inti=0;
!
fin.eof();
{fin>
sen[i];
cout<
sen[i]<
}returni;
//FIRSTVT表和LASTVT表中表项(非终结符)的初始化
voidItemInit(charsen[][col],charfirst[][col],charlast[][col],intsen_len,int&
frist_len)
frist_len=1;
first[0][0]=sen[0][0];
last[0][0]=sen[0][0];
for(i=1;
sen_len;
{if(TerminalJud(sen[i][0])==false&
ItemJud(first,frist_len,sen[i][0])==false)//k是当前first和last表的长度
{first[frist_len][0]=sen[i][0];
last[frist_len][0]=sen[i][0];
frist_len++;
}}}
voidFirstVt(charsen[][col],charfirst[][col],intsen_len,intfrist_len)//frist_len是first表的行数sen_len是产生式的个数
{StackElementDFS,record[SIZE];
stackOperator;
//创建存放(A,a)的栈
InitStack(Operator);
inti,j,r=0;
i++)//第一次扫描,将能直接得出的first(A,a)放进栈中
{for(j=3;
sen[i][j]!
{if(TerminalJud(sen[i][j])==true)//遇到的第一个终结符压入
{intexist=0;
DFS.nonterm=sen[i][0];
DFS.term=sen[i][j];
for(inti1=0;
r;
{if(record[i1].nonterm==sen[i][0]&
record[i1].term==sen[i][j])
{exist=1;
break;
record[r].nonterm=sen[i][0];
record[r].term=sen[i][j];
if(exist==0)
{Insert(Operator,DFS);
//A-aBA-aC(A,a)压栈两次?
record[r].nonterm=sen[i][0];
record[r].term=sen[i][j];
r++;
}break;
intlocation[col];
//辅助数组,用来记录first表中放入终结符的位置
i++)
location[i]=1;
ifEmpty(Operator))
{intexist=0;
//标志位,记录即将入栈的元素是否已经存在
StackElementIDElement,DElement;
DElement=Pop(Operator);
//弹出栈顶元素
for(i=0;
{if(first[i][0]==DElement.nonterm)
{intn=location[i];
first[i][n]=DElement.term;
//将终结符填入相应的first表中
location[i]++;
break;
for(j=0;
{if(sen[j][3]==DElement.nonterm)//找出能推出当前非终结符的产生式的左部
{IDElement.nonterm=sen[j][0];
IDElement.term=DElement.term;
//判断将要放进栈里的元素曾经是否出现过,若没有,才压入栈
for(intr0=0;
r0<
r0++)//r记录record数组中的元素个数
{if(record[r0].nonterm==IDElement.nonterm&
record[r0].term==IDElement.term)
}}
if(exist==0)
{Insert(Operator,IDElement);
record[r].nonterm=IDElement.nonterm;
record[r].term=IDElement.term;
}}}}}
voidLastVt(charsen[][col],charlast[][col],intsen_len,intfrist_len)//firstvt表与lastvt表行数一样first_len表示last表的行数
{inti,j,i1,j1;
charc,record[row][col]={'
{for(j=0;
{record[i][j]=sen[i][j];
j=j-1;
for(i1=3,j1=j;
i1<
j1;
i1++,j1--)//做翻转,就可以用求first的方法求last
{c=record[i][i1];
record[i][i1]=record[i][j1];
record[i][j1]=c;
FirstVt(record,last,sen_len,frist_len);
//判断非终结符在term表中是否已存在
boolTermTableJud(ch
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 农林大学 编译原理课程设计 农林 大学 编译 原理 课程设计