目标任务
实现 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;
}