【编译原理】LL(1)预测分析法

一、实验目的

LL(1)的含义:第一个L表明自顶向下分析是从左向右扫描输入串,第2个L表明分析过程中将使用最左推导,1表明只需向右看一个符号便可决定如何推导,即选择哪个产生式进行推导。

LL(1) 预测分析方法是确定的自顶向下的语法分析技术。本次实验的主要目的就是要加深对LL(1)预测分析法的理论和预测分析程序工作过程的理解。

二、实验要求

实现LL(1)预测分析法需要:

(1)判别文法是否为LL(1)文法。为此需要依次计算FIRST集、FOLLOW集和SELLECT集,根据SELLECT集可判断文法否为LL(1)文法。

(2)构造出分析表。根据SELLECT集和文法产生式构造出LL(1)分析表。

(3)进行句子分析。依据分析表判断出某句子是否为给定文法的句子。

为了降低实现的难度,本实验只要求实现步骤(3)的部分,即手动实现步骤(1)和(2),然后依据步骤(2)建立的分析表编写一个总控程序,实现的句子的分析。

程序应满足下列要求:

  1. 输入一个分析表,则输出预测分析的步骤。要求从输入文件(input.txt)和键盘中输入预测分析表,把结果输出到结果文件(result.txt)和显示器。

输出格式,如:

步骤         符号栈        输入串       所用产生式

0        #E          i1*i2+i3#               

1      #ET          i1*i2+i3#         T-->FT

…       ………        …………        …………

2、程序应能判断出某句子是否为该文法的句子。(结论)

3、准备多组测试数据存放于input.txt文件中,测试数据中应覆盖是文法的句子和不是文法的句子两种情况,测试结果要求以原数据与结果对照的形式输出并保存在result.txt中,同时要把结果输出到屏幕。

4、对于上面步骤(1)和(2)虽不需要通过程序来实现,但要求和测试数据一起在实验报告中写明。

5、提前准备

① 实验前,先编制好程序,上机时输入并调试程序。

  • 准备好多组测试数据(存放于文件input.txt中)。

三、实验过程:

  • 算法分析:
  • 初始化文法和预测分析表:
  • 首先,定义了文法的终结符集合 v1 和非终结符集合 v2。
  • 接着,创建了几个产生式对象,并将它们赋值给预测分析表 C 的不同位置。
  • 读取文件内容:
  • 从指定的文件中读取文本内容,并存储在变量 exps 中,每行表示一个要分析的文法。
  • 预测分析:
  • 对于每个读取的文法,先检查是否只包含终结符,然后开始进行预测分析。
  • 预测分析过程通过遍历输入字符并根据预测分析表中的产生式进行推导和匹配。
  • 复杂度分析:
  • 初始化阶段的时间复杂度取决于产生式数量和预测分析表的大小,通常为 O(n)。
  • 读取文件内容和预测分析的时间复杂度主要取决于文法的长度和输入长度,通常为 O(m), 其中 m 为文法或输入的长度。
  • 空间复杂度主要取决于预测分析表的大小和其他数据结构的空间占用,通常为 O(n^2)。
  • 优点:
  • 预测分析器具有较好的可读性和易于实现的特点。
  • 可以快速识别输入串是否符合给定文法规则。
  • 局限性:
  • 预测分析器需要提前构建预测分析表,对于大型文法或复杂语言可能会变得复杂。
  • 对于某些文法,可能需要使用其他类型的解析器来处理。
  • 程序流程图:

  • 程序代码:

class Type:def __init__(self):self.origin = 'N'  # 产生式左侧字符 大写字符self.array = ""  # 产生式右边字符self.length = 0  # 字符个数def init(self, a, b):self.origin = aself.array = bself.length = len(self.array)# 预测分析表C = [[Type() for _ in range(10)] for _ in range(10)]def is_terminator(c):# 判断是否是终结符v1 = "i+*()#"return c in v1def read_file(file_name):# 读文件res = []try:with open(file_name, 'r') as file:for line in file:res.append(line.strip())except Exception as e:print(e)return resdef init(exp):global ridx, len_exp, rest_stack, toptop = ridx = 0len_exp = len(exp)  # 分析串长度rest_stack = list(exp)def print_stack():# 输出分析栈和剩余栈global top, ridx, len_exp, analye_stack, rest_stackprint(''.join(analye_stack[:top + 1]), end=' '*(20-top))for i in range(ridx):print(' ', end='')for i in range(ridx, len_exp):print(rest_stack[i], end='')print('\t\t\t', end='')def analyze(exp):# 分析一个文法global ridx, len_exp, analye_stack, rest_stack, C, topinit(exp)k = 0analye_stack[top] = '#'top += 1analye_stack[top] = 'E'  # '#','E'进栈print("步骤\t\t分析栈 \t\t\t\t\t剩余字符 \t\t\t\t所用产生式 ")while True:ch = rest_stack[ridx]x = analye_stack[top]top -= 1  # x为当前栈顶字符print(str(k + 1).ljust(8), end='')if x == '#':print("分析成功!AC!\n")  # 接受returnif is_terminator(x):if x == ch:  # 匹配上了print_stack()print(ch, "匹配")ridx += 1  # 下一个输入字符else:  # 出错处理print_stack()print("分析出错,错误终结符为", ch)  # 输出出错终结符returnelse:  # 非终结符处理m = v2.find(x) if x in v2 else -1  # 非终结符下标n = v1.find(ch) if ch in v1 else -1  # 终结符下标if m == -1 or n == -1:  # 出错处理print_stack()print("分析出错,错误非终结符为", x)returnelif C[m][n].origin == 'N':  # 无产生式print_stack()print("分析出错,无法找到对应的产生式")  # 输出无产生式错误returnelse:  # 有产生式length = C[m][n].lengthtemp = C[m][n].arrayprint_stack()print(x, "->", temp)  # 输出所用产生式for i in range(length - 1, -1, -1):if temp[i] != '^':top += 1analye_stack[top] = temp[i]  # 将右端字符逆序进栈k += 1ExpFileName = "./input.txt"v1 = "i+*()#"  # 终结符v2 = "EGTSF"  # 非终结符e = Type()t = Type()g = Type()g1 = Type()s = Type()s1 = Type()f = Type()f1 = Type()e.init('E', "TG")t.init('T', "FS")g.init('G', "+TG")g1.init('G', "^")s.init('S', "*FS")s1.init('S', "^")f.init('F', "(E)")f1.init('F', "i")C[0][0] = C[0][3] = eC[1][1] = gC[1][4] = C[1][5] = g1C[2][0] = C[2][3] = tC[3][2] = sC[3][4] = C[3][5] = C[3][1] = s1C[4][0] = f1C[4][3] = fexps = read_file(ExpFileName)analye_stack = [' ' for _ in range(20)]for exp in exps:flag = Truefor ch in exp:if not is_terminator(ch):flag = Falsebreakif flag:analyze(exp)

  • 程序运行结果截图:

四、思考题:

请描述确定的自顶向下分析思想。

确定的自顶向下分析思想是指自顶向下地对输入串进行分析,在每一步都根据当前的符号栈顶符号和输入串的当前符号,在分析表中查找所用产生式,然后将产生式右部的符号依次推入符号栈中,直到符号栈中只剩下底符号和输入串中所有符号都被读入为止。如果在分析过程中遇到了分析表中没有对应的产生式,则分析失败。

五、实验小结: 

通过本次实验,我初步了解了LL(1)预测分析法的基本原理和实现方法,掌握了自顶向下分析思想。在实验过程中,我手动计算了文法的FIRST集、FOLLOW集和SELECT集,构造出了LL(1)分析表,并编写了一个总控程序,实现了句子的分析。在测试过程中,我准备了多组测试数据,覆盖了是文法的句子和不是文法的句子两种情况,测试结果以原数据与结果对照的形式输出并保存在result.txt中,同时输出到屏幕。通过本次实验,我深刻理解了LL(1)预测分析法的工作原理,并掌握了其实现方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/840735.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年【N1叉车司机】免费试题及N1叉车司机模拟试题

