Python-求First、Follow、select集合以及预测分析表和表驱动程序;

求文法符号的FIRST和FOLLOW集合(python编写) 求文法符号的FIRST和FOLLOW集合 自上而下分析:求FIRST、FOLLOW集 实验报告目录求文法符号的FIRST和FOLLOW集合预备介绍具体分析内容一:FIRST集合内容二:构造任何符号串的FIRST集合内容三:构造每一个非终结符的FOLLOW集合总结 预备介绍 在自上而下分析的过程中我们需要对指定文法 进行“消除二义性”、“消除左递归”、“消除回溯”等操作,而许多方面也涉及到文法符号的FIRST集和FOLLOW集的运用。 具体分析 FIRST集合和FOLLOW集合的求法在网上有很多,我也把 阅读详情

VT代表终结符集合
VN代表非终结符集合

一、求First集合:

求first集很简单

求解FIRST(X)
1)若X ∈ VT,则FIRST(X) = {X}。【终结符自己就是自己的FIRST集合】
2)若X ∈ VN,且有产生式X → a……, a ∈ VT,则a ∈ FIRST(X) 【非终结符,选第一个终结符加入】
3)若X ∈ VN,X → ε,则 ε ∈ FIRST(X) 【能直接推出ε,ε加入FIRST】
4)若X,Y1,Y2,……,Yn ∈ VN,而有产生式X → Y1,Y2,……,Yn。
当Y1,Y2,……,Y(i-1) 直接推出ε时,则FIRST(Y1) - ε, FIRST(Y2) - ε, …… , FIRST(Y(i-1) - ε) ,FIRST(Yi) 都包含在FIRST(X)中【中间的ε是不会加入进去的】
5)当4)中所有Yi 都推出 ε时,则最后的FIRST(X) = FIRST(Y1) ∪ FIRST(Y2) ∪ …… ∪ FIRST(Yn) ∪ {ε}

二、求Follow集合:

求follo集合比较麻烦,遇到很多坑点。
奈何老师东哥很严,再麻烦也得弄…

