编译原理实验:LL(1)文法

目标任务
实现 LL(1)分析中控制程序(表驱动程序);完成以下描述算术表达式的 LL(1)文法的 LL(1)分析程序。
    G[E]: E→TE'
    E'→ATE' |ε
    T→FT'
    T'→MFT' |ε
    F→ (E)|i
    A→+|-
    M→*|/
说明:终结符号 i 为用户定义的简单变量,即标识符的定义。

// Compiler3.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <string>
#include <stack>
#include <iostream>

using namespace std;

string LL1_table[7][8];
char Vn[7] = {'E','X','T','Y','F','A','M'};  //非终结符,E'转化为X,T'转化为Y
char Vt[8] = {'i','+','-','*','/','(',')','#'};  //终结符

int find_Vn(char s)  //查找非终结符
{
	for (int i = 0; i < 7; i++)
	{
		if (Vn[i] == s)
			return i;
	}
	return -1;
}
int find_Vt(char c)  //查找终结符
{
	for (int i = 0; i < 8; i++)
	{
		if (Vt[i] == c)
		{
			return i;
		}
	}
	return -1;
}
void zaobiao() 
{
	for (int i = 0; i < 7; i++) 
		for (int j = 0; j < 8; j++)
		{
			LL1_table[i][j] = "";
		}
	LL1_table[0][0] = "E→TX";
	LL1_table[0][5] = "E→TX";
	LL1_table[1][1] = "X→ATX";
	LL1_table[1][2] = "X→ATX";
	LL1_table[1][6] = "E→";
	LL1_table[1][7] = "E→";
	LL1_table[2][0] = "T→FY";
	LL1_table[2][5] = "T→FY";
	LL1_table[3][1] = "Y→";
	LL1_table[3][2] = "Y→";
	LL1_table[3][3] = "Y→MFY";
	LL1_table[3][4] = "Y→MFY";
	LL1_table[3][6] = "Y→";
	LL1_table[3][7] = "Y→";
	LL1_table[4][0] = "F→i";
	LL1_table[4][5] = "F→(E)";
	LL1_table[5][1] = "A→+";
	LL1_table[5][2] = "A→-";
	LL1_table[6][3] = "M→*";
	LL1_table[6][4] = "M→/";
}

/*
测试用例1:
12, i
21, +
12, c
32, /
12, i
*/
/*
测试用例2:
28, (
12, i
22, -
12, i
29, )
23, *
28, (
12, i
21, +
12, i
29, )
*/

int main()
{
	char input[50];  //输入串
	char read[10];  //读取文件
	FILE *fp;
	fp = fopen("text.txt", "r+");
	int num = 0;
	while (fgets(read, 10, fp) != NULL)
	{
		int i;
		printf("%s", read);
		for (i = 0; i < 10; i++)
			if (read[i] == ',')
			{
				break;
			}
		input[num] = read[i + 2];
		num++;
	}
	input[num] = '#';
	input[num + 1] = '\0';
	printf("\n表达式为:%s\n", input);
//	cin >> input;  //输入需要匹配的表达式
	stack<char> a;
	a.push('#');
	a.push('E');
	zaobiao();
/*	for (int i = 0; i < 7; i++)  输出LL(1)表
	{
		for (int j = 0; j < 8; j++)
		{
			if (LL1_table[i][j] != "")
				cout << " " << LL1_table[i][j] << " ";
			else
				cout << "        ";
		}
		cout << endl;
	}*/

	int tag = 0;

	while (!empty(a))
	{	
		if (isupper(a.top())) //非终结符号
		{
			int x = find_Vn(a.top());
			int y = find_Vt(input[tag]);
			if ((x != -1) && (y != -1) && (LL1_table[x][y] != ""))
			{
				cout << "使用规则" << LL1_table[x][y] << endl;
				cout<<a.top()<<"出栈,";  //出栈
				a.pop();
				for (int tt = LL1_table[x][y].length()-1; tt > 0; tt--)
				{
					if (int(LL1_table[x][y][tt]) == -6)  //箭头
						break;
					
					cout << LL1_table[x][y][tt] << "入栈 ";
					a.push(LL1_table[x][y][tt]);	
				}
				cout << endl;
			}
			else
			{
				cout << "没有可以匹配的规则,不能识别!出错!" << endl;
				return 0;
			}
		}
		else //终结符号
		{
			if (a.top() == input[tag])
			{
				cout << "识别" << a.top()<<",退栈" <<endl;
				tag++;
				a.pop();
			}
			else
			{
				cout << "不能识别 "<<a.top()<<" !出错!" << endl;
				return 0;
			}
		}
	}
	cout << "成功匹配!"<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35014850/article/details/81145731