LL1分析法.docx

上传人:b****3 文档编号:4959980 上传时间:2022-12-12 格式:DOCX 页数:38 大小:359.76KB
下载 相关 举报
LL1分析法.docx_第1页
第1页 / 共38页
LL1分析法.docx_第2页
第2页 / 共38页
LL1分析法.docx_第3页
第3页 / 共38页
LL1分析法.docx_第4页
第4页 / 共38页
LL1分析法.docx_第5页
第5页 / 共38页
点击查看更多>>
下载资源
资源描述

LL1分析法.docx

《LL1分析法.docx》由会员分享,可在线阅读,更多相关《LL1分析法.docx(38页珍藏版)》请在冰豆网上搜索。

LL1分析法.docx

LL1分析法

编译原理

 

日期:

班级:

题目:

LL

(1)分析法

组员:

LL

(1)语法分析程序

1.实验目的:

1.根据某一文法编制调试LL

(1)分析程序,以便对任意输入的符号串进行分析。

2.本次实验的目的主要是加深对预测分析LL

(1)分析法的理解。

2.实验平台

Windows+VC+Win32Console

范例程序:

“3-LL1.c”

3.实验内容

1.在范例程序的基础上完善功能

对下列文法,用LL

(1)分析法对任意输入的符号串进行分析:

(1)E→TG

(2)G→+TG|—TG

(3)G→ε

(4)T→FS

(5)S→*FS|/FS

(6)S→ε

(7)F→(E)

(8)F→i

程序输入/输出示例:

程序现有功能:

输入:

一个以#结束的符号串(包括+*()i#):

例如:

i+i*i#

步骤

分析栈

剩余输入串

所用产生式

1

#E

i+i*i#

E→TG

输出:

只能输出步骤1,格式如下:

 

程序目前还不能对所有输入串进行正确的分析.

需要完善的功能:

(1)请输出完整的分析过程。

即详细输出每一步骤分析栈和剩余串的变化情况,及每一步所用的产生式. 

(2)请输出最终的分析结果,即输入串“合法”或“非法”.

(3)示例程序只能完成+、*、(、)的语法分析,请加入-和/的语法分析

(4)可将测试用的表达式事先放在文本文件中,一行存放一个表达式,以分号分割。

同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照;

 备注:

1.在“所用产生式”一列中,

如果对应有推导,则写出所用产生式;如果为匹配终结符,则写明匹配的终结符;

如分析异常出错则,写为“分析出错”;如成功结束则写为“分析成功”。

2.对一个新的文法实现LL

(1)分析。

4.程序代码

第一种文法

#include

#include

#include

#include

charA[20];/*分析栈*/

charB[20];/*剩余串*/

charv1[20]={'i','+','-','*','/','(',')','#'};/*终结符*/

charv2[20]={'E','G','T','S','F'};/*非终结符*/

intj=0,b=0,top=0,l;/*L为输入串长度*/

typedefstructtype/*产生式类型定义*/

{

charorigin;/*大写字符*/

chararray[7];/*产生式右边字符*/

intlength;/*字符个数*/

}type;

typee,t,g,g0,g1,s,s0,s1,f,f1;/*结构体变量*/

typeC[10][10];/*预测分析表*/

voidprint()/*输出分析栈*/

{

inta;/*指针*/

for(a=0;a<=top+1;a++)

printf("%c",A[a]);

printf("\t\t");

}/*print*/

voidprint1()/*输出剩余串*/

