编译原理 LL1文法分析器 实验二 (详细代码) 左递归&First&Follow&Select&预测分析表

本文档详述了LL(1)分析器的实验要求,包括简单和高要求的文法分析。介绍了如何构造First、Follow、Select集合,预测分析表,并提供了去除左递归、First集和Follow集的计算方法。此外,还展示了固定文法和任意文法的运行示例,以及相关代码实现。
摘要由CSDN通过智能技术生成

LL(1)分析器 实验二

实验要求

简单要求:

至少做到对下列已知的文法,用LL(1)分析法对任意输入的符号串进行分析:

(1)E->TG

(2)G->+TG

(3)G->ε

(4)T->FS

(5)S->*FS

(6)S->ε

(7)F->(E)

(8)F->I

高要求:

1、手动输入文法

2、显示文法的非终结符的Follow集

3、显示规则的可选集合

3、构造预测分析表

4、对任意输入的符号串进行分析

记号和规定

  • 空串:$
  • 符号栈终止符:#
  • 规定第一个产生式的左边那个非终结符就是开始符号

简单要求的固定文法(无左递归)

(1)E->TG

(2)G->+TG

(3)G->ε

(4)T->FS

(5)S->*FS

(6)S->ε

(7)F->(E)

(8)F->I

First Follow Select 集合

非终结符 First集 Follow集 Select集
E ( I # ) ( I
T ( I + # ) ( I
G + ε # ) + # )
F ( I + * # ) ( I
S * ε + # ) * + # )

产生式对应的SELECT集

非终结符 产生式 Slect集
E E->TG ( I
T T->FS ( I
G G->+TG +
G G->ε # )
S S->*FS *
S S->ε + # )
F F->(E) (
F F->I I

分析表

I + * #
E TG TG synch synch
T FS FS synch synch synch
G +TG ε ε
F (E) I synch synch synch synch
S ε *FS ε ε

简单要求(固定文法递归的预测分析)

在主函数中构造一个RecursionSimple对象调用run方法即可运行

运行示例

[递归式固定文法]请输入需要分析的字符串:
I
[递归式固定文法]*****输入的字符串符合该文法*****success*****
[递归式固定文法]请输入需要分析的字符串:
***
[递归式固定文法]#####输入的字符串符不合该文法#####error#####
[递归式固定文法]请输入需要分析的字符串:
(I)
[递归式固定文法]*****输入的字符串符合该文法*****success*****

头文件 RecursionSimple.h

#pragma once

#include<iostream>
using namespace std;


//简单的递归版本 固定文法 
class RecursionSimple{
	public:
		static const string name;
		static enum over{Run,Error,Success};
		int isOver;
		char cur;
		int len;
		int pos;//当前指向的字符位置
		string text;//需要分析的文本

		//文法函数
		void E();
		void T();
		void G();
		void S();
		void F();

		//执行函数
		void run();
		//读入数据 在末尾插入#
		void cinData();
		//输入的字符串符合文法
		void success();
		//输入的内容不符合文法处理函数
		void error();
		//获取下一个字符 如果已经到了末尾则执行 error()
		void next();
		//输出结果
		void coutResult();


};


源文件 RecursionSimple.cpp

#include "RecursionSimple.h"

#define IS_OVER if(isOver!=Run)return;

const string RecursionSimple::name = "[递归式固定文法]";

void RecursionSimple::E(){
	IS_OVER
	T();
	G();
}

void RecursionSimple::T(){
	IS_OVER
	F();
	S();
}

void RecursionSimple::G(){
	IS_OVER
	if(cur == '+'){
		next();
		T();
		G();
	} else if(cur != '+' && cur != ')' && cur != '#')error();
}

void RecursionSimple::S(){
	IS_OVER
	if(cur == '*'){
		next();
		F();
		S();
	} else if(cur != '+' && cur != ')' && cur != '#')error();
}

void RecursionSimple::F(){
	IS_OVER
	if(cur == '('){
		next();
		E();
		if(cur == ')')next(); else error();

	} else if(cur == 'I'){
		next();
	} else error();
}

void RecursionSimple::run(){
	cout << "文法:\n" << "E->TG\n" << "G->+TG\n" << "G->ε\n" << "T->FS\n" << "S->*FS\n" << "S->ε\n" << "F->(E)\n" << "F->I\n";
	cinData();//读入数据 并初始化
	next();//获取第一个字符
	E();//分析开始(首个非终结符函数)
	if(cur == '#')success();
	else error();
	coutResult();//输出结果
}

void RecursionSimple::cinData(){
	cout << name << "请输入需要分析的字符串:" << endl;
	cin >> text;
	text += '#';
	pos = 0;
	isOver = false;
	len = text.length();
}

void RecursionSimple::success(){
	isOver = Success;
}

void RecursionSimple::error(){
	isOver = Error;
}

void RecursionSimple::next(){
	if(pos < len){
		cur = text[pos++];
		return;
	}
	error();
}

void RecursionSimple::coutResult(){
	if(isOver==Success)	cout << name << "*****输入的字符串符合该文法*****success*****" << endl;
	else cout << name << "#####输入的字符串符不合该文法#####error#####" << endl;
}



高要求(任意文法非递归的预测分析)

  1. 读入文法
  2. 确定终结符与非终结符
  3. 去除左递归
  4. First集 Follow集
  5. 判断是否为LL(1)文法(First与Follow元素不相交)
  6. Select集
  7. 预测分析表
  8. 分析

解析

  1. 读入文法: A -> @B a | c | $

    • 先输入左边 (在这里输入含有 # 的会结束文法输入)
    • 再输入右边 (同时输入各种可能 用 | 隔开 非终结符要在前面加@ ,#号结束本次右边输入)
    • 不可以包含下划线
    • 包含$的将自动转换为$单个字符
  2. 确定终结符与非终结符

  3. 去除左递归

    • 先将间接左递归转换为直接左递归
    • 将所有直接左递归消除
    • 删除所有不可达的产生式
  4. First集 Follow集

    • First集:
      • 遍历每一个左部为x的产生式
      • 如果产生式右部第一个字符为终结符,则将其计入左部非终
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值