姓名 **
学号 **
班级 **
完成日期 **
1.实验目的
加深对语法分析器工作过程的理解;加强对预测分析法实现语法分析程序的掌握;能够采用一种编程语言实现简单的语法分析程序;能够使用自己编写的分析程序对简单的程序段进行语法翻译。
2.实验要求
1.对语法规则有明确的定义;
2.编写的分析程序能够对实验一的结果进行正确的语法分析;
3.对于遇到的语法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成语法分析过程;
4.实验报告要求用文法的形式对语法定义做出详细说明,说明语法分析程序的工作过程,说明错误处理的实现。
3.实验原理
对文法G进行语法分析,文法G如下所示:
*0. S→a */
*1. S→^
*2. S→(T)
*3. T→SW *
*4. W→,SW
*5. W→ε;
4.软件设计与编程
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char str[100]; //存储待分析的句子
const char T[ ] = "a^(),#"; //终结符,分析表的列符
const char NT[ ] = "STW"; //非终结符,分析表的行符
/*指向产生式右部符号串*/
const char *p[] = {
/*0. S→a */ "a",
/*1. S→^ */ "^",
/*2. S→(T) */ "(T)",
/*3. T→SW */ "SW",
/*4. W→,SW */ ",SW",
/*5. W→ε; */ ""
};
//设M[i][j]=x,通过p[M[i][j]]=p[x]获取右部符号串。
const int M[][6] = {
/* a ^ ( ) , # */
/*S*/ { 0, 1, 2, -1, -1, -1 },
/*T*/ { 3, 3, 3, -1, -1, -1 },
/*W*/ { -1, -1,-1, 5, 4, -1 }
};
void init()//输入待分析的句子
{
printf("请输入待分析的句子(以$结束):\n");
scanf("%s",str);
}
int lin(char c);//非终结符转换为行号
int col(char c);//终结转换为列号
bool isNT(char c);//isNT判断是否是非终结符
bool isT(char c);//isT判断是否是终结符。
void main(void)
{
int i,j=0;
int flag=1,flag2=0;
char A; //设置指示句子的当前字符
char stack[20]= {'#','S'}; //栈赋初值
int top = 1 ; //设置栈顶指针
char X = ' ' ; //存储栈顶字符
init();
A=str[0];
printf("\t步数\t分析栈\t输入串\t所用规则\n"); //在屏幕上输出列表标题
while ( 1 )
{
printf("\n\t(%d)\t",++j); //输出当前执行步数
for ( i = 0 ; i <= top ; i++ ) //输出当前栈的内容(出栈前)
{
printf("%c",stack[i]);
}
printf("\t");
for ( i = flag-1 ; str[i]!='$' ; i++ )
{
printf("%c",str[i]);
}
if(flag2==1)
{
printf("\t%d",M[ lin(X) ][col(A)]);
flag2=0;
}
//出栈
X = stack[top--] ;
if (X=='#')//是结束符
{
if (X==A)//是结束符
{
printf("\tAcc\n");
}
else printf("\tERROR\n");
break;
}
else if (isT(X))//是终结符
{
A=str[flag++];
}
else if (isNT(X))//是否是非终结符
{
flag2=1;
//逆序入栈
for( i = strlen( p[ M[ lin(X) ][col(A)] ] ) - 1; i >= 0; i--)
{
stack[++top] = *(p[M[lin(X)][col(A)]] + i ) ;
}
}
else
{
printf("Error in main()>%c\n",X);
exit(0);
}
}
}
int lin(char c)
{
for(int i = 0; i < (int)strlen(NT); i ++ )
{
if (c == NT[i])
{
return i ;
}
}
printf("Error in lin()>%c\n",c);
exit(0) ;
}
int col(char c)
{
for (int i=0; i<(int)strlen(T); i ++ )
{
if (c == T[i]) return i;
}
printf("Error in col()>%c\n",c);
exit(0);
}
bool isNT(char c) //是否是非终结符
{
for (int i = 0; i < (int)strlen(NT); i ++ )
{
if (c==NT[i])
return true;
}
return false;
}
bool isT(char c) //是否是终结符(不包括'#')
{
for (int i = 0; i < (int)strlen(T) - 1; i ++ )
{
if (c == T[i])
{
return true;
}
}
return false;
}
5.程序测试结果
课 程 编译原理 实验名称 实验四 LR(1)分析法
一. 实验目的
1.掌握LR(1)分析法的基本原理;
2.掌握LR(1)分析表的构造方法;
3.掌握LR(1)驱动程序的构造方法。
二. 实验内容及要求
根据某一文法编制调试LR(1)分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对LR(1)分析法的理解。
对下列文法,用LR(1)分析法对任意输入的符号串进行分析:
(0)E->S
(1)S->BB
(2)B->aB
(3)B->b
程序输入一以#结束的符号串(包括a、b、#),如:abb#。输出过程如下:
三. 实验过程及结果
(说明:实验结果可以是运行画面的抓屏,抓屏图片要尽可能的小。)
实验代码:
#include<stdio.h>
#include<string.h>
char *action[10][3]={"S3#","S4#",NULL, /*ACTION表*/
NULL,NULL,"acc",
"S6#","S7#",NULL,
"S3#","S4#",NULL,
"r3#","r3#",NULL,
NULL,NULL,"r1#",
"S6#","S7#",NULL,
NULL,NULL,"r3#",
"r2#","r2#",NULL,
NULL,NULL,"r2#"};
int goto1[10][2]={
1,2, /*GOTO表*/
0,0,
0,5,
0,8,
0,0,
0,0,
0,9,
0,0,
0,0,
0,0};
char vt[3]={'a','b','#'}; /*存放非终结符*/
char vn[2]={'S','B'}; /*存放终结符*/
char *LR[4]={"E->S#","S->BB#","B->aB#","B->b#"};/*存放产生式*/
int a[10];
char b[10],c[10],c1;
int top1,top2,top3,top,m,n;
void main(){
int g,h,i,j,k,l,p,y,z,count;
char x,copy[10],copy1[10];
top1=0;top2=0;top3=0;top=0;
a[0]=0;y=a[0];b[0]='#';
count=0;z=0;
printf("请输入表达式\n");
/*输出状态栈、输出符号栈、输出输入串*/
do{
scanf("%c",&c1);
c[top3]=c1;
top3=top3+1;
}while(c1!='#');
printf("步骤\t状态栈\t\t符号栈\t\t输入串\t\tACTION\tGOTO\n");
do{
y=z;m=0;n=0; /*y,z指向状态栈栈顶*/
g=top;j=0;k=0;
x=c[top];
count++;
printf("%d\t",count);
while(m<=top1){ /*输出状态栈*/
printf("%d",a[m]);
m=m+1;
}
printf("\t\t");
while(n<=top2){ /*输出符号栈*/
printf("%c",b[n]);
n=n+1;
}
printf("\t\t");
while(g<=top3){ /*输出输入串*/
printf("%c",c[g]);
g=g+1;
}
printf("\t\t");
while(x!=vt[j]&&j<=2) j++;
if(j==2&&x!=vt[j]){
printf("error\n");
return;
}
if(action[y][j]==NULL){
printf("error\n");
return;
}
else
strcpy(copy,action[y][j]);
if(copy[0]=='S'){ /*处理移进*/
z=copy[1]-'0';
top1=top1+1;
top2=top2+1;
a[top1]=z;
b[top2]=x;
top=top+1;
i=0;
while(copy[i]!='#'){
printf("%c",copy[i]);
i++;
}
printf("\n");
}
if(copy[0]=='r'){ /*处理归约*/
i=0;
while(copy[i]!='#'){
printf("%c",copy[i]);
i++;
}
h=copy[1]-'0';
strcpy(copy1,LR[h]);
while(copy1[0]!=vn[k]) k++;
l=strlen(LR[h])-4;
top1=top1-l+1;
top2=top2-l+1;
y=a[top1-1];
p=goto1[y][k];
a[top1]=p;
b[top2]=copy1[0];
z=p;
printf("\t");
printf("%d\n",p);
} }
while(action[y][j]!="acc");
printf("acc\n");
getchar();
}
截屏如下:
四. 实验中的问题及心得
同前面一样。实验加深了对LR(1)的理解,再接再厉吧
蛋白质与酶工程包埋法制备固定化微生物预实验报告实验目的1考察PYD是否与麦芽汁培养基一样可发酵酵母2考察干酵母活化与酵母培养过夜活…
预实验报告随机对一期学员进行调查并做了简单统计统计项目还未做全初步结果如下总人数85人其中男41女44按学历分为两组大专以上学历组…
计算机组成原理预做实验报告实验三存储器实验1实验目的和要求掌握静态随机存储器(6116)的工作原理及数据的读写方法。2实验设备JY…
统计学实验报告一姓名专业学号日期地点实验项目一描述性统计区间估计在EXCEL里的实现一实验目的1掌握利用EXCEL菜单进行数据的预…
重庆交通大学学生实验报告实验课程名称预测与决策开课实验室管理学院实验室学院年级数学专业班学生姓名龙凯学号开课时间20xx至20xx…
实验一系列缺口试样静拉伸实验及断口形貌观察1实验目的11了解材料在硬性应力状态和应力集中情况下的脆性趋向12了解试样缺口几何形状对…
神华亿利能源有限责任公司电厂试验报告编号GYSY20xx0072设备类型预防性试验试验设备试验日期主管审核单位签章神华亿利能源有限…
蛋白质与酶工程包埋法制备固定化微生物预实验报告实验目的1考察PYD是否与麦芽汁培养基一样可发酵酵母2考察干酵母活化与酵母培养过夜活…