编译原理--LL(1)分析法实验C++

一、实验项目要求

1.实验目的

根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对预测分析LL(1)分析法的理解。

2.实验要求

对下列文法,用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

输出的格式如下:

(1)LL(1)分析程序,编制人:姓名,学号,班级

(2)输入一以#结束的符号串(包括+—*/()i#):在此位置输入符号串

(3)输出过程如下: 

步骤

分析栈

剩余输入串

所用产生式

1

E

i+i*i#

E->TG

(4)输入符号串为非法符号串(或者为合法符号串)

备注:

(1)在“所用产生式”一列中如果对应有推导则写出所用产生式;如果为匹配终结符则写明匹配的终结符;如分析异常出错则写为“分析出错”;若成功结束则写为“分析成功”。

(2)在此位置输入符号串为用户自行输入的符号串。

(3)上述描述的输出过程只是其中一部分的。

注意:

1.表达式中允许使用运算符(+-*/)、分割符(括号)、字符i,结束符#;

2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);

二、理论分析或算法分析

1.模块设计:将程序分成合理的多个模块(函数),每个模块做具体的同一事情。

2.写出(画出)设计方案:模块关系简图、流程图、全局变量、函数接口等。

3.程序编写

(1)定义部分:定义常量、变量、数据结构。

(2)初始化:设立LL(1)分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等);

(3)控制部分:从键盘输入一个表达式符号串;

(4)利用LL(1)分析算法进行表达式处理:根据LL(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。

三、实验方法

程序流程图如图所示:

编译原理--LL(1)分析法实验C++_第1张图片

四、实验结果分析

实验结果图

编译原理--LL(1)分析法实验C++_第2张图片

编译原理--LL(1)分析法实验C++_第3张图片

遇到的问题

(1)遇到如图所示的问题

编译原理--LL(1)分析法实验C++_第4张图片

解决办法

(1)在程序最前面加#define _CRT_SECURE_NO_WARNINGS后可以解决;

在本次实验中,不仅使我编译原理的知识更加巩固,而且可以使理论与实践相结合,更好的掌握所学知识。我也发现自己的不足之处,以后会多加改正。

五、代码

#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
char A[20];/*分析栈*/
char B[20];/*剩余串*/
char v1[20] = { 'i','+','-','*','/','(',')','#' };/*终结符  */
char v2[20] = { 'E','G','T','S','F' };/*非终结符   */

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

typedef struct type/*产生式类型定义      */
{
	char origin;/*大写字符  */
	char array[5];/*产生式右边字符 */
	int length;/*字符个数      */
}type;

type e, t, g, g1, g2, s, s2, s1, f, f1;/*结构体变量  */
type C[10][10];/*预测分析表      */

void print()/*输出分析栈  */
{
	int a;/*指针*/
	for (a = 0; a <= top + 1; a++)
		printf("%c", A[a]);
	printf("\t\t");
}/*print*/

void print1()/*输出剩余串*/
{
	int j;
	for (j = 0; j < b; j++)/*输出对齐符*/
		printf(" ");
	for (j = b; j <= l; j++)
		printf("%c", B[j]);
	printf("\t\t\t");
}/*print1*/

void main()
{
	int m, n, k = 0, flag = 0, finish = 0;
	char ch, x;
	type cha;/*用来接受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;
	g1.origin = 'G';
	strcpy(g1.array, "-TG");
	g1.length = 3;
	g2.origin = 'G';
	g2.array[0] = '^';
	g2.length = 1;
	/
	s.origin = 'S';
	strcpy(s.array, "*FS");
	s.length = 3;
	s1.origin = 'S';
	strcpy(s1.array, "/FS");
	s1.length = 3;
	s2.origin = 'S';
	s2.array[0] = '^';
	s2.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 <= 5; n++)
			C[m][n].origin = 'N';/*全部赋为空*/

   /*填充分析表*/
//char v1[20]={'i','+','-','*','/','(',')','#'};/*终结符  */
//char v2[20]={'E','G','T','S','F'};/*非终结符   */

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

	C[1][1] = g; C[1][2] = g1; C[1][3] = C[1][4] = C[1][7] = g2;

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

	C[3][1] = C[3][2] = s2; C[3][3] = s; C[3][4] = s1; C[3][6] = C[3][7] = s2;

	C[4][0] = f1;     C[4][5] = f;
	printf("LL(1)分析程序,编制人:孙志英,27号,1920542班\n");
	printf("输入一以#结束的符号串(包括+ - * / () i #):");
	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("acc!\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 < cha.length; 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*/

你可能感兴趣的:(汇编实验,c++)