Tomcat 端口映射 进程 高阶函数 arrays github redux merge stack devise Semantic UI Font Awesome java设计模式视频 electron安装 excel太长的文字隐藏 spark算法 mysql卸载重装 python编程练习题 windows查看进程命令 oracle分析函数 java数据结构 java数据类型 java接口怎么写 java抽象方法 java学习平台 java时间戳转换日期格式 java判断语句 java获取文件大小 java字符 shell编程学习 python 教程 sql综合利用工具 linux命令详解词典 ipad锁屏 烧饼修改器打不开 摩尔斯电码翻译器在线 陌陌电脑直播设置教程 瑞兹技能 画图怎么添加文字 ios删除描述文件
当前位置: 首页 > 学习教程  > 编程语言

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

2020/7/24 10:19:36 文章标签:

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() //语法分析主函数

程序流程图

在这里插入图片描述

源代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<stack>
#include <fstream>
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$

在这里插入图片描述


本文链接: http://www.dtmao.cc/news_show_50229.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?