题库来源:安全生产模拟考试一点通公众号小程序 N1叉车司机免费试题考前必练!安全生产模拟考试一点通每个月更新N1叉车司机模拟试题题目及答案!多做几遍,其实通过N1叉车司机模拟考试题库很简单。 1、【多选题】《中华人民共和国特…

Java 反射效率

反射性能比正常new对象使用慢&#xff0c;今天我们来测试一下其中效率&#xff0c;以及探索优化。 测试方法main long start System.currentTimeMillis();for (int i0;i<10000000;i){// 调用如下不同case的测试方法分别创建一千万个对象&#xff0c;对比效率}long end Sys…

第三讲 栈、队列和数组 (1)

文章目录 第三讲 栈、队列和数组3.1 栈3.1.1 出栈元素的不同排列与卡特兰数3.1.2 栈的顺序表实现3.1.3共享栈3.1.4 栈的链表实现3.1.5 栈的两种实现的优缺点3.1.6 c中的栈( s t a c k stack stack)容器适配器3.1.7 栈的应用:star:3.1.7.1 **栈在括号匹配中的应用**3.1.7.2 **栈…

白话文docker-001

第一章&#xff1a;Docker简介 Docker的定义与历史 Docker 是一个开源的应用容器引擎&#xff0c;它允许开发者打包他们的应用以及应用的运行环境到一个可移植的容器中。Docker 首次发布于2013年&#xff0c;由 Solomon Hykes 和他领导的团队在 dotCloud 公司开发。Docker 的…

CSS布局和定位应用方案

目录 浮动布局绝对布局表格布局响应式布局弹性布局网格布局多栏布局浮动布局 CSS3浮动布局的核心在于使用float属性将元素移出文档流,通过左右浮动来排列元素,并结合clear属性或清除浮动技巧(如这里的伪元素法)来处理浮动带来的副作用。尽管浮动布局在某些简单布局中依然实…

m1系列芯片aarch64架构使用docker-compose安装rocketmq5.0以及运维控制台

之前看到 DockerHub 上有大佬制作了 m1 芯片, aarch64架构的 rocketmq 镜像, 所以就尝试的安装了下, 亲测可用: 一. docker-compose.yml 文件命令 volumes 挂载目录需要换成自己的目录 注意 depends_on 标签, broker 和 console 的 启动要晚于 namesrv, 因为 broker 需要注册…

MPLS LDP原理与配置

1.LDP基本概念 &#xff08;1&#xff09;LDP协议概述 &#xff08;2&#xff09;LDP会话、LDP邻接体、LDP对等体 &#xff08;3&#xff09;LSR ID 与LDP ID &#xff08;4&#xff09;LDP消息 ⦁ 按照消息的功能&#xff0c;LDP消息一共可以分为四大类型&#xff1a;发现…

JKI State Machine的特点与详细介绍

JKI State Machine是一种基于状态机的LabVIEW架构&#xff0c;由JKI公司开发。它广泛用于开发复杂的应用程序&#xff0c;提供了一种灵活且可扩展的结构&#xff0c;适用于多种任务的管理和执行。其设计目标是提高开发效率、代码可读性和可维护性。 2. 基本架构 JKI State Ma…

【算法题】520 钻石争霸赛 2024 全解析

都是自己写的代码&#xff0c;发现自己的问题是做题速度还是不够快 520-1 爱之恒久远 在 520 这个特殊的日子里&#xff0c;请你直接在屏幕上输出&#xff1a;Forever and always。 输入格式&#xff1a; 本题没有输入。 输出格式&#xff1a; 在一行中输出 Forever and always…

python给图片加上图片水印

python给图片加上图片水印 作用效果代码 作用 给图片加上图片水印图片水印的透明度&#xff0c;位置可自定义 效果 原始图片&#xff1a; 水印图片&#xff1a; 添加水印后的图片&#xff1a; 代码 from PIL import Image, ImageDraw, ImageFontdef add_watermark(in…

