求文法符号的FIRST和FOLLOW集合(python编写)

求文法符号的FIRST和FOLLOW集合

  • 自上而下分析:求FIRST、FOLLOW集

预备介绍

在自上而下分析的过程中我们需要对指定文法 进行“消除二义性”、“消除左递归”、“消除回溯”等操作,而许多方面也涉及到文法符号的FIRST集和FOLLOW集的运用。

具体分析

FIRST集合和FOLLOW集合的求法在网上有很多,我也把我看到过的比较好的一种讲述方法呈现给大家参考,并且本文附带我自己编写的求两个集合的代码也供大家参考。

内容一:FIRST集合

首先我们了解一下FIRST集合的求法,对比了许多网上的方法,基本大同小异,这里贴一个给大家参考:链接

大致过程如下:

扫描所有的产生式,对于每一个X,连续使用以下规则,直至每个集合的FIRST集合不再增大为止,每一遍扫描所有产生式如果有FIRST集合变化则重新扫描:
1.如果X是终结符,则FIRST(X) = {X}.
2.如果X是非终结符 ,且有产生式 X → a… 则把a加入到FIRST集合中.
若 X → ε也是其中一条产生式,则把ε也加入到FIRST集合中.
3.如果X是非终结符,且 X → Y… 是一条产生式,其中Y是非终结符,那么则把FIRST(Y) \ {ε}(即FIRST集合去除ε)加入到FIRST(X)中.
更复杂些的,对于产生式 X → Y1 Y2…Yi-1 Yi…Yk ,其中Y1,…,Yi-1都是非终结符:
① 对于任意的j,满足 1 <= j <= i-1 ,且FIRST(Yj)都含有ε,则把
FIRST(Yi) \ {ε} 加入到FIRST(X)中.
② 对于任意的p,满足 1 <= p <= k ,且FIRST(Yp)都含有ε,则把
ε加入到FIRST(X)中.

注意: 每一遍对所有产生式的扫描若有一点点改动就要再全部扫描一遍。

接下来是具体代码分析,本文将拆分开来分析,完整源码见 FIRST集合

定义这个函数,确定形参和返回值:
其中形参lst为嵌套列表,第一层为所有产生式,第二层为每一条产生式的具体元素。

# 形参lst为嵌套列表,内容为每一条产生式.返回值为一个字典,记录所有FIRST集合的数据
def get_first(lst):

初始化一些要用到的变量: 其中rst为返回的字典,flag用来判断本次扫描是否有集合的变化。同时引入标点符号库,判断一些特殊符号的终结符

    rst = {}
    flag = 1
    punc = string.punctuation # 引入标点符号库

存储每个非终结符:

	for i in lst:
        rst["".join(i[:i.index('→')])] = [] # 将每一个非终结符存入字典

循环扫描所有产生式:
对于每一条产生式,我的做法是,首先获取这一条产生式,然后找到这条产生式中→和 | 的索引。

			# 获取这一条产生式的所有'|'的索引值
            temp_or = []
            temp_push = []
            for k in range(len(j)):
                if j[k] == '|':
                    temp_or.append(k)
            # 获取这一条产生式'→'的索引值
            temp_get = j.index('→')
            # 转换成列表方便组合
            temp_push.append(temp_get)
            # 合并查找索引列表
            temp_search = temp_push + temp_or

如此,我们把这几个分隔位置存在一个列表里,就可以根据这里的列表,来轻松地获取我们需要的产生式的右部。当然也可以直接在处理的时候查找→和 | 的位置。

