原理
資料結構
1 G = {'key':[v1,v2,v3],'key':[v1,v2,v3]};
2 VN = [];
3 Vt = [];
4 FirstVT = {'key':[v1,v2,v3],'key':[v1,v2,v3]};
也就是map裡放list,同樣将文法壓縮,對于産生式相同的發到一個map元素裡,追加到map元素對應的list後面
算法過程
1、 先求出直接滿足A->a 或 A->Ba的文法的A的FIRSTVT集合
2、 掃描FIRSTVT集,将滿足蔓延性公式的終結符加到非終結符的FIRSTVT集合中。蔓延性滿足下面的條件
若a屬于FIRSTVT(B) 且有産生式A->B..... 則a屬于FIRSTVT(A)
輸入
1 8
2 S->#E#
3 E->E+T
4 E->T
5 T->T*F
6 T->F
7 F->P^F|P
8 P->(E)
9 P->i
完整算法
1 #!/usr/bin/env python
2 #-*-coding:utf8-*-
3
4 #count = raw_input('Please input P count:');
5
6 #print "Input all P:\n";
7 f = open("./2.in", 'r',1);
8 count = int(f.readline());
9 #G = [];
10 G = {};
11 VN = [];
12 Vt = [];
13 FirstVT = {};
14 for i in range(0,count):
15 #key = raw_input("P key:");
16 #value = raw_input("P value:");
17 line = f.readline().strip();
18 print line;
19 arr = line.split("->");
20 #P = {'key':key,'value':value};
21 #P = {
22 #'key':arr[0],
23 #'value':arr[1]
24 #};
25 VN.append(arr[0]);
26
27 #G.append();
28 if arr[0] not in G:
29 G[arr[0]] = [];
30 G[arr[0]].append(arr[1]);
31 #print G;
32
33 #for p in G:
34 #a = '';
35 #if (p['value'][0] not in VN):
36 #a = p['value'][0];
37 #elif (len(p['value']) >= 2 ) and ( p['value'][0] in VN):
38 #a = p['value'][1];
39
40 for k in G:
41 vs = G.get(k);
42 for v in vs:
43 a = '';
44 if v[0] not in VN:
45 a = v[0];
46 elif len(v) >= 2 and v[0] in VN and v[1] not in VN:
47 a = v[1];
48
49 if k not in FirstVT:
50 FirstVT[k] = [];
51
52 if a != '':
53 #将形如 A->a 的 FirstVT[A] 添加進 a
54 FirstVT[k].append(a);
55
56 #print FirstVT;
57
58 stack = [];
59
60 for _k in FirstVT:
61 _vs = FirstVT.get(_k);
62 for _v in _vs:
63 # 将 形如 A->a 的入棧
64 stack.append([_k,_v]);
65
66
67 #print stack;
68
69 while len(stack) > 0:
70 ij = stack.pop();
71 B = ij[0];
72 a = ij[1];
73 for A in G:
74 vvs = G.get(A);
75 for _vs in vvs:
76 # 存在形式如 A->B && f[ia,ja]為假
77 if _vs[0] == B and A != B and ( a not in FirstVT.get(A) ):
78 FirstVT[A].append(a);
79 stack.append([A,a]);
80
81
82
83 #print FirstVT;
84
85 print '------------------------------------------------'
86 for fk in FirstVT:
87 fv = FirstVT.get(fk);
88 print 'FIRSTVT(',fk,')={',;
89 for item in fv:
90 if item != fv[-1] :
91 print item,',',;
92 else:
93 print item,;
94 print '}\n',;
運作結果