{

intj;

for(j=0;j

printf("");

for(j=b;j<=l;j++)

printf("%c",B[j]);

printf("\t\t\t");

}/*print1*/

voidmain()

{

intm,n,k=0,flag=0,finish=0;

charch,x;

typecha;/*用来接受C[m][n]*/

/*把文法产生式赋值结构体*/

e.origin='E';

strcpy(e.array,"TG");

e.length=2;

t.origin='T';

strcpy(t.array,"FS");

t.length=2;

g.origin='G';

strcpy(g.array,"+TG");

g.length=3;

g0.origin='G';

strcpy(g0.array,"-TG");

g0.length=3;

g1.origin='G';

g1.array[0]='^';

g1.length=1;

s.origin='S';

strcpy(s.array,"*FS");

s.length=3;

s0.origin='S';

strcpy(s0.array,"/FS");

s0.length=3;

s1.origin='S';

s1.array[0]='^';

s1.length=1;

f.origin='F';

strcpy(f.array,"(E)");

f.length=3;

f1.origin='F';

f1.array[0]='i';

f1.length=1;

for(m=0;m<=4;m++)/*初始化分析表*/

for(n=0;n<=7;n++)

C[m][n].origin='N';/*全部赋为空*/

/*填充分析表*/

C[0][0]=e;C[0][5]=e;

C[1][1]=g;

C[1][2]=g0;

C[1][6]=g1;C[1][7]=g1;

C[2][0]=t;C[2][5]=t;

C[3][1]=s1;C[3][2]=s1;C[3][3]=s;

C[3][4]=s0;

C[3][6]=s1;C[3][7]=s1;

C[4][0]=f1;C[4][5]=f;

printf("提示:

本程序只能对由'i','+','-','*','/','(',')'构成的以'#'结束的字符串进行分析,\n");

printf("请输入要分析的字符串:

\n");

do/*读入分析串*/

{

scanf("%c",&ch);

if((ch!

='i')&&(ch!

='+')&&(ch!

='-')&&(ch!

='*')&&(ch!

='/')&&(ch!

='(')&&(ch!

=')')&&(ch!

='#'))

{

printf("输入串中有非法字符\n");

exit

(1);

}

B[j]=ch;

j++;

}while(ch!

='#');

l=j;/*分析串长度*/

ch=B[0];/*当前分析字符*/

A[top]='#';A[++top]='E';/*'#','E'进栈*/

printf("步骤\t\t分析栈\t\t剩余字符\t\t所用产生式\n");

do

{

x=A[top--];/*x为当前栈顶字符*/

printf("%d",k++);

printf("\t\t");

for(j=0;j<=7;j++)/*判断是否为终结符*/

if(x==v1[j])

{

flag=1;

break;

}

if(flag==1)/*如果是终结符*/

{

if(x=='#')

{

finish=1;/*结束标记*/

printf("合法\n");/*接受*/

getchar();

getchar();

exit

(1);

}/*if*/

if(x==ch)

{

print();

print1();

printf("%c匹配\n",ch);

ch=B[++b];/*下一个输入字符*/

flag=0;/*恢复标记*/

}/*if*/

else/*出错处理*/

{

print();

print1();

printf("%c出错\n",ch);/*输出出错终结符*/

exit

(1);

}/*else*/

}/*if*/

else/*非终结符处理*/

{

for(j=0;j<=4;j++)

if(x==v2[j])

{

m=j;/*行号*/

break;

}

for(j=0;j<=7;j++)

if(ch==v1[j])

{

n=j;/*列号*/

break;

}

cha=C[m][n];

if(cha.origin!

='N')/*判断是否为空*/

{

print();

print1();

printf("%c->",cha.origin);/*输出产生式*/

for(j=0;j

printf("%c",cha.array[j]);

printf("\n");

for(j=(cha.length-1);j>=0;j--)/*产生式逆序入栈*/

A[++top]=cha.array[j];

if(A[top]=='^')/*为空则不进栈*/

top--;

}/*if*/

else/*出错处理*/

{

print();

print1();

printf("%c出错\n",x);/*输出出错非终结符*/

exit

(1);

}/*else*/

}/*else*/

}while(finish==0);

}/*main*/

测试一

(1)测试i+i#

(2)测试i-i

(3)测试i*i#

(4)测试i/i#

(5)测试i+i*i#

(6)测试输入非法字符i+i*#

第二中文发

#include

#include

#include

/*******************************************/

intcount=0;/*分解的产生式的个数*/

intnumber;/*所有终结符和非终结符的总数*/

charstart;/*开始符号*/

chartermin[50];/*终结符号*/

charnon_ter[50];/*非终结符号*/

charv[50];/*所有符号*/

charleft[50];/*左部*/

charright[50][50];/*右部*/

charfirst[50][50],follow[50][50];/*各产生式右部的FIRST和左部的FOLLOW集合*/

charfirst1[50][50];/*所有单个符号的FIRST集合*/

charselect[50][50];/*各单个产生式的SELECT集合*/

charf[50],F[50];/*记录各符号的FIRST和FOLLOW是否已求过*/

charempty[20];/*记录可直接推出^的符号*/

charTEMP[50];/*求FOLLOW时存放某一符号串的FIRST集合*/

intvalidity=1;/*表示输入文法是否有效*/

intll=1;/*表示输入文法是否为LL

(1)文法*/

intM[20][20];/*分析表*/

charchoose;/*用户输入时使用*/

charempt[20];/*求_emp()时使用*/

charfo[20];/*求FOLLOW集合时使用*/

/*******************************************

判断一个字符是否在指定字符串中

********************************************/

intin(charc,char*p)

{

inti;

if(strlen(p)==0)

return(0);

for(i=0;;i++)

{

if(p[i]==c)

return

(1);/*若在,返回1*/

if(i==strlen(p))

return(0);/*若不在,返回0*/

}

}

/*******************************************

得到一个不是非终结符的符号

********************************************/

charc()

{

charc='A';

while(in(c,non_ter)==1)

c++;

return(c);

}

/*******************************************

分解含有左递归的产生式

********************************************/

voidrecur(char*point)

{/*完整的产生式在point[]中*/

intj,m=0,n=3,k;

chartemp[20],ch;

ch=c();/*得到一个非终结符*/

k=strlen(non_ter);

non_ter[k]=ch;

non_ter[k+1]='\0';

for(j=0;j<=strlen(point)-1;j++)

{

if(point[n]==point[0])

{/*如果'|'后的首符号和左部相同*/

for(j=n+1;j<=strlen(point)-1;j++)

{

while(point[j]!

='|'&&point[j]!

='\0')

temp[m++]=point[j++];

left[count]=ch;

memcpy(right[count],temp,m);

right[count][m]=ch;

right[count][m+1]='\0';

m=0;

count++;

if(point[j]=='|')

{

n=j+1;

break;

}

}

}

else

{/*如果'|'后的首符号和左部不同*/

left[count]=ch;

right[count][0]='^';

right[count][1]='\0';

count++;

for(j=n;j<=strlen(point)-1;j++)

{

if(point[j]!

='|')

temp[m++]=point[j];

else

{

left[count]=point[0];

memcpy(right[count],temp,m);

right[count][m]=ch;

right[count][m+1]='\0';

printf("count=%d",count);

m=0;

count++;

}

}

left[count]=point[0];

memcpy(right[count],temp,m);

right[count][m]=ch;

right[count][m+1]='\0';

count++;

m=0;

}

}

}

/*******************************************

分解不含有左递归的产生式

********************************************/

voidnon_re(char*point)

{

intm=0,j;

chartemp[20];

for(j=3;j<=strlen(point)-1;j++)

{

if(point[j]!

='|')

temp[m++]=point[j];

else

{

left[count]=point[0];

memcpy(right[count],temp,m);

right[count][m]='\0';

m=0;

count++;

}

}

left[count]=point[0];

memcpy(right[count],temp,m);

right[count][m]='\0';

count++;

m=0;

}

/*******************************************

读入一个文法

********************************************/

chargrammer(char*t,char*n,char*left,charright[50][50])

{

charvn[50],vt[50];

chars;

charp[50][50];

inti,j,k;

printf("\n请输入文法的非终结符号串:

");

scanf("%s",vn);

getchar();

i=strlen(vn);

memcpy(n,vn,i);

n[i]='\0';

printf("请输入文法的终结符号串:

");

scanf("%s",vt);

getchar();

i=strlen(vt);

memcpy(t,vt,i);

t[i]='\0';

printf("请输入文法的开始符号:

");

scanf("%c",&s);

getchar();

printf("请输入文法产生式的条数:

");

scanf("%d",&i);

getchar();

for(j=1;j<=i;j++)

{

printf("请输入文法的第%d条(共%d条)产生式:

",j,i);

scanf("%s",p[j-1]);

getchar();

}

for(j=0;j<=i-1;j++)

if(p[j][1]!

='-'||p[j][2]!

='>')

{printf("\ninputerror!

");

validity=0;

return('\0');

}/*检测输入错误*/

for(k=0;k<=i-1;k++)

{/*分解输入的各产生式*/

if(p[k][3]==p[k][0])

recur(p[k]);

else

non_re(p[k]);

}

return(s);

}

/*******************************************

将单个符号或符号串并入另一符号串

********************************************/

voidmerge(char*d,char*s,inttype)

{/*d是目标符号串,s是源串,type=1,源串中的'^'一并并入目串;

type=2,源串中的'^'不并入目串*/

inti,j;

for(i=0;i<=strlen(s)-1;i++)

{

if(type==2&&s[i]=='^')

;

else

{

for(j=0;;j++)

{

if(j

break;

if(j==strlen(d))

{

d[j]=s[i];

d[j+1]='\0';

break;

}

}

}

}

}

/*******************************************

求所有能直接推出^的符号

********************************************/

voidemp(charc)

{/*即求所有由'^'推出的符号*/

chartemp[10];

inti;

for(i=0;i<=count-1;i++)

{

if(right[i][0]==c&&strlen(right[i])==1)

{

temp[0]=left[i];

temp[1]='\0';

merge(empty,temp,1);

emp(left[i]);

}

}

}

/*******************************************

求某一符号能否推出'^'

********************************************/

int_emp(charc)

{/*若能推出,返回1;否则,返回0*/

inti,j,k,result=1,mark=0;

chartemp[20];

temp[0]=c;

temp[1]='\0';

merge(empt,temp,1);

if(in(c,empty)==1)

return

(1);

for(i=0;;i++)

{

if(i==count)

return(0);

if(left[i]==c)/*找一个左部为c的产生式*/

{

j=strlen(right[i]);/*j为右部的长度*/

if(j==1&&in(right[i][0],empty)==1)

return

(1);

elseif(j==1&&in(right[i][0],termin)==1)

return(0);

else

{

for(k=0;k<=j-1;k++)

if(in(right[i][k],empt)==1)

mark=1;

if(mark==1)

continue;

else

{

for(k=0;k<=j-1;k++)

{

result*=_emp(right[i][k]);

temp[0]=right[i][k];

temp[1]='\0';

merge(empt,temp,1);

}

}

}

if(result==0&&i

continue;

elseif(result==1&&i

return

(1);

}

}

}

/*******************************************

判断读入的文法是否正确

********************************************/

intjudge()

{

inti,j;

for(i=0;i<=count-1;i++)

{

if(in(left[i],non_ter)==0)

{/*若左部不在非终结符中,报错*/

printf("\nerror1!

");

validity=0;

return(0);

}

for(j=0;j<=strlen(right[i])-1;j++)

{

if(in(right[i][j],non_ter)==0&&in(right[i][j],termin)==0&&right[i][j]!

='^')

{/*若右部某一符号不在非终结符、终结符中且不为'^',报错*/

printf("\nerror2!

");

validity=0;

return(0);

}

}

}

return

(1);

}

/*******************************************

求单个符号的FIRST

********************************************/

voidfirst2(inti)

{/*i为符号在所有输入符号中的序号*/

charc,temp[20];

intj,k,m;

c=v[i];

charch='^';

emp(ch);

if(in(c,termin)==1)/*若为终结符*/

{

f

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1