接下来就是按照上面条件开始判断,循环体的代码如下:

	while flag == 1:
        flag = 0
        for j in lst:
            # 获取这一条产生式的所有'|'的索引值
            temp_or = []
            temp_push = []
            for k in range(len(j)):
                if j[k] == '|':
                    temp_or.append(k)
            # 获取这一条产生式'→'的索引值
            temp_get = j.index('→')
            # 转换成列表方便组合
            temp_push.append(temp_get)
            # 合并查找索引列表
            temp_search = temp_push + temp_or
            # 按条件判断
            if "".join(j[:temp_get]).islower() or ("".join(j[:temp_get]) in punc):
                if "".join(j[:temp_get]) not in rst["".join(j[:temp_get])]:
                    rst["".join(j[:temp_get])].append("".join(j[:temp_get]))
                    flag = 1
            for m in temp_search:
                if "".join(j[m + 1:m + 2]).islower() or ("".join(j[m + 1:m + 2]) in punc)\
                        or "".join(j[m + 1:m + 2]) == 'ε':
                    if "".join(j[m + 1:m + 2]) not in rst["".join(j[:temp_get])]:
                        rst["".join(j[:temp_get])].append("".join(j[m + 1:m + 2]))
                        flag = 1
                if "".join(j[m + 1:m + 2]).isupper() :
                    if "".join(j[m + 2:m + 3]) == "'":
                        if 'ε' in rst["".join(j[m + 1:m + 3])]: # temp_delete用于储存FIRST(...) \ {ε}的数据
                            temp_delete = rst["".join(j[m + 1:m + 3])].remove('ε')
                            # 将两个列表转换成结合进行交集运算若交集为空集则说明之前没有进行此操作可以添加
                            if not set(temp_delete) <= set(rst["".join(j[:temp_get])]):
                                rst["".join(j[:temp_get])].extend(temp_delete)
                                flag =1
                        else:
                            if not set(rst["".join(j[m + 1:m + 3])]) <= set(rst["".join(j[:temp_get])]):
                                rst["".join(j[:temp_get])].extend(rst["".join(j[m + 1:m + 3])])
                                flag = 1
                    else:
                        if 'ε' in rst["".join(j[m + 1:m + 2])]:
                            temp_delete = rst["".join(j[m + 1:m + 2])].remove('ε')
                            if not set(temp_delete) <= set(rst["".join(j[:temp_get])]):
                                rst["".join(j[:temp_get])].extend(temp_delete)
                                flag = 1
                        else:
                            if not set(rst["".join(j[m + 1:m + 2])]) <= set(rst["".join(j[:temp_get])]):
                                rst["".join(j[:temp_get])].extend(rst["".join(j[m + 1:m + 2])])
                                flag = 1
    return rst

内容二:构造任何符号串的FIRST集合

我们能求任何一个文法符号的FIRST集合后,有时候会碰到要求一个符号串的FIRST集合的情况,比如:A→Abc 求FIRST(bc)
介绍一下求符号串FIRST集合的方法.

对于文法G的任何符号串α = X1 X2 … Xn 构造集合FIRST(α):
1.置FIRST(α) = FIRST(X1) \ {ε} .即把X1的FIRST集合元素去掉ε后给α的FIRST集合来作为其第一批元素.
2.若对于任何 1 <= j <= i-1 ,ε∈ FIRST(Xj),则把FIRST(Xi) \ {ε}加入到FIRST(α)中.

特别的:
若所有的FIRST(Xj)均含有ε,其中1 <= j <= n,那么把ε也加入到FIRST(α)中.
显然:若α = ε,则FIRST(α) = {ε}.
接下来是具体代码分析,下载源码见 FIRST_BUNCH

## 形参lst为符号串,形式为列表,内容为每一个符号.返回值为一个列表,记录所求FIRST集合
## 形参lst_origin为嵌套列表,可以通过这个调用get_first获取所有非终结符的FIRST集合
def get_first_bunch(lst,lst_origin):
    punc = string.punctuation # 引入标点符号库
    temp_rst = get_first(lst_origin)
    if (lst[0] in punc) or lst[0] == 'ε' or lst[0].islower():
        rst = [lst[0]]
    else:
        rst = temp_rst[lst[0]][:]
        if 'ε' in rst:
            rst.remove('ε')
        i = 0
        for i in range(len(lst)):
            if 'ε' not in temp_rst[lst[i]]:
                break
        rst.extend(temp_rst[lst[i]])
        if 'ε' in rst:
            rst.remove('ε')
        if i + 1 == len(lst) and ('ε' in temp_rst[lst[i]]):
            rst.append('ε')
    return list(set(rst))

