形式语言与自动机实验:消去空生成式,单生成式以及无用符号(JAVA)

题目概述

编写上下文无关文法的变换算法,用于消除文法中的空产生式、单产生式以及无用符号

算法解析

  • 消除空产生式
    空产生式的消除采用的方法是找到直接置空和间接置空的生成式,例如:
    S -> bA1 | A2 | A1
    A1 -> null | a
    那么A1为直接置空元素,S通过生成A1再置空那么为间接置空元素;
    通过遍历我们可以将直接置空和间接置空元素放入一个集合,下一步是替换元素,将替换情况用组合算出来再加入原生成式集合;
    bA1元素有两种组合方式,分别为b和bA1,所以替换为b | bA1, A1元素替换为A1 | null:
    S-> b | bA1 | A2 | A1 | null
    A1 -> a | null
    再次遍历消去null;
    S-> bA1 | A2 | A1 | b
    A1 -> a
    如果起始符置空则需要引入S1,所以可以得到:
    S1 -> null | S
    S-> bA1 | A2 | A1 | b
    A1 -> a

  • 消去单产生式
    单产生式的消除采用的方法是先找到单元素,例如:
    S -> A | aB
    A -> c | a
    B -> ab
    可以得到S - > A,A为单元素,把A集合中的元素和S集合做并集,可以得到S -> A | aB | c | a;重复操作,直至所有含单元素的生成式都经过并集;
    之后删去每个生成式的单元素即可;
    S -> aB
    A -> c | a
    B -> ab

  • 消去无用符号
    无用符号包括两部分,一部分是不可达符号,另一部分是非产生符号;
    产生符号指的是起始符生成式包含的非终止符,例如:
    S->Ab | B
    则A与B为产生符;
    可达符号指的是生成式中含有只含终结符的生成串,例如:
    S -> ab | A | C
    ab是只含终结符的串,所以S是可达符号;
    因此我们将无用符号通过条件遍历出来删除就可,记得含有无用符号的串都需要删除;

数据结构

这里我采用了JAVA中的hashmap进行生成式的存储,例如:
S -> Ab | B
A -> a | Bb
B -> b | aA
hashmap中的key是一个集合,存储生成式左端,则有key = {S,A,B},
hashmap中的value用 List< List < String > >来填充,例如:
外层List中含有生成式的右端,里层的List为单个元素组成的集合,一个 List< List < String > >具体表示为:
[[A,b],[B]]

一些小提醒

这个算法流程有大量的JAVA集合操作,因为数据结构的关系,遍历到每个单元素基本需要三层for循环,复杂度较高,而且由于需要边遍历边进行集合操作,元素的位置会改变会导致for循环失效报错,需要另辟蹊径,总得来说用JAVA写该程序需要耐心和细心。

代码网址

网络上大多公开的算法程序都是用python写的,python集合操作相当简单。
创作不易,我将JAVA版本开源,希望大家点赞支持一下博主的头发(hhh)。

https://gitcode.net/flag_wkx/experiment

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值