示例#1
0
def compute_firsts():

    from Skoarcery.terminals import Empty, tokens as T
    from Skoarcery.nonterminals import nonterminals as N

    global FIRST

    # do terminals first
    for X in T.values():
        FIRST(X).add(X)

    last = 0
    first_len = len(FIRST)
    while first_len > last:

        last = first_len

        for X in N.values():
            if X.derives_empty:
                FIRST(X).add(Empty)

            for R in X.production_rules:

                i = -1
                n = len(R.production)

                # figure out FIRST(X) first
                for Yi in R.production:
                    i += 1

                    Yi_to_end = R.production[i:]

                    if len(Yi_to_end) > 0:
                        S = FIRST(Yi_to_end)

                        S.update(
                            everything_but_e(FIRST(Yi))
                        )

                        FIRST(X).update(S)
                        FIRST(Yi_to_end).update(S)

                    if not Yi.derives_empty:
                        break

                # if we got to the end of the loop without breaking, add Empty
                else:
                    FIRST(X).add(Empty)

        first_len = len(FIRST)
示例#2
0
def compute_firsts():

    from Skoarcery.terminals import Empty, tokens as T
    from Skoarcery.nonterminals import nonterminals as N

    global FIRST

    # do terminals first
    for X in T.values():
        FIRST(X).add(X)

    last = 0
    first_len = len(FIRST)
    while first_len > last:

        last = first_len

        for X in N.values():
            if X.derives_empty:
                FIRST(X).add(Empty)

            for R in X.production_rules:

                i = -1
                n = len(R.production)

                # figure out FIRST(X) first
                for Yi in R.production:
                    i += 1

                    Yi_to_end = R.production[i:]

                    if len(Yi_to_end) > 0:
                        S = FIRST(Yi_to_end)

                        S.update(everything_but_e(FIRST(Yi)))

                        FIRST(X).update(S)
                        FIRST(Yi_to_end).update(S)

                    if not Yi.derives_empty:
                        break

                # if we got to the end of the loop without breaking, add Empty
                else:
                    FIRST(X).add(Empty)

        first_len = len(FIRST)
示例#3
0
def compute_follows():
    from Skoarcery.terminals import EOF, Empty
    from Skoarcery.nonterminals import nonterminals as N, SKOAR

    global FIRST, FOLLOW

    # start symbol gets end symbol
    FOLLOW(SKOAR).add(EOF)

    # repeat until nothing can be added to any follow set
    last = 0
    follow_len = len(FOLLOW)
    while follow_len > last:

        last = follow_len

        for X in N.values():

            for R in X.production_rules:

                A = R.production

                # If there is a production [ A -> alpha B beta]:
                #     everything except <e> in FIRST(beta) is in FOLLOW(B)

                # examine each suffix (except last)
                n = len(A)

                for i in range(0, n - 1):

                    B = A[i]
                    if not isinstance(B, Nonterminal):
                        continue

                    beta = A[i + 1:]

                    #print("n: " + str(n) + " i: " + str(i) + " A: " + repr(A) + " beta: " + repr(beta))

                    S = FIRST(beta)
                    FOLLOW(B).update(everything_but_e(S))

                for i in reversed(range(0, n)):

                    B = A[i]
                    if not isinstance(B, Nonterminal):
                        continue

                    # we are at the end of the list
                    if i == n - 1:
                        FOLLOW(B).update(FOLLOW(X))
                        continue

                    beta = A[i + 1:]

                    S = FIRST(beta)

                    #print(": FIRST(" + repr(beta) + ") = " + repr(S))

                    if Empty in S:
                        FOLLOW(B).update(FOLLOW(X))
                    else:
                        break

        follow_len = len(FOLLOW)
示例#4
0
def compute_follows():
    from Skoarcery.terminals import EOF, Empty
    from Skoarcery.nonterminals import nonterminals as N, SKOAR

    global FIRST, FOLLOW

    # start symbol gets end symbol
    FOLLOW(SKOAR).add(EOF)

    # repeat until nothing can be added to any follow set
    last = 0
    follow_len = len(FOLLOW)
    while follow_len > last:

        last = follow_len

        for X in N.values():

            for R in X.production_rules:

                A = R.production

                # If there is a production [ A -> alpha B beta]:
                #     everything except <e> in FIRST(beta) is in FOLLOW(B)

                # examine each suffix (except last)
                n = len(A)

                for i in range(0, n - 1):

                    B = A[i]
                    if not isinstance(B, Nonterminal):
                        continue

                    beta = A[i + 1:]

                    #print("n: " + str(n) + " i: " + str(i) + " A: " + repr(A) + " beta: " + repr(beta))

                    S = FIRST(beta)
                    FOLLOW(B).update(everything_but_e(S))

                for i in reversed(range(0, n)):

                    B = A[i]
                    if not isinstance(B, Nonterminal):
                        continue

                    # we are at the end of the list
                    if i == n - 1:
                        FOLLOW(B).update(FOLLOW(X))
                        continue

                    beta = A[i + 1:]

                    S = FIRST(beta)

                    #print(": FIRST(" + repr(beta) + ") = " + repr(S))

                    if Empty in S:
                        FOLLOW(B).update(FOLLOW(X))
                    else:
                        break

        follow_len = len(FOLLOW)