内容三:构造每一个非终结符的FOLLOW集合

首先我们了解一下FOLLOW集合的求法,对比了许多网上的方法,基本大同小异,这里贴一个给大家参考:链接

大致过程如下:

扫描所有产生式.对于文法G的每一个非终结符A构造FOLLOW(A)可以连续使用以下规则,直至每一个FOLLOW集合不在增大为止:
1.对于文法的开始符号S,置 # 于FOLLOW(S)中.
2.若有产生式 A → αBβ,其中α和β是非终结符和终结符构成的串,B为非终结符,则把FIRST(β) \ {ε}加入到FOLLOW(B)中.
3.若有产生式 A → αB 或 A → αBβ ε∈FIRST(β) ,则把FOLLOW(A)加入到FOLLOW(B)中.

注意: 一个产生式可能匹配算法的好几个步骤。

这一部分的逻辑代码我构思了挺久,没有想到什么好的方法,我的想法是:

按照产生式右部的长度分类讨论,长度为1、2、3以及大于3。其中长度小于等于3的逻辑代码我已经测试完毕,大于3部分的代码还在测试,还有一些小问题,所以暂时只分析(逻辑代码写起来也不复杂),之后完成后更新。

接下来是具体代码分析,下载源码见 FOLLOW集合

首先是和获取FIRST集合差不多的获取数据的部分:
其中形参lst为嵌套列表,第一层为所有产生式,第二层为每一条产生式的具体元素。

## 形参lst为嵌套列表,内容为每一条产生式.返回值为一个字典,记录所有FOLLOW集合的数据
## 产生式的条数和非终结符的个数相同,这里我通过分类讨论每一条产生式中的非终结符个数来确定这一产生式匹配几个算法
## 2020.5.11 代码中运算只包括小于等于三个非终结符/终结符的串,并且在等于三的情况中,有一些情况等待coding
##           计算一个指定串的FIRST集合代码已经写好,可以方便在待coding部分调用
## 2020.5.11 修改部分判定条件。我觉得这整个求FOLLOW集的算法有点太过于繁琐,是不是因为思考方向?
def get_follow(lst):
    rst = {}
    flag = 1
    punc = string.punctuation # 引入标点符号库
    for i in lst:
        rst["".join(i[:i.index('→')])] = [] # 将每一个非终结符存入字典
    while flag == 1:
        flag = 0
        for j in lst:
            first  = get_first(lst) # 获取first字典
            temp_split = [] # 将每一个产生式分割以便求的长度来进行分类讨论
            # 获取这一条产生式的所有'|'的索引值
            temp_or = []
            temp_push = []
            for k in range(len(j)):
                if j[k] == '|':
                    temp_or.append(k)
            # 获取这一条产生式'→'的索引值
            temp_get = j.index('→')
            # 转换成列表方便组合
            temp_push.append(temp_get)
            # 合并查找索引列表
            temp_search =  temp_push + temp_or

获取 → 和 | 的索引,并且根据这些索引,把一条产生式所有的右部都分离出来方便调用:
这里temp_split中存储的就是当前产生式所有的右部,比如,若产生式为
A → Ea|bE’|abc , 则存储的是[[‘E’,‘a’],[‘b’,‘E’,"’"],[‘a’,‘b’,‘c’]]

# 把一个产生式以'→'和'|'为分隔符分割,将分割后的数据存储在嵌套列表temp_split里
            for m in range(len(temp_search)):
                if len(temp_search) == 1:
                    temp_split = [j[temp_search[m] + 1:]]
                else:
                    if m == (len(temp_search) - 1):
                        temp_split.append(j[temp_search[m] + 1:])
                    else:
                        temp_split.append(j[temp_search[m] + 1:temp_search[m + 1]])

