杭电编译原理实验-实验三-LL(1)语法分析实验

LL1语法分析实验

      • 实验目的
      • 实验内容
      • 函数定义
      • 程序流程图
      • 源代码
      • 测试用例

实验目的

  1. 了解 LL(1)语法分析是如何根据语法规则逐一分析词法分析所得到的单词,检查语法错误,即掌握语法分析过程。
  2. 掌握LL(1)语法分析器的设计与调试。

实验内容

针对CP语言中简单算术表达式文法G[E]:
   E→TE’
   E’→ATE’|ε
   T→FT’
   T’→MFT’ |ε
   F→(E) | i
   A → + | -
   M → * | /
  求解相应的FIRST、FOLLOW集,构造预测分析表,并编写LL(1)语法分析程序,并给出测试句子的分析过程。(注:如果有选做专题7关于LL(1)文法判断的同学,可以将专题7的部分整合到这个实验的前面,自动产生预测分析表,相当于把这个程序做成一个通用的LL(1)分析器)

  1. 输入:是词法分析输出的二元组序列,即任意简单算术表达式经过专题1程序输出后得到的结果。【上述文法中i即对应词法分析的标识符, ±*/分别对应词法分析得到的运算符】
  2. 处理:基于分析表进行 LL(1)语法分析,判断其是否符合文法。
  3. 输出:串是否合法。

函数定义

	int findH(char a) 	//在文法分析表中找到符号的对应行
	int findL(char b) 	//在文法分析表中找到符号的对应列
	int error(int i, int cnt, int len, char p[], char str[]) //报错
	void analyze(char str[], int len) //进行LL(1)语法分析
	int main() //语法分析主函数

程序流程图

杭电编译原理实验-实验三-LL(1)语法分析实验_第1张图片

源代码

#include
#include
#include
#include
#include
#include 
using namespace std;
int flag=0;
char LL1[50][50][100] = {
      {
     "::TX" ,"::TX","null" ,"null","null","null","null","null",},
                          {
     "::FY" ,"::FY","null" ,"null", "null","null","null","null",},
                          {
     "null" ,"null" ,"::~","::ATX","::ATX","null","null","::~", },
                          {
     "null" ,"null" ,"null"  ,"::+","::-","null","null","null", },
                          {
     "::i","::(E)","null" ,"null","null","null","null" ,"null", },
                          {
     "null","null","null" ,"null","null","::*","::/", "null",   },
                          {
     "null","null","::~" ,"::~","::~","::MFY","::MFY", "::~" ,  }, };

char H[200] = "ETXAFMY";
char L[200] = "i()+-*/$";
stack<char>cmp;

int findH(char a)
{
     
	for (int i = 0; i < 7; i++)//找到对应行
	{
     
		if (a == H[i])
		{
     
			return i;
		}
	}
	return -1;
}

int findL(char b)
{
     
	for (int i = 0; i < 8; i++)//找到对应列
	{
     
		if (b == L[i])
		{
     
			return i;
		}
	}
	return -1;
}

/*int error(int i, int cnt, int len, char p[], char str[])
{
	cout << cnt << "\t" << p << "\t";
	for (int q = i; q < len; q++)
	{
		cout << str[q];
	}
	cout << "\t报错" << endl;
	return len;
}*/

void analyze(char str[], int len)
{
     
	int cnt = 1;//输出Step
	int i = 0;
	char p[200] = "$E";//输出stack
	int pindex = 2;
	cout << "Step\tStack\tString\tRule" << endl;
	while (i < len)
	{
     
		int x, y;
		char ch = cmp.top();
		if (ch >= 'A'&&ch <= 'Z')
		{
     
			cmp.pop();
			x = findH(ch);
			y = findL(str[i]);
			if (x != -1 && y != -1)
			{
     
				int len2 = strlen(LL1[x][y]);
				if (strcmp(LL1[x][y], "null") == 0)
				{
     
				        cout << cnt << "\t" << p << "\t";
				        for (int q = i; q < len; q++)
				{
     
					cout << str[q];
				}
					cout << "\t出错,已忽略当前符号" << endl;
					cnt++;
					flag=1;
					cmp.push(ch);
                                        i=i+1;
                                continue;
				}
				cout << cnt << "\t" << p << "\t";
				if (p[pindex - 1] != '$')
				{
     
					p[pindex] = '\0';
					pindex--;
				}
				if (LL1[x][y][2] != '~')
				{
     
					for (int q = len2 - 1; q > 1; q--)
					{
     
						p[pindex++] = LL1[x][y][q];
						cmp.push(LL1[x][y][q]);//进栈
					}
				}
				else
				{
     
					p[pindex] = '\0';
					pindex;
				}
				for (int q = i; q < len; q++)
				{
     
					cout << str[q];//输出剩余输入串
				}
				cout << "\t" << ch << LL1[x][y] << endl;
			}
			else
			{
            cout << "\t出错,已忽略当前错误" << endl;
                                i=i+1;
				//i = error(i, cnt, len, p, str);//未找到,报错
				continue;
			}

		}
		else
		{
     
			if (ch == str[i])
			{
     
				cmp.pop();
				cout << cnt << "\t" << p << "\t";
				if (ch == '$'&&str[i] == '$')
				{
     
					cout << "$\t接受" << endl;
					return;
				}
				for (int q = i; q < len; q++)
				{
     
					cout << str[q];
				}
				cout << "\t" << ch << "匹配" << endl;
				pindex--;
				p[pindex] = '\0';
				i++;
			}
			else
			{
            cout << "\t出错,已忽略当前错误" << endl;
                                i=i+1;

				//i = error(i, cnt, len, p, str);//报错
				continue;
			}
		}
		cnt++;
	}
}

int main()
{
            string str1;
        ifstream Prewords("test.txt", ios::in);
        getline(Prewords, str1);
        char *str=(char*)str1.c_str();
	int len = strlen(str);
	cmp.push('$');
	cmp.push('E');
	analyze(str, len + 1);
	if(flag==1)
                cout<<"\t当前语句不合法"<<endl;
                else
                        cout<<"\t当前语句合法"<<endl;
	system("pause");
	return 0;
}

测试用例

注: X表示E’  Y表示T’  ~表示ε

1. i+i*i$
2. i++i$

杭电编译原理实验-实验三-LL(1)语法分析实验_第2张图片

你可能感兴趣的:(杭电编译原理实验)