1)S是文法开始符号,初始化follow(S)= {  #  }
2)	D --+--> BAC        follow(A)+=first(C)/ @
3)如果上述产生式D--+-->BAC 中,存在C->@,即  D--+-->BA  ,那么还要进行follow(A)+=  follow(B)
坑点1:注意S --+-->BAC ,如果C能为空,那么要将其看成S --+-->BA ,S --+-->BAC两种情况
坑点2:
如果出现循环引用:follow(A)=follow(B) +…  而follow(B) = follow(A)这种情况:
原则上是要继续使用上述规则,直到每个Vn的follow集合不再变化为止,
然后让循环调用的follow集赋值为空,但具体很难办,就直接用下面的的做法:
如果遇到:S ---> BA,且S是开始符 ,
那么follow(A)={ # } 而不是 follow(A)=follow(S)

三、求Select集合:

A->B,A属于Vn,
若B不能推导出空,那么select(A->B) = first(B)
如果B经过有限次推导能推出空,那么那么select(A->B) = first(B) - 空  ∪ Follow(A)

四、预测分析表:

根据select集合来求

五、表驱动分析程序:

整体代码:

input.txt文件内容
E -> TA
A -> +TA
A -> @
T -> FB
B -> *FB
B -> @
F -> i
F -> (E)

```python
# !/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author : WangRay
# @Software: PyCharm
def getOriginData():
    tranformFunctionData = {}
    Vn = []
    Vt = []
    with open("input.txt", 'r+', encoding="utf-8") as f:
        temp = f.readlines()
    for ind,i  in enumerate(temp):
        t = i[:-1].split(" ") #去掉换行 E -> TA
        if ind == 0: # 默认第一个Vn是开始符
            S =  i[0]
        x = tranformFunctionData.get(t[0],None)
        if x :
            x.append(t[2])
            tranformFunctionData.update( { t[0] : x } )
        else:
            tranformFunctionData[ t[0] ] = [ t[2] ]  #加入 {E : [TA,]}
        if( 'A'<=t[0] <='Z'):
            Vn.append(t[0])
        else:
            Vt.append(t[0])
        for tx in t[2]:
            if( 'A'<= tx <='Z'):
                Vn.append(tx)
            else:
                Vt.append(tx)
    Vn = getOnly(Vn)
    Vt = getOnly(Vt)
    return (Vn,Vt,tranformFunctionData,S)
def getOnly(l):
    n = []
    for x in l:
        if x not in n :
            n.append(x)
    return n
class MyChart():
    def __init__(self, mystr):
        self.mstr = mystr  # 输入的句子
        self.Vn = []  # 非终结符
        self.Vt = []  # 终结符
        tranformFunctionData = {}
        self.S = None  # 开始符
        self.first = {}  # first集合,是一个map对象,元素是"V":{ }
        self.follow = {}  # follow集合,也是一个map对象
        self.select = {}  # select集合,也是一个map对象,每个对象key是Vn;Value是一个map={"产生式","Vt集合"},{ F : { "->i" : "i" , "->(E)":"(" }  }
        self.analysisTable = []
        self.initFirstAndFollow()
        self.getFollow(self.S)
        self.getselect()
        self.row = []
        self.column = []
        self.initAnalysisTableData()
        print("预测分析表:")
        for i in self.analysisTable:
            print(i)
        print()

    def doAnaysis(self):
        myStack = ["#", self.S]
        X = myStack[-1]
        ind = 0
        a = self.mstr[ind]
        ind += 1
        while myStack:
            if X in self.Vt:
                if X == a:
                    a = self.mstr[ind]
                    ind += 1
                    myStack.pop()
                    X = myStack[-1]
                else:
                    return "error,经判断" + self.mstr + "不是符合该文法的句子"
            else:
                if X == "#":
                    if X == a:
                        return "success,经判断" + self.mstr + "是符合该文法的句子"
                    else:
                        return "error,经判断" + self.mstr + "不是符合该文法的句子"
                else:
                    prod = self.getProd(X, a)
                    if prod == "#":  # 没有对应产生式
                        return "error,经判断" + self.mstr + "不是符合该文法的句子"
                    else:  # 存在对应产生式
                        myStack.pop()
                        temp = prod[:1:-1]
                        if temp != "@":
                            myStack.extend(temp)  #
                        X = myStack[-1]

    def getselect(self):
        for k in self.tranformFunctionData.keys():  # k是Vn,E A T B F
            for prod in self.tranformFunctionData.get(k):  # prod 是Vn k=F 对应的产生式["i","(E)"]
                # 对于一个k->prod,检查prod的组成元素Vn集合,能不能同时都变成@,
                if self.checkIfTranfToKong(prod) == 1:  # 等于1表示全都能变成@
                    # 若能:tempS = prod[0]的first集合除去空∪follow(k)
                    temps = self.first.get(prod[0]).replace("@", "") + self.follow.get(k)
                else:
                    # 否则:tempS = prod[0]的first集合
                    temps = self.first.get(prod[0])
                prodToTemps = self.select.get(k, None)
                if prodToTemps is None:
                    self.select.update({k: {"->" + prod: temps}})
                else:
                    self.select.get(k).update({"->" + prod: temps})

    def checkIfTranfToKong(self, prod):
        for i in prod:  # 遍历 (E) 的每一个Vn/Vt,但凡有一个是Vt(不是空)或者有一个Vn的first不包含@,那么返回-1
            if i == "@":
                continue
            if i in self.Vt:
                return -1
            elif "@" not in self.first.get(i):
                return -1
        return 1

    def initAnalysisTableData(self):
        self.row = self.Vn.copy()
        self.column = self.Vt.copy()
        self.column.remove("@")
        self.column.append("#")
        for tempVn in self.row:  # 拿到行标
            T = self.getRowColumnPrdo(tempVn)
            self.analysisTable.append(T)

    def getRowColumnPrdo(self, tempVn):
        T = []
        for tempVt in self.column:
            mp = self.select.get(tempVn)  # {'->+TA': '+', '->@': '#)'}
            flag = 0
            for tk in mp.keys():
                if tempVt in mp.get(tk):
                    T.append(tk)
                    flag = 1
            if flag == 0:
                T.append("#")
        return T

    def getProd(self, X, a):
        x = self.row.index(X)
        y = self.column.index(a)
        return self.analysisTable[x][y]

    def initFirstAndFollow(self):
        (self.Vn, self.Vt, self.tranformFunctionData, self.S) = getOriginData()
        for t in self.Vn + self.Vt:
            if t in self.Vt:
                self.first.update({t: t})
            else:
                self.first.update({t: None})
                self.follow.update({t: ""})
        for t in self.Vn + self.Vt:
            self.getFisrt(t)
        for t in self.Vn:
            self.follow.update({t: self.getFollow(t)})

    def getFollow(self, T):
        x = self.follow.get(T)
        if x != "": return x
        if T == self.S:
            tempFollow = "#"
        else:
            tempFollow = ""
        for prodFromLeft in self.tranformFunctionData.keys():  # 遍历所有的左部 "A","P"  。 tranformFunctionData为  { "A":["+E" , "@"]  ,"P": [ "(E)","a","b","^" ]  }
            for prodFromRight in self.tranformFunctionData.get(
                    prodFromLeft):  # 遍历每个左部能够产生的右部"aTCA","TE","ABT","a","@"   ===>>> ["+E" , "@"]  [ "(E)","a","b","^" ]
                ind = prodFromRight.find(T)
                mylen = len(prodFromRight)
                if ind != -1 and mylen >= 2:  # 产生式右部满足T -> ABC的形式
                    if (ind == mylen - 1):
                        tempFollow = self.restart(tempFollow, prodFromLeft, T)
                    else:
                        tempFollow += self.first.get(prodFromRight[ind + 1]).replace("@", "")  # 除去 @ 符号

                        if (ind == mylen - 2 and prodFromRight[mylen - 1] in self.Vn and "@" in
                                self.tranformFunctionData[prodFromRight[mylen - 1]]):
                            tempFollow = self.restart(tempFollow, prodFromLeft, T)  # 进行反复传送
        return "".join(sorted(list(set(tempFollow))))

    # 求follow的反复传送函数
    def restart(self, tempFollow, prodFromLeft, T):
        if T == prodFromLeft: return tempFollow  # 有些产生式可能是 T -> aT ,这个时候不要再follow(T) = follow(T)了,会死循环
        if self.follow.get(prodFromLeft) == "" and prodFromLeft == self.S:
            tempFollow += "#"
        else:
            tempFollow += self.getFollow(prodFromLeft)
        return tempFollow

    # 求first集合
    def getFisrt(self, T):
        '''
        # 注意如果 T -> AB , A如果能产生@,那么firstB也属于First(T)
        :param T: 终结符或者非终结符
        :return String :  T的first集,
        '''
        x = self.first.get(T, None)
        if x:
            return x
        else:  # 为空,求了First,更新了self.first,再返回其first集
            tempFirst = ""
            for prodForm in self.tranformFunctionData[T]:  # 遍历所有它的产生式右部 T -> ["F" , "Ta" , "(E)" , "a" , @ ]
                tempFirst += self.getFisrt(prodForm[0])
                if len(prodForm) >= 2 and prodForm[1] in self.Vn and prodForm[0] in self.Vn and '@' in \
                        self.tranformFunctionData[prodForm[0]]:
                    tempFirst += self.getFisrt(prodForm[1])
            self.first.update({T: tempFirst})
            return tempFirst


if __name__ == "__main__":
    mstr = "i+i*i#"
    print("待判断的句子为:", mstr)
    mc = MyChart(mstr)
    print(mc.doAnaysis())


【编译原理-实验-3】预测分析表一篇解决你所有问题(python版) 这篇文章是因为前一篇文章c++版好多缺陷,而选择用python实现词法分析器于语法分子整合,python操作便捷,对字符串处理灵活宽松,选择python,珍爱生命!!! c++版本: 编译原理预测分析表一篇解决你所有问题(c++版) 实验 预测分析表方法 一、实验目的 理解预测分析表方法的实现原理。 二、实验内容 编写一通用的预测法分析程序,要求有一定的错误处理能力,出错后能够使程序继续运行下... 阅读详情

相关推荐

语法分析之自上而下分析:根据文法构造预测分析表环节(用python编写)

根据文法构造预测分析表 自上而下分析:预测分析法的步骤一 实验报告目录根据文法构造预测分析表预备介绍具体分析总结 预备介绍 语法分析部分的自上而下分析有两个方法,一个是递归分析法,另一个就是预测分析法。预测分析法最重要的一个环节就是构造预测分析表。接下来介绍一下如何用python来构造一个文法的预测分析表。 具体分析 构造过程会用到求文法符号的FIRST集、FOLLOW集,或者求符号串的FIRST集合的算法,可以参考之前发的一篇文章 点击此处跳转 首先介绍一下预测分析表的结构,简单来说他就是一张表,表

x1Nge的博客 2431

Python求first 和follow 集

FIRST = {} FOLLOW = {} sentences = [ 'E->TG', 'G->+TG', 'G->-TG', 'G->ε', 'T->FS', 'S->*FS', 'S->/FS', 'S->ε', 'F->(E)', 'F->i',] #初始化 first 集 和follow集合字典的键值对中的 值 为空 ...

leechoy 3821

get_first.py

自上而下分析法,求每一个文法符号的FIRST集合,配合博客进行分析和处理。代码由python编写,可以自行“翻译”成别的语言。

编译原理-FIRST表-FOLLOW表-LL1表(含python代码)

问题描述 给出产生式文法,根据文法描述得出其FIRST集、FOLLOW集,若符合LL(1)文法,则求出其LL(1)表格。 算法设计 FIRST集设计 概念: FIRST集由终结符和ε组成。 求取FIRST集规则: 产生式左部的FIRST集取决于右部产生式的FIRST集。其中,非终结符和ε的FIRST集等于其本身。 产生式左部的FIRST集求取分为4种情况,其求取方法如下: 右部为单个字符时:左部FIRST集等于右部FIRST集 右部为多个字符时,执行以下算法: index为右部字符的坐标,index从开始字

CodeEggs的博客 1507

想发故障诊断论文?手把手教你用CWRU数据集复现第一个Baseline模型

本文提供了一份基于CWRU轴承数据集的故障诊断Baseline模型实战指南,手把手教你从数据准备到模型构建的全流程。通过详细的Python代码示例和学术级实验设计,帮助初学者快速复现第一个故障诊断模型,为发表高质量论文奠定基础。

weixin_28681255的博客 428

FreeCAD MCP实战:用自然语言驱动AI建模,效率提升10倍

MCP(Model Context Protocol)是一种让AI模型调用外部工具和数据的协议标准,通过标准化通信层解决AI与CAD软件之间的交互难题。其原理是向AI暴露工具清单,AI根据自然语言需求自动选择工具并填充参数。在工程实践中,这一技术显著降低了CAD建模门槛,将重复性操作从手动点击转为语音指令,适用于批量零件生成、参数化设计等场景。FreeCAD作为开源CAD,凭借开放的Python API和脚本化能力,成为落地MCP的理想平台。本文基于FreeCAD MCP的实操经验,分享环境搭建、自然语言建

weixin_31188927的博客 322

用python进行语法分析,第一步用python求出first集和follow集。

本文的中心思想就是定义好两个字典FIRST,FOLLOW集合,用这两个字典去装我们的FIRST集合与FOLLOW集合.后面就是定义相应的函数求解给定文法的FIRST集合与FOLLOW集合。这两个集合我们都进行了去重操作,把集合的重复元素给去了。其实还是应该说就是根据求FIRST集合与FOLLOW集合的原理去求,定义相应的函数,最后把结果放入相应的集合,去重!

weixin_61662887的博客 590

地瓜机器人RDK Studio使用入门教程

不知道大家在使用AI开发板的时候有没有遇到过板子官方镜像占据空间大难以保存,想要的时候找不到?官方示例项目久而久之便难以找寻?首次登陆开发板连接网络还需要准备显示器键盘鼠标外设繁杂?…为了解决平时开发过程中遇到的种种不便利问题,地瓜机器人创新的推出了RDK Studio这一官方开发者软件,使智能机器人开发迎来新纪元!通过这一软件极大降低了机器人的开发门槛,哪怕是零基础的用户亦可轻松上手RDK系列板卡!

xiongqi123123的博客 3426

求first、follow、select集,并判断是否为ll1文法,用python实现

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar

Bamboo9999的博客 2285

域控制器迁移后NETLOGON共享丢失的修复指南

本文详细解析了在Windows域控制器迁移后NETLOGON共享丢失的故障现象与修复方法。通过使用Dcdiag工具诊断,定位注册表键值SysVolReady异常及SCRIPTS目录缺失等核心原因,并提供了修改注册表、创建目录、重启Netlogon服务等逐步修复指南,帮助管理员快速恢复域用户登录功能,确保业务连续性。

weixin_29245767的博客 88

SAP ABAP BADI_FINS_ACDOC_POSTING_EVENTS 深度应用:KO88工单结算的凭证字段定制与财务数据增强

本文深入探讨了SAP ABAP中BADI_FINS_ACDOC_POSTING_EVENTS在KO88工单结算中的应用,详细解析了如何通过BADI实现财务凭证字段的定制与数据增强。文章提供了从结构扩展到BADI方法实现的完整步骤,包括性能优化建议和实际应用中的测试验证流程,帮助开发人员高效解决企业个性化财务需求。

weixin_26869081的博客 389

对编译原理中First、Follow、Select集的一些不算太抽象的理解

对编译原理中First、Follow、Select集的一些不算太抽象的理解 刚开始接触的时候非常懵,不知道是在算什么,在干什么,去询问大佬和老师是否有更生动的理解方式,但是他们都达成一致说反向理解(然而我还是没听懂) 趁着写课后作业的机会再翻了翻书本,看了书上例题,进行了预习回顾,研究了一些个人认为不算太差的适合普通人类大学牲理解的角度,在此记录 下面以一道例题作为例子,核心是通过一个树状推导结构来理解! 有一说一,可以不看上面这图,直接看下面的推导图即可,重在理解! 我们之前学过推导和归约,我们这里

qq_49666427的博客 1514

CUDA编程 - Nsight system & Nsight compute 的安装和使用 - 学习记录

在 cuda 编程中,经常会用到 Nsight system 和 Nsight compute 进行性能分析等,下面做个学习总结。本篇包括安装和常用分析思路总结,具体实践操作总结会放在下一篇博客。

点云算法工程师 1万+

求SELECT集,改写文法,写预测分析表

SELECT集和之前讲过的FIRST集和FOLLOW集有些不同。 给出文法如下: S->ABc A->a|ε B->b|ε 我们可以求FOLLOW(S)或者FOLLOW(ABc),同样也可以求FIRST(S),FIRST(ABc)。 但是不能求SELECT(S),SELECT(ABc)这种形式,这是不对的。应该写成SELECT(S->ABc)。 所以不同点就是,FOLLOW集和FIRST集是对产生式箭头的左部或右部进行求解;而SELECT集是对整个产生式进行求解。 同样,还是先讲.

此用户不懒,但懒得写简介 8553

Debezium系列之:深入理解 Debezium Topic的设置要求

Debezium系列之:配置 Debezium Topic

zhengzaifeidelushang的博客 1009

6、基于深度强化学习的无人机路径规划

本文研究了基于深度强化学习的无人机路径规划方法,提出了一种融合改进DQN算法与人工势场法的路径规划策略。通过设计合理的网络结构、状态空间、动作空间和奖励函数,结合ε-贪心策略进行动作选择,实现了无人机在复杂环境中的自主避障与目标导向飞行。仿真实验表明,该方法具有收敛速度快、实时性强和可操作性高等优点,能有效完成室内环境下的路径规划任务。文章还总结了算法优势,并对未来在连续动作、复杂环境适应及多无人机协同等方面的发展方向进行了展望。

web39explorer的博客 166

三、语法分析(1)自顶向下:First集、Follow集、Select集、LL(1)文法、表驱动LL(1)分析表、消除左递归、提取左公因子

左递归:文法中一个非终结符号A使得对某个串α,存在一个推导 A Aα,则称这个文法是左递归的。匹配成功的终结符号不会再被考虑,因此只需要记住句型的余下部分,以及尚未匹配的输入终结符号串。在实际的语法分析过程中并不一定会构造出相应的分析树,但是用分析树的概念可以方便解。从叶子 (输入串中的终结符号,将位于分析树的底端) 开始,向上到达根结点。自顶向下的语法分析技术不能处理左递归的情况,因此需要消除左递归,但是。b、从开始符号出发,不断进行上面的替换,就可以得到文法的不同句型。

m0_74161592的博客 1264

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

FIRST集、FOLLOW集 和 SELECT集

FIRST集、FOLLOW集 和 SELECT集 一、FIRST集 FIRST(A)为A的开始符或者首符号集。 1、定义: 设G=(VT,VN,S,P)是上下文无关文法 ,FIRST(α)={a|α能推导出aβ,a∈VT,α,β∈V*}    特别的,若α能推导出ε,则规定ε∈FIRST(α). 2、根据定义求解FIRST集(对每一文法...

DR的专栏 990

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

【编译原理】一篇搞定First集、Follow集与select集(超详细)

思考回溯算法的问题——随意选择文法产生式作为操作。 想要不是随便选择,而是有目的性的选择就需要 考察后面输入的值是什么。 这也就是为什么这类算法叫做预测分析(考察下一位是什么,然后预测哪个产生式可能性高)~~ 基本思想:采用深度优先策略构建解析树,每次为非终结符号选择适当的产生式,以避免回溯。具体实现上通过向前查看输入中的一个或多个尚未被匹配的终结符来选定产生式。 对于非左递归文法,因不再回溯所以速度更快;但是仍存在无法处理的文法(例如左递归文法)。 考虑通过向前查看一个输入符号就能用预测分析算法

十二月的猫 5027

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

自己动手写编译器:First 集合,Follow 集合和 Select 集合

本文介绍了编译原理中语法解析时,自动化生成语法解析表的若干基础概念

tyler_download的专栏 943

求解FIRST集合的2个步骤+求解FOLLOW集合的5个步骤(保证不会有遗漏!!)

实际上,我们在求解过程中将找推导这一过程变成找满足相应条件的产生式,就不会出错。

KI的博客 10万+

基于预测分析表法的语法分析程序

1.实验内容1、定义一个LL(1)文法,示例如(仅供参考)  G[E]:E →TE'     E'→+TE'|εT →FT'      T' → *FT'|εF → i|(E) 2、构造其预测分析表,如3、LL(1)文法的预测分析表的模型示意图 4、运行结果,示例如下2.实验设计分析2.1 实验设计思路    根据实验指导书和书本上的相关知识,实现算法。2.2 实验算法(1)输入文法,用字典存储(...

再走一步 1万+

如何求First集、Follow集和预测分析表

求First集:对每个非终结符,找出分别从它们开始能推出的所有的第一个终结符组成的集合 求Follow集:对每个非终结符,找出分别紧跟它们的所有第一个终结符或$组成的集合,例如 F --> ( E ) | id,E 后面紧跟了 ) ,所以它的Follow集里面一定有 ),Follow集最后一定要加上 $ 例如下面的文法 E --> T E' E' --> + T E' | ε T --> F T' T' --> * F T' | ε F --> ( E ) | id F

Doge的技术小屋 2065

python预测分析_python实现预测分析程序

import sysimport operatorimport copy#终结符terSymbol = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','+','-','*','/','(',')','^']#非终结符non_ter = ...

weixin_39855796的博客 591

first集和follow集的计算

纯属瞎写借鉴,我觉得很好懂,给那些不懂的人看计算FIRST集: ① 根据定义计算:  对每一文法符号X∈V 计算FIRST(X) (a) 若X∈VT,则FIRST(X)={X} (b) 若X∈VN,且有产生式X→a…,a∈VT, 则 a∈FIRST(X) (c) 若X∈VN,X→ε,则ε∈FIRST(X) (d) 若X, Y1,Y2,…,Yn都∈VN,且有产生式X→Y1 Y2 …

焱少的博客 2万+
上一篇: spring控制反转IOC总结
下一篇: 测试题目案例
wang__Ray
博客等级 码龄8年 59粉丝 17原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值