线性表——链式存储

单链表&#xff08;有头结点&#xff09; #include<stdio.h> #include<stdlib.h> //定义 typedef struct LNode{int data; //数据域 struct LNode *next; //指针域指向下一个结点&#xff0c;所以是 struct LNode类型 }LNode,*LinkList; //…

体检系统商业源码,C/S架构的医院体检系统源码,大型健康体检中心管理系统源码

体检系统商业源码&#xff0c;C/S架构的医院体检系统源码&#xff0c;大型健康体检中心管理系统源码 体检信息管理系统软件是对医院体检中心进行系统化和规范化的管理。系统从检前&#xff0c;检中&#xff0c;检后整个业务流程提供标准化以及精细化的解决方案。实现体检业务市…

C 语言实例 - 阶乘

一个正整数的阶乘&#xff08;英语&#xff1a;factorial&#xff09;是所有小于及等于该数的正整数的积&#xff0c;并且 0 的阶乘为 1。自然数 n 的阶乘写作 n!。 n!123…n。阶乘亦可以递归方式定义&#xff1a;0!1&#xff0c;1!1&#xff0c;n!(n-1)!n。 #include <st…

优化css样式的网站

一、按钮的css样式 https://neumorphism.io/#e0e0e0https://neumorphism.io/#e0e0e0 二、渐变样式 Fresh Background Gradients | WebGradients.com &#x1f48e;Come to WebGradients.com for 180 beautiful linear gradients in CSS3, Photoshop and Sketch. This collect…

【Linux+Docker】修改Docker容器中的hosts文件

1、进入容器bash docker exec -it <container_id> bash2、安装编辑器 2.1、安装vim apt-get updateapt-get install vim2.2、安装nano apt-get install nano3、编辑hosts文件 3.1、使用vim编辑 vi /etc/hosts3.2、使用nano编辑 nano /etc/hosts4、安装ping apt-get…

Git Core Lecture

1、Git 简介 官方介绍&#xff1a;Git is a fast distributed revision control system (Git 是一个快速的分布式版本控制系统) 2、Git Core Command 2.1 git init git 工程初始化&#xff0c;会在工作区 (working directory) 根目录中创建.git 目录 # 创建目录 $ mkdir git-i…

C# 深拷贝和浅拷贝

文章目录 1.深拷贝2.浅拷贝3.拷贝类4.浅拷贝的实现5.深拷贝实现5.1 浅拷贝对象&#xff0c;对引用类型重新一个个赋值5.2 反射实现5.3 利用XML序列化和反序列化实现 1.深拷贝 拷贝一个对象时&#xff0c;不仅仅把对象的引用进行复制&#xff0c;还把该对象引用的值也一起拷贝。…

MySQL数据库入门之视图、存储过程、触发器

一、视图&#xff1a; 1.1、视图是什么&#xff1f;怎么理解&#xff1f; 视图是从数据库的基本表&#xff08;或者视图&#xff09;导出的虚表&#xff08;数据库只放定义&#xff0c;它不实际存储数据&#xff0c;而是根据用户定义的SQL查询动态生成的结果集&#xff0c;具…

python期末作业:批量爬取站长之家的网站排行榜数据并保存,数据分析可视化

爬虫作业,含python爬取数据和保存文件,数据分析使用pyecharts做数据可视化 整体上分析网站的排名,直观看各个网站的热度。 数据分析之后大致的效果: 整个项目分为两个大的部分,第一部分就是抓取网站排名数据,然后保存为Excel、csv等格式,其次就是从文件中…

【30天精通Prometheus:一站式监控实战指南】第8天:redis_exporter从入门到实战:安装、配置详解与生产环境搭建指南,超详细

亲爱的读者们&#x1f44b;   欢迎加入【30天精通Prometheus】专栏&#xff01;&#x1f4da; 在这里&#xff0c;我们将探索Prometheus的强大功能&#xff0c;并将其应用于实际监控中。这个专栏都将为你提供宝贵的实战经验。&#x1f680;   Prometheus是云原生和DevOps的…