| 
 | 1 | +from collections import deque  | 
 | 2 | + | 
 | 3 | +from grammars.grammar import STARTSYMBOL  | 
 | 4 | + | 
1 | 5 | """  | 
2 | 6 | Algorithm 18.2.1  | 
3 | 7 | Breadth-First Top-Down Parser  | 
4 | 8 |  | 
5 | 9 | input: context free grammar G = (V, Alphabet, P, S)  | 
6 |  | - string p, where p is element of Alphabet*  | 
 | 10 | + string p, where p is element of Alphabet*  | 
7 | 11 | data structure: queue Q  | 
8 | 12 |  | 
9 | 13 | 1. initialize T with root S  | 
10 | 14 |  INSERT(S, Q)  | 
11 | 15 | 2. repeat  | 
12 |  | -2.1 q := REMOVE(Q) (node to be expanded)  | 
13 |  | -2.2 i := 0 (number of last rule used)  | 
14 |  | -2.3 done := false (Boolean indicator of expansion completion)  | 
15 |  | -Let q = uAv where A is the leftmost variable in q  | 
16 |  | -2.4 repeat  | 
17 |  | -2.4.1 if there is no A rule numbered greater than i the done := true  | 
18 |  | -2.4.2 if not done then  | 
19 |  | -Let A -> w be the first A rule with number greater than i and  | 
20 |  | -let j be the number of this rule  | 
21 |  | -2.4.2.1 if uwv is not element of Alphabet* and the terminal prefix of  | 
22 |  | -uwv matches a prefix of p then  | 
23 |  | -2.4.2.1.1 INSERT(uwv, Q)  | 
24 |  | -2.4.2.1.2 Add node uwv to T. Set a pointer from uwv to q  | 
25 |  | -end if  | 
26 |  | -end if  | 
27 |  | -2.4.3 i := j  | 
28 |  | - until done or p = uwv  | 
 | 16 | +2.1 q := REMOVE(Q) (node to be expanded)  | 
 | 17 | +2.2 i := 0 (number of last rule used)  | 
 | 18 | +2.3 done := false (Boolean indicator of expansion completion)  | 
 | 19 | +Let q = uAv where A is the leftmost variable in q  | 
 | 20 | +2.4 repeat  | 
 | 21 | +2.4.1 if there is no A rule numbered greater than i the done := true  | 
 | 22 | +2.4.2 if not done then  | 
 | 23 | +Let A -> w be the first A rule with number greater than i and  | 
 | 24 | +let j be the number of this rule  | 
 | 25 | +2.4.2.1 if uwv is not element of Alphabet* and the terminal prefix of  | 
 | 26 | +uwv matches a prefix of p then  | 
 | 27 | +2.4.2.1.1 INSERT(uwv, Q)  | 
 | 28 | +2.4.2.1.2 Add node uwv to T. Set a pointer from uwv to q  | 
 | 29 | +end if  | 
 | 30 | +end if  | 
 | 31 | +2.4.3 i := j  | 
 | 32 | + until done or p = uwv  | 
29 | 33 |  until EMPTY(Q) or p = uwv  | 
30 | 34 | 3. if p = uwv then accept else reject  | 
31 | 35 | """  | 
32 |  | -def breadthFirstTopDownParse( contextFreeGrammar, p):  | 
 | 36 | +def breadthFirstTopDownParse( G, p, Q):  | 
 | 37 | + S = Node( STARTSYMBOL )  | 
 | 38 | + T = SearchTree( S )  | 
 | 39 | + INSERT( S, Q )  | 
 | 40 | + while True: # repeat  | 
 | 41 | + q = REMOVE(Q)  | 
 | 42 | + i = 0  | 
 | 43 | + done = False  | 
 | 44 | + u, A, v = uAv_structure( q.sentForm )  | 
 | 45 | + while True: # repeat  | 
 | 46 | + validRules = [(j, rule) for j, rule in enumerate(G.rules) if (rule.lhs == A) and (j > i)]  | 
 | 47 | + if not validRules:  | 
 | 48 | + done = True  | 
 | 49 | + if not done:  | 
 | 50 | + A, w = validRules[0][1].lhs, validRules[0][1].rhs # rule A -> w  | 
 | 51 | + j = validRules[0][0]  | 
 | 52 | + if (not all(x.islower() for x in u+w+v) and  | 
 | 53 | + ***the terminal prefix of uwv matches a prefix of p***):  | 
 | 54 | + uwv = Node(u+w+v)  | 
 | 55 | + INSERT( uwv, Q )  | 
 | 56 | + uwv.parent = q # and add uwv to T  | 
 | 57 | + i = j  | 
 | 58 | + if done or p == uwv: break # until  | 
 | 59 | + if EMPTY(Q) or p == uwv  | 
 | 60 | + return True if p == uwv else False  | 
 | 61 | + | 
 | 62 | +def uAv_structure( sentForm ):  | 