接下来按条件判断:
处理开始符号:

			if lst.index(j) == 0:
                if '#' not in rst["".join(j[:j.index('→')])]:
                    rst["".join(j[:j.index('→')])].append('#')
                    flag = 1

按右部的长度进行分类处理:
这边需要说明的就是,有注释待编写代码的地方,其实是一些小的分支,具体就是跟其他处理方式一致,不过要用调用get_first_bunch方法求符号串的FIRST集合。另外长度大于3的情况也是如此,用一个循环,来匹配三个步骤里的几个条件,只不过需要调用的就是get_first_bunch,而并非只有get_first方法了。

			for n in temp_split:
                length = len(n)
                if length == 2 and ("'" not in n):
                    # 两个非终结符
                    if "".join(n).isupper():
                        if 'ε' in first[n[1]]:
                            temp_judge = first[n[1]]
                            temp_judge.remove('ε')
                            if not set(rst[n[0]]) >= set(temp_judge):
                                rst[n[0]].extend(temp_judge)
                                flag = 1
                        if not set(rst[n[0]]) >= set(first[n[1]]):
                            rst[n[0]].extend(first[n[1]])
                            flag = 1
                        if not set(rst[n[1]]) >= set(rst["".join(j[:temp_get])]):
                            rst[n[1]].extend(rst["".join(j[:temp_get])])
                            flag = 1
                        if 'ε' in first[n[1]]:
                            if not set(rst[n[0]]) >= set(rst["".join(j[:temp_get])]):
                                rst[n[0]].extend(rst["".join(j[:temp_get])])
                                flag =1
                    # 一个非终结符和一个终结符
                    if "".join(n[0]).islower() or ("".join(n[0]) in punc) and "".join(n[1]).isupper():
                        if not set(rst[n[1]]) >= set(rst["".join(j[:temp_get])]):
                            rst[n[1]].extend(rst["".join(j[:temp_get])])
                            flag = 1
                    if "".join(n[1]).islower() or ("".join(n[1]) in punc) and "".join(n[0]).isupper():
                        if n[1] not in rst[n[0]]:
                            rst[n[0]].append(n[1])
                            flag = 1
                if length == 3 and ("'" in n):
                    if n.index("'") == 1:
                        if n[2].isupper():
                            if 'ε' in first[n[2]]:
                                temp_judge = first[n[2]]
                                temp_judge.remove('ε')
                                if not set(rst["".join(n[:2])]) >= set(temp_judge):
                                    rst["".join(n[:2])].extend(temp_judge)
                                    flag = 1
                                if not set(rst["".join(n[:2])]) >= set(rst["".join(j[:temp_get])]):
                                    rst["".join(n[:2])].extend(rst["".join(j[:temp_get])])
                                    flag =1
                            if not set(rst["".join(n[:2])]) >= set(first[n[2]]):
                                rst["".join(n[:2])].extend(first[n[2]])
                                flag = 1
                            if not set(rst[n[2]]) >= set(rst["".join(j[:temp_get])]):
                                rst[n[2]].extend(rst["".join(j[:temp_get])])
                                flag = 1
                            # if 'ε' in first[n[2]]:
                            #     if not set(rst["".join(n[:2])]) >= set(rst["".join(j[:temp_get])]):
                            #         rst["".join(n[:2])].extend(rst["".join(j[:temp_get])])
                            #         flag =1
                        else:
                            if n[2] not in rst["".join(n[:2])]:
                                rst["".join(n[:2])].append(n[2])
                                flag = 1
                    if n.index("'") == 2:
                        if n[0].isupper():
                            if 'ε' in first["".join(n[1:])]:
                                temp_judge = first["".join(n[1:])]
                                temp_judge.remove('ε')
                                if not set(rst[n[0]]) >= set(temp_judge):
                                    rst[n[0]].extend(temp_judge)
                                    flag = 1
                                if not set(rst[n[0]]) >= set(rst["".join(j[:temp_get])]):
                                    rst[n[0]].extend(rst["".join(j[:temp_get])])
                                    flag =1
                            if not set(rst[n[0]]) >= set(first["".join(n[1:])]):
                                rst[n[0]].extend(first["".join(n[1:])])
                                flag = 1
                            if not set(rst["".join(n[1:])]) >= set(rst["".join(j[:temp_get])]):
                                rst["".join(n[1:])].extend(rst["".join(j[:temp_get])])
                                flag = 1
                            # if 'ε' in first["".join(n[1:])]:
                            #     print("ok2")
                            #     if not set(rst[n[0]]) >= set(rst["".join(j[:temp_get])]):
                            #         rst[n[0]].extend(rst["".join(j[:temp_get])])
                            #         flag =1
                if length == 3 and ("'" not in n):
                    if n[0].islower() or (n[0] in punc):
                        if n[1].islower() or (n[1] in punc):
                            if n[2].isupper():
                                if not set(rst[n[2]]) >= set(rst["".join(j[:temp_get])]):
                                    rst[n[2]].extend(rst["".join(j[:temp_get])])
                                    flag = 1
                        if n[1].isupper():
                            if n[2].isupper():
                                if 'ε' in first[n[2]]:
                                    temp_judge = first[n[2]]
                                    temp_judge.remove('ε')
                                    if not set(rst[n[1]]) >= set(temp_judge):
                                        rst[n[1]].extend(temp_judge)
                                        flag = 1
                                    if not set(rst[n[1]]) >= set(rst["".join(j[:temp_get])]):
                                        rst[n[1]].extend(rst["".join(j[:temp_get])])
                                        flag =1
                                if not set(rst[n[1]]) >= set(first[n[2]]):
                                    rst[n[1]].extend(first[n[2]])
                                    flag = 1
                                # if 'ε' in first[n[2]]:
                                #     if not set(rst[n[1]]) >= set(rst["".join(j[:temp_get])]):
                                #         rst[n[1]].extend(rst["".join(j[:temp_get])])
                                #         flag =1
                            else:
                                if n[2] not in rst[n[1]]:
                                    rst[n[1]].append(n[2])
                                    flag = 1
                    if n[0].isupper():
                        if n[1].isupper():
                            if n[2].isupper():
                                if 'ε' in first[n[2]]:
                                    temp_judge = first[n[2]]
                                    temp_judge.remove('ε')
                                    if not set(rst[n[1]]) >= set(temp_judge):
                                        rst[n[1]].extend(temp_judge)
                                        flag = 1
                                    if not set(rst[n[1]]) >= set(rst["".join(j[:temp_get])]):
                                        rst[n[1]].extend(rst["".join(j[:temp_get])])
                                        flag = 1
                                if not set(rst[n[1]]) >= set(first[n[2]]):
                                    rst[n[1]].extend(first[n[2]])
                                    flag = 1

                                # code record εAAA
                                ## ...

                                # if 'ε' in first[n[2]]:
                                #     if not set(rst[n[1]]) >= set(rst["".join(j[:temp_get])]):
                                #         rst[n[1]].extend(rst["".join(j[:temp_get])])
                                #         flag = 1
                            else:
                                if n[2] not in rst[n[1]]:
                                    rst[n[1]].append(n[2])
                                    flag = 1

                                # code record εAAa
                                ## ...
                        else:
                            # AaA
                            if n[2].isupper():
                                if not set(rst[n[2]]) >= set(rst["".join(j[:temp_get])]):
                                    rst[n[2]].extend(rst["".join(j[:temp_get])])
                                    flag = 1

                                # code record εAaA
                                ## ...

                            # code record Aaa
                            ## ...
                if length == 4 and ("'" in n):
                    if n[1] == "'":
                        if n[2].isupper():
                            if n[3].isupper():
                                if 'ε' in first[n[3]]:
                                    temp_judge = first[n[3]]
                                    temp_judge.remove('ε')
                                    if not set(rst[n[2]]) >= set(temp_judge):
                                        rst[n[2]].extend(temp_judge)
                                        flag = 1
                                    if not set(rst[n[2]]) >= set(rst["".join(j[:temp_get])]):
                                        rst[n[2]].extend(rst["".join(j[:temp_get])])
                                        flag = 1
                                if not set(rst[n[2]]) >= set(first[n[3]]):
                                    rst[n[2]].extend(first[n[3]])
                                    flag = 1

                                # code record εA'AA
                                ## ...

                                # if 'ε' in first[n[3]]:
                                #     if not set(rst[n[2]]) >= set(rst["".join(j[:temp_get])]):
                                #         rst[n[2]].extend(rst["".join(j[:temp_get])])
                                #         flag = 1
                            else:
                                if n[3] not in rst[n[2]]:
                                    rst[n[2]].append(n[3])
                                    flag = 1

                                # code record εA'Aa
                                ## ...
                        else:
                            # A'aA
                            if n[3].isupper():
                                if not set(rst[n[3]]) >= set(rst["".join(j[:temp_get])]):
                                    rst[n[3]].extend(rst["".join(j[:temp_get])])
                                    flag = 1

                                # code record εA'aA
                                ## ...

                            # code record A'aa
                            ## ...
                    if n[2] == "'":
                        if n[0].isupper():
                            if n[3].isupper():
                                if 'ε' in first[n[3]]:
                                    temp_judge = first[n[3]]
                                    temp_judge.remove('ε')
                                    if not set(rst["".join(n[1:3])]) >= set(temp_judge):
                                        rst["".join(n[1:3])].extend(temp_judge)
                                        flag = 1
                                    if not set(rst["".join(n[1:3])]) >= set(rst["".join(j[:temp_get])]):
                                        rst["".join(n[1:3])].extend(rst["".join(j[:temp_get])])
                                        flag = 1
                                if not set(rst["".join(n[1:3])]) >= set(first[n[3]]):
                                    rst["".join(n[1:3])].extend(first[n[3]])
                                    flag = 1

                                # code record εAA'A
                                ## ...

                                # if 'ε' in first[n[3]]:
                                #     if not set(rst["".join(n[1:3])]) >= set(rst["".join(j[:temp_get])]):
                                #         rst["".join(n[1:3])].extend(rst["".join(j[:temp_get])])
                                #         flag = 1
                            else:
                                if n[3] not in rst["".join(n[1:3])]:
                                    rst["".join(n[1:3])].append(n[3])
                                    flag = 1

                                # code record εAA'a
                                ## ...
                        else:
                            # aA'A
                            if n[3].isupper():
                                if 'ε' in first[n[3]]:
                                    temp_judge = first[n[3]]
                                    temp_judge.remove('ε')
                                    if not set(rst["".join(n[1:3])]) >= set(temp_judge):
                                        rst["".join(n[1:3])].extend(temp_judge)
                                        flag = 1
                                    if not set(rst["".join(n[1:3])]) >= set(rst["".join(j[:temp_get])]):
                                        rst["".join(n[1:3])].extend(rst["".join(j[:temp_get])])
                                        flag = 1
                                if not set(rst["".join(n[1:3])]) >= set(first[n[3]]):
                                    rst["".join(n[1:3])].extend(first[n[3]])
                                    flag = 1

                                # code record εaA'A
                                ## ...

                                # if 'ε' in first[n[3]]:
                                #     if not set(rst["".join(n[1:3])]) >= set(rst["".join(j[:temp_get])]):
                                #         rst["".join(n[1:3])].extend(rst["".join(j[:temp_get])])
                                #         flag = 1
                            else:
                                if n[3] not in rst["".join(n[1:3])]:
                                    rst["".join(n[1:3])].append(n[3])
                                    flag = 1

                                # code record εaA'a
                                ## ...
                    if n[3] == "'":
                        if n[0].isupper():
                            if n[1].isupper():
                                # AAA'
                                if 'ε' in first["".join(n[2:])]:
                                    temp_judge = first["".join(n[2:])]
                                    temp_judge.remove('ε')
                                    if not set(rst[n[1]]) >= set(temp_judge):
                                        rst[n[1]].extend(temp_judge)
                                        flag = 1
                                    if not set(rst[n[1]]) >= set(rst["".join(j[:temp_get])]):
                                        rst[n[1]].extend(rst["".join(j[:temp_get])])
                                        flag = 1
                                if not set(rst[n[1]]) >= set(first["".join(n[2:])]):
                                    rst[n[1]].extend(first["".join(n[2:])])
                                    flag = 1

                                # code record εAAA'
                                ## ...

                                # if 'ε' in first["".join(n[2:])]:
                                #     if not set(rst[n[1]]) >= set(rst["".join(j[:temp_get])]):
                                #         rst[n[1]].extend(rst["".join(j[:temp_get])])
                                #         flag = 1
                            else:
                                if n[0].isupper():
                                    # AaA'
                                    if not set(rst["".join(n[2:3])]) >= set(rst["".join(j[:temp_get])]):
                                        rst["".join(n[2:3])].extend(rst["".join(j[:temp_get])])
                                        flag = 1
                        else:
                            if n[1].isupper():
                                # aAA'
                                if 'ε' in first["".join(n[2:])]:
                                    temp_judge = first["".join(n[2:])]
                                    temp_judge.remove('ε')
                                    if not set(rst[n[1]]) >= set(temp_judge):
                                        rst[n[1]].extend(temp_judge)
                                        flag = 1
                                    if not set(rst[n[1]]) >= set(rst["".join(j[:temp_get])]):
                                        rst[n[1]].extend(rst["".join(j[:temp_get])])
                                        flag = 1
                                if not set(rst[n[1]]) >= set(first["".join(n[2:])]):
                                    rst[n[1]].extend(first["".join(n[2:])])
                                    flag = 1

                                # code record εAAA'
                                ## ...

                                # if 'ε' in first["".join(n[2:])]:
                                #     if not set(rst[n[1]]) >= set(rst["".join(j[:temp_get])]):
                                #         rst[n[1]].extend(rst["".join(j[:temp_get])])
                                #         flag = 1
                            else:
                                if not set(rst["".join(n[2:3])]) >= set(rst["".join(j[:temp_get])]):
                                    rst["".join(n[2:3])].extend(rst["".join(j[:temp_get])])
                                    flag = 1
    # code record
    ## AAA...

利用集合的特性删除重复的数据

    # 利用集合特性删除重复的数据
    for q in rst:
        rst[q] = list(set(rst[q]))
    return rst

供测试的代码:

if __name__ == '__main__':
    lst_demo = [["E","→","T","E","'"],["E","'","→","+","T","E","'","|","ε"],["T","→","F","T","'"],\
           ["T","'","→","*","F","T","'","|","ε"],["F","→","(","E",")","|","i"]]
    lst_demo1 = ["E'","E"]
    lst_demo1 = ["q"]
    print("代码测试1:求FIRST集、FOLLOW集和符号串的FIRST集.")
    result = {}
    result = get_first(lst_demo)
    print("FIRST:",result)
    result = get_follow(lst_demo)
    print("FOLLOW:",result)
    result1 = get_first_bunch(lst_demo1,lst_demo)
    print("FIRST(BUNCH):",result1)

总结

  • 逻辑代码可以处理大部分简单的文法结构,FOLLOW集合中的其他部分可以自行编写,和前几个判断差不多。
  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

x1Nge.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值