33 | 63 |  raise NotImplementedError  | 
34 | 64 | 
 
  | 
 | 65 | +def INSERT( x, Q ):  | 
 | 66 | + """ places the string x at the rear of the queue """  | 
 | 67 | + return Q.append(x)  | 
 | 68 | + | 
 | 69 | +def REMOVE( Q ):  | 
 | 70 | + """ returns the item at the front of Q and deletes it from Q. """  | 
 | 71 | + return Q.popleft()  | 
 | 72 | + | 
 | 73 | +def EMPTY( Q ):  | 
 | 74 | + """ boolean function that returns true if queue is empty, false otherwise. """  | 
 | 75 | + return len(Q) == 0  | 
 | 76 | + | 
 | 77 | +class Node( object ):  | 
 | 78 | + """ A node to be a part of the search tree T. Contains a sentential form. """  | 
 | 79 | + def __init__(self, sentForm, parent=None ):  | 
 | 80 | + self.parent = parent  | 
 | 81 | + self.sentForm = sentForm  | 
 | 82 | + | 
 | 83 | +class SearchTree( object ):  | 
 | 84 | + """  | 
 | 85 | + The 'implicit tree' of a grammar is the tree of possible derivation  | 
 | 86 | + paths in that grammar. This 'search tree' is the portion of the implicit  | 
 | 87 | + tree that is examined during the parse.  | 
 | 88 | + """  | 
 | 89 | + def __init__(self, root=None):  | 
 | 90 | + self.root = root  | 
 | 91 | + # TODO: expand class to fulfil its function within the parsers  | 
 | 92 | + | 
 | 93 | + | 
35 | 94 | """  | 
36 | 95 | Algorithm 18.4.1  | 
37 | 96 | Breath-First Bottom-Up Parser  | 
38 | 97 |  | 
39 | 98 | input: context-free grammar G = (V, Alphabet, P, S)  | 
40 |  | - string p, where p is element of Alphabet*  | 
 | 99 | + string p, where p is element of Alphabet*  | 
41 | 100 | data structure: queue Q  | 
42 | 101 |  | 
43 | 102 | 1. initialize T with root p  | 
44 |  | - INSERT(p, Q)  | 
 | 103 | + INSERT(p, Q)  | 
45 | 104 | 2. repeat  | 
46 |  | -q := REMOVE(Q)  | 
47 |  | -2.1 for each rule A -> w in P do  | 
48 |  | -2.2.1 for each decomposition uwv of q with v, where v is element of Alphabet* do  | 
49 |  | -2.1.1.1 INSERT(uAv, Q)  | 
50 |  | -2.1.1.2 Add node uAv to T. Set a pointer from uAv to q  | 
51 |  | - end for  | 
52 |  | -end for  | 
53 |  | - until q = S or EMPTY(Q)  | 
 | 105 | +q := REMOVE(Q)  | 
 | 106 | +2.1 for each rule A -> w in P do  | 
 | 107 | +2.2.1 for each decomposition uwv of q with v, where v is element of Alphabet* do  | 
 | 108 | +2.1.1.1 INSERT(uAv, Q)  | 
 | 109 | +2.1.1.2 Add node uAv to T. Set a pointer from uAv to q  | 
 | 110 | + end for  | 
 | 111 | +end for  | 
 | 112 | + until q = S or EMPTY(Q)  | 
54 | 113 | 3. if q = S then accept else reject  | 
55 | 114 | """  | 
56 | 115 | def breadthFirstBottomUpParser( contextFreeGrammar, p):  | 
 | 
0 commit comments