1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 __version__ = "2.3"
54
55
56
57
58
59
60
61 yaccdebug = 1
62
63
64 debug_file = 'parser.out'
65 tab_module = 'parsetab'
66 default_lr = 'LALR'
67
68 error_count = 3
69
70 import re, types, sys, cStringIO, md5, os.path
71
72
74
75
76
77
78
79 try:
80 _INSTANCETYPE = (types.InstanceType, types.ObjectType)
81 except AttributeError:
82 _INSTANCETYPE = types.InstanceType
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
103 - def __str__(self): return self.type
105
106
107
108
109
110
111
112
113
114
117 self.slice = s
118 self.pbstack = []
119 self.stack = stack
121 if n >= 0: return self.slice[n].value
122 else: return self.stack[n].value
123
125 self.slice[n].value = v
126
128 return [s.value for s in self.slice[i:j]]
129
131 return len(self.slice)
132
134 return getattr(self.slice[n],"lineno",0)
135
137 startline = getattr(self.slice[n],"lineno",0)
138 endline = getattr(self.slice[n],"endlineno",startline)
139 return startline,endline
140
142 return getattr(self.slice[n],"lexpos",0)
143
145 startpos = getattr(self.slice[n],"lexpos",0)
146 endpos = getattr(self.slice[n],"endlexpos",startpos)
147 return startpos,endpos
148
150 if n <= 0:
151 raise ValueError, "Expected a positive value"
152 if n > (len(self.slice)-1):
153 raise ValueError, "Can't push %d tokens. Only %d are available." % (n,len(self.slice)-1)
154 for i in range(0,n):
155 self.pbstack.append(self.slice[-i-1])
156
157
158
159
160
161
164
165
166
167
168 if magic != "xyzzy":
169 raise YaccError, "Can't instantiate Parser. Use yacc() instead."
170
171
172 self.productions = None
173 self.errorfunc = None
174 self.action = { }
175 self.goto = { }
176 self.require = { }
177 self.method = "Unknown LR"
178
180 self.errorok = 1
181
183 del self.statestack[:]
184 del self.symstack[:]
185 sym = YaccSymbol()
186 sym.type = '$end'
187 self.symstack.append(sym)
188 self.statestack.append(0)
189
190 - def parse(self,input=None,lexer=None,debug=0,tracking=0):
191 lookahead = None
192 lookaheadstack = [ ]
193 actions = self.action
194 goto = self.goto
195 prod = self.productions
196 pslice = YaccProduction(None)
197 errorcount = 0
198
199
200 if not lexer:
201 import lex
202 lexer = lex.lexer
203
204 pslice.lexer = lexer
205 pslice.parser = self
206
207
208 if input:
209 lexer.input(input)
210
211
212 get_token = lexer.token
213
214 statestack = [ ]
215 self.statestack = statestack
216 symstack = [ ]
217 self.symstack = symstack
218
219 pslice.stack = symstack
220 errtoken = None
221
222
223
224 statestack.append(0)
225 sym = YaccSymbol()
226 sym.type = '$end'
227 symstack.append(sym)
228 state = 0
229 while 1:
230
231
232
233 if debug > 1:
234 print 'state', state
235 if not lookahead:
236 if not lookaheadstack:
237 lookahead = get_token()
238 else:
239 lookahead = lookaheadstack.pop()
240 if not lookahead:
241 lookahead = YaccSymbol()
242 lookahead.type = '$end'
243 if debug:
244 errorlead = ("%s . %s" % (" ".join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip()
245
246
247 ltype = lookahead.type
248 t = actions[state].get(ltype)
249
250 if debug > 1:
251 print 'action', t
252 if t is not None:
253 if t > 0:
254
255 if ltype == '$end':
256
257 sys.stderr.write("yacc: Parse error. EOF\n")
258 return
259 statestack.append(t)
260 state = t
261 if debug > 1:
262 sys.stderr.write("%-60s shift state %s\n" % (errorlead, t))
263 symstack.append(lookahead)
264 lookahead = None
265
266
267 if errorcount: errorcount -=1
268 continue
269
270 if t < 0:
271
272 p = prod[-t]
273 pname = p.name
274 plen = p.len
275
276
277 sym = YaccSymbol()
278 sym.type = pname
279 sym.value = None
280 if debug > 1:
281 sys.stderr.write("%-60s reduce %d\n" % (errorlead, -t))
282
283 if plen:
284 targ = symstack[-plen-1:]
285 targ[0] = sym
286 if tracking:
287 t1 = targ[1]
288 sym.lineno = t1.lineno
289 sym.lexpos = t1.lexpos
290 t1 = targ[-1]
291 sym.endlineno = getattr(t1,"endlineno",t1.lineno)
292 sym.endlexpos = getattr(t1,"endlexpos",t1.lexpos)
293 del symstack[-plen:]
294 del statestack[-plen:]
295 else:
296 if tracking:
297 sym.lineno = lexer.lineno
298 sym.lexpos = lexer.lexpos
299 targ = [ sym ]
300 pslice.slice = targ
301
302
303 p.func(pslice)
304
305
306 if pslice.pbstack:
307 lookaheadstack.append(lookahead)
308 for _t in pslice.pbstack:
309 lookaheadstack.append(_t)
310 lookahead = None
311 pslice.pbstack = []
312
313 symstack.append(sym)
314 state = goto[statestack[-1]][pname]
315 statestack.append(state)
316 continue
317
318 if t == 0:
319 n = symstack[-1]
320 return getattr(n,"value",None)
321
322 if t == None:
323 if debug:
324 sys.stderr.write(errorlead + "\n")
325
326
327
328
329
330
331
332
333
334
335 if errorcount == 0 or self.errorok:
336 errorcount = error_count
337 self.errorok = 0
338 errtoken = lookahead
339 if errtoken.type == '$end':
340 errtoken = None
341 if self.errorfunc:
342 global errok,token,restart
343 errok = self.errok
344 token = get_token
345 restart = self.restart
346 tok = self.errorfunc(errtoken)
347 del errok, token, restart
348
349 if self.errorok:
350
351
352
353 lookahead = tok
354 errtoken = None
355 continue
356 else:
357 if errtoken:
358 if hasattr(errtoken,"lineno"): lineno = lookahead.lineno
359 else: lineno = 0
360 if lineno:
361 sys.stderr.write("yacc: Syntax error at line %d, token=%s\n" % (lineno, errtoken.type))
362 else:
363 sys.stderr.write("yacc: Syntax error, token=%s" % errtoken.type)
364 else:
365 sys.stderr.write("yacc: Parse error in input. EOF\n")
366 return
367
368 else:
369 errorcount = error_count
370
371
372
373
374
375 if len(statestack) <= 1 and lookahead.type != '$end':
376 lookahead = None
377 errtoken = None
378
379 del lookaheadstack[:]
380 continue
381
382
383
384
385
386 if lookahead.type == '$end':
387
388 return
389
390 if lookahead.type != 'error':
391 sym = symstack[-1]
392 if sym.type == 'error':
393
394
395 lookahead = None
396 continue
397 t = YaccSymbol()
398 t.type = 'error'
399 if hasattr(lookahead,"lineno"):
400 t.lineno = lookahead.lineno
401 t.value = lookahead
402 lookaheadstack.append(lookahead)
403 lookahead = t
404 else:
405 symstack.pop()
406 statestack.pop()
407
408 continue
409
410
411 raise RuntimeError, "yacc: internal parser error!!!\n"
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
436 base,ext = os.path.splitext(filename)
437 if ext != '.py': return 1
438
439 try:
440 f = open(filename)
441 lines = f.readlines()
442 f.close()
443 except IOError:
444 return 1
445
446
447 fre = re.compile(r'\s*def\s+(p_[a-zA-Z_0-9]*)\(')
448 counthash = { }
449 linen = 1
450 noerror = 1
451 for l in lines:
452 m = fre.match(l)
453 if m:
454 name = m.group(1)
455 prev = counthash.get(name)
456 if not prev:
457 counthash[name] = linen
458 else:
459 sys.stderr.write("%s:%d: Function %s redefined. Previously defined on line %d\n" % (filename,linen,name,prev))
460 noerror = 0
461 linen += 1
462 return noerror
463
464
466 for n,v in d.items():
467 if n[0:2] == 'p_' and type(v) in (types.FunctionType, types.MethodType): continue
468 if n[0:2] == 't_': continue
469
470 if n[0:2] == 'p_':
471 sys.stderr.write("yacc: Warning. '%s' not defined as a function\n" % n)
472 if 1 and isinstance(v,types.FunctionType) and v.func_code.co_argcount == 1:
473 try:
474 doc = v.__doc__.split(" ")
475 if doc[1] == ':':
476 sys.stderr.write("%s:%d: Warning. Possible grammar rule '%s' defined without p_ prefix.\n" % (v.func_code.co_filename, v.func_code.co_firstlineno,n))
477 except StandardError:
478 pass
479
480
481
482
483
484
485
486
487
489 global Productions, Prodnames, Prodmap, Terminals
490 global Nonterminals, First, Follow, Precedence, LRitems
491 global Errorfunc, Signature, Requires
492
493 Productions = [None]
494
495
496
497 Prodnames = { }
498
499
500 Prodmap = { }
501
502
503 Terminals = { }
504
505
506 Nonterminals = { }
507
508
509 First = { }
510
511 Follow = { }
512
513 Precedence = { }
514
515
516 LRitems = [ ]
517
518
519 Errorfunc = None
520
521 Signature = md5.new()
522
523
524
525 Requires = { }
526
527
528 global _vf, _vfc
529 _vf = cStringIO.StringIO()
530 _vfc = cStringIO.StringIO()
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
558 for k,v in kw.items():
559 setattr(self,k,v)
560 self.lr_index = -1
561 self.lr0_added = 0
562 self.lr1_added = 0
563 self.usyms = [ ]
564 self.lookaheads = { }
565 self.lk_added = { }
566 self.setnumbers = [ ]
567
569 if self.prod:
570 s = "%s -> %s" % (self.name," ".join(self.prod))
571 else:
572 s = "%s -> <empty>" % self.name
573 return s
574
576 return str(self)
577
578
580 if n > len(self.prod): return None
581 p = Production()
582 p.name = self.name
583 p.prod = list(self.prod)
584 p.number = self.number
585 p.lr_index = n
586 p.lookaheads = { }
587 p.setnumbers = self.setnumbers
588 p.prod.insert(n,".")
589 p.prod = tuple(p.prod)
590 p.len = len(p.prod)
591 p.usyms = self.usyms
592
593
594 try:
595 p.lrafter = Prodnames[p.prod[n+1]]
596 except (IndexError,KeyError),e:
597 p.lrafter = []
598 try:
599 p.lrbefore = p.prod[n-1]
600 except IndexError:
601 p.lrbefore = None
602
603 return p
604
606 pass
607
608
609 _is_identifier = re.compile(r'^[a-zA-Z0-9_-]+$')
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
629
630 if Terminals.has_key(prodname):
631 sys.stderr.write("%s:%d: Illegal rule name '%s'. Already defined as a token.\n" % (file,line,prodname))
632 return -1
633 if prodname == 'error':
634 sys.stderr.write("%s:%d: Illegal rule name '%s'. error is a reserved word.\n" % (file,line,prodname))
635 return -1
636
637 if not _is_identifier.match(prodname):
638 sys.stderr.write("%s:%d: Illegal rule name '%s'\n" % (file,line,prodname))
639 return -1
640
641 for x in range(len(syms)):
642 s = syms[x]
643 if s[0] in "'\"":
644 try:
645 c = eval(s)
646 if (len(c) > 1):
647 sys.stderr.write("%s:%d: Literal token %s in rule '%s' may only be a single character\n" % (file,line,s, prodname))
648 return -1
649 if not Terminals.has_key(c):
650 Terminals[c] = []
651 syms[x] = c
652 continue
653 except SyntaxError:
654 pass
655 if not _is_identifier.match(s) and s != '%prec':
656 sys.stderr.write("%s:%d: Illegal name '%s' in rule '%s'\n" % (file,line,s, prodname))
657 return -1
658
659
660 map = "%s -> %s" % (prodname,syms)
661 if Prodmap.has_key(map):
662 m = Prodmap[map]
663 sys.stderr.write("%s:%d: Duplicate rule %s.\n" % (file,line, m))
664 sys.stderr.write("%s:%d: Previous definition at %s:%d\n" % (file,line, m.file, m.line))
665 return -1
666
667 p = Production()
668 p.name = prodname
669 p.prod = syms
670 p.file = file
671 p.line = line
672 p.func = f
673 p.number = len(Productions)
674
675
676 Productions.append(p)
677 Prodmap[map] = p
678 if not Nonterminals.has_key(prodname):
679 Nonterminals[prodname] = [ ]
680
681
682 i = 0
683 while i < len(p.prod):
684 t = p.prod[i]
685 if t == '%prec':
686 try:
687 precname = p.prod[i+1]
688 except IndexError:
689 sys.stderr.write("%s:%d: Syntax error. Nothing follows %%prec.\n" % (p.file,p.line))
690 return -1
691
692 prec = Precedence.get(precname,None)
693 if not prec:
694 sys.stderr.write("%s:%d: Nothing known about the precedence of '%s'\n" % (p.file,p.line,precname))
695 return -1
696 else:
697 p.prec = prec
698 del p.prod[i]
699 del p.prod[i]
700 continue
701
702 if Terminals.has_key(t):
703 Terminals[t].append(p.number)
704
705 if not hasattr(p,"prec"):
706 p.prec = Precedence.get(t,('right',0))
707 else:
708 if not Nonterminals.has_key(t):
709 Nonterminals[t] = [ ]
710 Nonterminals[t].append(p.number)
711 i += 1
712
713 if not hasattr(p,"prec"):
714 p.prec = ('right',0)
715
716
717 p.len = len(p.prod)
718 p.prod = tuple(p.prod)
719
720
721 p.usyms = [ ]
722 for s in p.prod:
723 if s not in p.usyms:
724 p.usyms.append(s)
725
726
727 try:
728 Prodnames[p.name].append(p)
729 except KeyError:
730 Prodnames[p.name] = [ p ]
731 return 0
732
733
734
735
737 line = f.func_code.co_firstlineno
738 file = f.func_code.co_filename
739 error = 0
740
741 if isinstance(f,types.MethodType):
742 reqdargs = 2
743 else:
744 reqdargs = 1
745
746 if f.func_code.co_argcount > reqdargs:
747 sys.stderr.write("%s:%d: Rule '%s' has too many arguments.\n" % (file,line,f.__name__))
748 return -1
749
750 if f.func_code.co_argcount < reqdargs:
751 sys.stderr.write("%s:%d: Rule '%s' requires an argument.\n" % (file,line,f.__name__))
752 return -1
753
754 if f.__doc__:
755
756 pstrings = f.__doc__.splitlines()
757 lastp = None
758 dline = line
759 for ps in pstrings:
760 dline += 1
761 p = ps.split()
762 if not p: continue
763 try:
764 if p[0] == '|':
765
766 if not lastp:
767 sys.stderr.write("%s:%d: Misplaced '|'.\n" % (file,dline))
768 return -1
769 prodname = lastp
770 if len(p) > 1:
771 syms = p[1:]
772 else:
773 syms = [ ]
774 else:
775 prodname = p[0]
776 lastp = prodname
777 assign = p[1]
778 if len(p) > 2:
779 syms = p[2:]
780 else:
781 syms = [ ]
782 if assign != ':' and assign != '::=':
783 sys.stderr.write("%s:%d: Syntax error. Expected ':'\n" % (file,dline))
784 return -1
785
786
787 e = add_production(f,file,dline,prodname,syms)
788 error += e
789
790
791 except StandardError:
792 sys.stderr.write("%s:%d: Syntax error in rule '%s'\n" % (file,dline,ps))
793 error -= 1
794 else:
795 sys.stderr.write("%s:%d: No documentation string specified in function '%s'\n" % (file,line,f.__name__))
796 return error
797
798
799
800
802 '''
803 Find each symbol that can be reached from the start symbol.
804 Print a warning for any nonterminals that can't be reached.
805 (Unused terminals have already had their warning.)
806 '''
807 Reachable = { }
808 for s in Terminals.keys() + Nonterminals.keys():
809 Reachable[s] = 0
810
811 mark_reachable_from( Productions[0].prod[0], Reachable )
812
813 for s in Nonterminals.keys():
814 if not Reachable[s]:
815 sys.stderr.write("yacc: Symbol '%s' is unreachable.\n" % s)
816
818 '''
819 Mark all symbols that are reachable from symbol s.
820 '''
821 if Reachable[s]:
822
823 return
824 Reachable[s] = 1
825 for p in Prodnames.get(s,[]):
826 for r in p.prod:
827 mark_reachable_from(r, Reachable)
828
829
830
831
832
833
834
835
837 '''
838 Raise an error for any symbols that don't terminate.
839 '''
840 Terminates = {}
841
842
843 for t in Terminals.keys():
844 Terminates[t] = 1
845
846 Terminates['$end'] = 1
847
848
849
850
851 for n in Nonterminals.keys():
852 Terminates[n] = 0
853
854
855 while 1:
856 some_change = 0
857 for (n,pl) in Prodnames.items():
858
859 for p in pl:
860
861 for s in p.prod:
862 if not Terminates[s]:
863
864
865 p_terminates = 0
866 break
867 else:
868
869
870
871 p_terminates = 1
872
873 if p_terminates:
874
875 if not Terminates[n]:
876 Terminates[n] = 1
877 some_change = 1
878
879 break
880
881 if not some_change:
882 break
883
884 some_error = 0
885 for (s,terminates) in Terminates.items():
886 if not terminates:
887 if not Prodnames.has_key(s) and not Terminals.has_key(s) and s != 'error':
888
889
890 pass
891 else:
892 sys.stderr.write("yacc: Infinite recursion detected for symbol '%s'.\n" % s)
893 some_error = 1
894
895 return some_error
896
897
898
899
900
901
903 error = 0
904 for p in Productions:
905 if not p: continue
906
907 for s in p.prod:
908 if not Prodnames.has_key(s) and not Terminals.has_key(s) and s != 'error':
909 sys.stderr.write("%s:%d: Symbol '%s' used, but not defined as a token or a rule.\n" % (p.file,p.line,s))
910 error = 1
911 continue
912
913 unused_tok = 0
914
915 if yaccdebug:
916 _vf.write("Unused terminals:\n\n")
917 for s,v in Terminals.items():
918 if s != 'error' and not v:
919 sys.stderr.write("yacc: Warning. Token '%s' defined, but not used.\n" % s)
920 if yaccdebug: _vf.write(" %s\n"% s)
921 unused_tok += 1
922
923
924 if yaccdebug:
925 _vf.write("\nGrammar\n\n")
926 for i in range(1,len(Productions)):
927 _vf.write("Rule %-5d %s\n" % (i, Productions[i]))
928
929 unused_prod = 0
930
931 for s,v in Nonterminals.items():
932 if not v:
933 p = Prodnames[s][0]
934
935 unused_prod += 1
936
937
938 if unused_tok == 1:
939 sys.stderr.write("yacc: Warning. There is 1 unused token.\n")
940 if unused_tok > 1:
941 sys.stderr.write("yacc: Warning. There are %d unused tokens.\n" % unused_tok)
942
943
944
945
946
947
948 if yaccdebug:
949 _vf.write("\nTerminals, with rules where they appear\n\n")
950 ks = Terminals.keys()
951 ks.sort()
952 for k in ks:
953 _vf.write("%-20s : %s\n" % (k, " ".join([str(s) for s in Terminals[k]])))
954 _vf.write("\nNonterminals, with rules where they appear\n\n")
955 ks = Nonterminals.keys()
956 ks.sort()
957 for k in ks:
958 _vf.write("%-20s : %s\n" % (k, " ".join([str(s) for s in Nonterminals[k]])))
959
960 if (cycle_check):
961 compute_reachable()
962 error += compute_terminates()
963
964 return error
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
982 for p in Productions:
983 lastlri = p
984 lri = p.lr_item(0)
985 i = 0
986 while 1:
987 lri = p.lr_item(i)
988 lastlri.lr_next = lri
989 if not lri: break
990 lri.lr_num = len(LRitems)
991 LRitems.append(lri)
992 lastlri = lri
993 i += 1
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1007 plevel = 0
1008 error = 0
1009 for p in plist:
1010 plevel += 1
1011 try:
1012 prec = p[0]
1013 terms = p[1:]
1014 if prec != 'left' and prec != 'right' and prec != 'nonassoc':
1015 sys.stderr.write("yacc: Invalid precedence '%s'\n" % prec)
1016 return -1
1017 for t in terms:
1018 if Precedence.has_key(t):
1019 sys.stderr.write("yacc: Precedence already specified for terminal '%s'\n" % t)
1020 error += 1
1021 continue
1022 Precedence[t] = (prec,plevel)
1023 except:
1024 sys.stderr.write("yacc: Invalid precedence table.\n")
1025 error += 1
1026
1027 return error
1028
1029
1030
1031
1032
1033
1034
1035
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1053
1054
1055 result = [ ]
1056 for x in beta:
1057 x_produces_empty = 0
1058
1059
1060 for f in First[x]:
1061 if f == '<empty>':
1062 x_produces_empty = 1
1063 else:
1064 if f not in result: result.append(f)
1065
1066 if x_produces_empty:
1067
1068
1069 pass
1070 else:
1071
1072 break
1073 else:
1074
1075
1076
1077 result.append('<empty>')
1078
1079 return result
1080
1081
1082
1083
1084
1085
1087
1088 for k in Nonterminals.keys():
1089 Follow[k] = [ ]
1090
1091 if not start:
1092 start = Productions[1].name
1093
1094 Follow[start] = [ '$end' ]
1095
1096 while 1:
1097 didadd = 0
1098 for p in Productions[1:]:
1099
1100 for i in range(len(p.prod)):
1101 B = p.prod[i]
1102 if Nonterminals.has_key(B):
1103
1104 fst = first(p.prod[i+1:])
1105 hasempty = 0
1106 for f in fst:
1107 if f != '<empty>' and f not in Follow[B]:
1108 Follow[B].append(f)
1109 didadd = 1
1110 if f == '<empty>':
1111 hasempty = 1
1112 if hasempty or i == (len(p.prod)-1):
1113
1114 for f in Follow[p.name]:
1115 if f not in Follow[B]:
1116 Follow[B].append(f)
1117 didadd = 1
1118 if not didadd: break
1119
1120 if 0 and yaccdebug:
1121 _vf.write('\nFollow:\n')
1122 for k in Nonterminals.keys():
1123 _vf.write("%-20s : %s\n" % (k, " ".join([str(s) for s in Follow[k]])))
1124
1125
1126
1127
1128
1129
1131
1132
1133 for t in Terminals.keys():
1134 First[t] = [t]
1135
1136 First['$end'] = ['$end']
1137 First['#'] = ['#']
1138
1139
1140
1141
1142 for n in Nonterminals.keys():
1143 First[n] = []
1144
1145
1146 while 1:
1147 some_change = 0
1148 for n in Nonterminals.keys():
1149 for p in Prodnames[n]:
1150 for f in first(p.prod):
1151 if f not in First[n]:
1152 First[n].append( f )
1153 some_change = 1
1154 if not some_change:
1155 break
1156
1157 if 0 and yaccdebug:
1158 _vf.write('\nFirst:\n')
1159 for k in Nonterminals.keys():
1160 _vf.write("%-20s : %s\n" %
1161 (k, " ".join([str(s) for s in First[k]])))
1162
1163
1164
1165
1166
1167
1168
1169
1170
1172 global _lr_action, _lr_goto, _lr_method
1173 global _lr_goto_cache, _lr0_cidhash
1174
1175 _lr_action = { }
1176 _lr_goto = { }
1177 _lr_method = "Unknown"
1178 _lr_goto_cache = { }
1179 _lr0_cidhash = { }
1180
1181
1182
1183
1184
1185 _add_count = 0
1186
1188 global _add_count
1189
1190 _add_count += 1
1191 prodlist = Productions
1192
1193
1194 J = I[:]
1195 didadd = 1
1196 while didadd:
1197 didadd = 0
1198 for j in J:
1199 for x in j.lrafter:
1200 if x.lr0_added == _add_count: continue
1201
1202 J.append(x.lr_next)
1203 x.lr0_added = _add_count
1204 didadd = 1
1205
1206 return J
1207
1208
1209
1210
1211
1212
1213
1214
1216
1217 g = _lr_goto_cache.get((id(I),x),None)
1218 if g: return g
1219
1220
1221
1222
1223 s = _lr_goto_cache.get(x,None)
1224 if not s:
1225 s = { }
1226 _lr_goto_cache[x] = s
1227
1228 gs = [ ]
1229 for p in I:
1230 n = p.lr_next
1231 if n and n.lrbefore == x:
1232 s1 = s.get(id(n),None)
1233 if not s1:
1234 s1 = { }
1235 s[id(n)] = s1
1236 gs.append(n)
1237 s = s1
1238 g = s.get('$end',None)
1239 if not g:
1240 if gs:
1241 g = lr0_closure(gs)
1242 s['$end'] = g
1243 else:
1244 s['$end'] = gs
1245 _lr_goto_cache[(id(I),x)] = g
1246 return g
1247
1248 _lr0_cidhash = { }
1249
1250
1252
1253 C = [ lr0_closure([Productions[0].lr_next]) ]
1254 i = 0
1255 for I in C:
1256 _lr0_cidhash[id(I)] = i
1257 i += 1
1258
1259
1260 i = 0
1261 while i < len(C):
1262 I = C[i]
1263 i += 1
1264
1265
1266 asyms = { }
1267 for ii in I:
1268 for s in ii.usyms:
1269 asyms[s] = None
1270
1271 for x in asyms.keys():
1272 g = lr0_goto(I,x)
1273 if not g: continue
1274 if _lr0_cidhash.has_key(id(g)): continue
1275 _lr0_cidhash[id(g)] = len(C)
1276 C.append(g)
1277
1278 return C
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1312 nullable = {}
1313 num_nullable = 0
1314 while 1:
1315 for p in Productions[1:]:
1316 if p.len == 0:
1317 nullable[p.name] = 1
1318 continue
1319 for t in p.prod:
1320 if not nullable.has_key(t): break
1321 else:
1322 nullable[p.name] = 1
1323 if len(nullable) == num_nullable: break
1324 num_nullable = len(nullable)
1325 return nullable
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1339 trans = []
1340 for state in range(len(C)):
1341 for p in C[state]:
1342 if p.lr_index < p.len - 1:
1343 t = (state,p.prod[p.lr_index+1])
1344 if Nonterminals.has_key(t[1]):
1345 if t not in trans: trans.append(t)
1346 state = state + 1
1347 return trans
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1359 dr_set = { }
1360 state,N = trans
1361 terms = []
1362
1363 g = lr0_goto(C[state],N)
1364 for p in g:
1365 if p.lr_index < p.len - 1:
1366 a = p.prod[p.lr_index+1]
1367 if Terminals.has_key(a):
1368 if a not in terms: terms.append(a)
1369
1370
1371 if state == 0 and N == Productions[0].prod[0]:
1372 terms.append('$end')
1373
1374 return terms
1375
1376
1377
1378
1379
1380
1381
1383
1384 rel = []
1385 state, N = trans
1386
1387 g = lr0_goto(C[state],N)
1388 j = _lr0_cidhash.get(id(g),-1)
1389 for p in g:
1390 if p.lr_index < p.len - 1:
1391 a = p.prod[p.lr_index + 1]
1392 if empty.has_key(a):
1393 rel.append((j,a))
1394
1395 return rel
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1426
1427 lookdict = {}
1428 includedict = {}
1429
1430
1431 dtrans = {}
1432 for t in trans:
1433 dtrans[t] = 1
1434
1435
1436 for state,N in trans:
1437 lookb = []
1438 includes = []
1439 for p in C[state]:
1440 if p.name != N: continue
1441
1442
1443
1444
1445 lr_index = p.lr_index
1446 j = state
1447 while lr_index < p.len - 1:
1448 lr_index = lr_index + 1
1449 t = p.prod[lr_index]
1450
1451
1452 if dtrans.has_key((j,t)):
1453
1454
1455
1456
1457 li = lr_index + 1
1458 while li < p.len:
1459 if Terminals.has_key(p.prod[li]): break
1460 if not nullable.has_key(p.prod[li]): break
1461 li = li + 1
1462 else:
1463
1464 includes.append((j,t))
1465
1466 g = lr0_goto(C[j],t)
1467 j = _lr0_cidhash.get(id(g),-1)
1468
1469
1470 for r in C[j]:
1471 if r.name != p.name: continue
1472 if r.len != p.len: continue
1473 i = 0
1474
1475 while i < r.lr_index:
1476 if r.prod[i] != p.prod[i+1]: break
1477 i = i + 1
1478 else:
1479 lookb.append((j,r))
1480 for i in includes:
1481 if not includedict.has_key(i): includedict[i] = []
1482 includedict[i].append((state,N))
1483 lookdict[(state,N)] = lookb
1484
1485 return lookdict,includedict
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1505 N = { }
1506 for x in X:
1507 N[x] = 0
1508 stack = []
1509 F = { }
1510 for x in X:
1511 if N[x] == 0: traverse(x,N,stack,F,X,R,FP)
1512 return F
1513
1515 stack.append(x)
1516 d = len(stack)
1517 N[x] = d
1518 F[x] = FP(x)
1519
1520 rel = R(x)
1521 for y in rel:
1522 if N[y] == 0:
1523 traverse(y,N,stack,F,X,R,FP)
1524 N[x] = min(N[x],N[y])
1525 for a in F.get(y,[]):
1526 if a not in F[x]: F[x].append(a)
1527 if N[x] == d:
1528 N[stack[-1]] = sys.maxint
1529 F[stack[-1]] = F[x]
1530 element = stack.pop()
1531 while element != x:
1532 N[stack[-1]] = sys.maxint
1533 F[stack[-1]] = F[x]
1534 element = stack.pop()
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1571 FP = lambda x: readsets[x]
1572 R = lambda x: inclsets.get(x,[])
1573 F = digraph(ntrans,R,FP)
1574 return F
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1589 for trans,lb in lookbacks.items():
1590
1591 for state,p in lb:
1592 if not p.lookaheads.has_key(state):
1593 p.lookaheads[state] = []
1594 f = followset.get(trans,[])
1595 for a in f:
1596 if a not in p.lookaheads[state]: p.lookaheads[state].append(a)
1597
1598
1599
1600
1601
1602
1603
1604
1623
1624
1625
1626
1627
1628
1630 global _lr_method
1631 goto = _lr_goto
1632 action = _lr_action
1633 actionp = { }
1634
1635 _lr_method = method
1636
1637 n_srconflict = 0
1638 n_rrconflict = 0
1639
1640 if yaccdebug:
1641 sys.stderr.write("yacc: Generating %s parsing table...\n" % method)
1642 _vf.write("\n\nParsing method: %s\n\n" % method)
1643
1644
1645
1646
1647 C = lr0_items()
1648
1649 if method == 'LALR':
1650 add_lalr_lookaheads(C)
1651
1652
1653
1654 st = 0
1655 for I in C:
1656
1657 actlist = [ ]
1658 st_action = { }
1659 st_actionp = { }
1660 st_goto = { }
1661 if yaccdebug:
1662 _vf.write("\nstate %d\n\n" % st)
1663 for p in I:
1664 _vf.write(" (%d) %s\n" % (p.number, str(p)))
1665 _vf.write("\n")
1666
1667 for p in I:
1668 try:
1669 if p.len == p.lr_index + 1:
1670 if p.name == "S'":
1671
1672 st_action["$end"] = 0
1673 st_actionp["$end"] = p
1674 else:
1675
1676 if method == 'LALR':
1677 laheads = p.lookaheads[st]
1678 else:
1679 laheads = Follow[p.name]
1680 for a in laheads:
1681 actlist.append((a,p,"reduce using rule %d (%s)" % (p.number,p)))
1682 r = st_action.get(a,None)
1683 if r is not None:
1684
1685 if r > 0:
1686
1687
1688
1689 sprec,slevel = Productions[st_actionp[a].number].prec
1690 rprec,rlevel = Precedence.get(a,('right',0))
1691 if (slevel < rlevel) or ((slevel == rlevel) and (rprec == 'left')):
1692
1693 st_action[a] = -p.number
1694 st_actionp[a] = p
1695 if not slevel and not rlevel:
1696 _vfc.write("shift/reduce conflict in state %d resolved as reduce.\n" % st)
1697 _vf.write(" ! shift/reduce conflict for %s resolved as reduce.\n" % a)
1698 n_srconflict += 1
1699 elif (slevel == rlevel) and (rprec == 'nonassoc'):
1700 st_action[a] = None
1701 else:
1702
1703 if not rlevel:
1704 _vfc.write("shift/reduce conflict in state %d resolved as shift.\n" % st)
1705 _vf.write(" ! shift/reduce conflict for %s resolved as shift.\n" % a)
1706 n_srconflict +=1
1707 elif r < 0:
1708
1709
1710 oldp = Productions[-r]
1711 pp = Productions[p.number]
1712 if oldp.line > pp.line:
1713 st_action[a] = -p.number
1714 st_actionp[a] = p
1715
1716 n_rrconflict += 1
1717 _vfc.write("reduce/reduce conflict in state %d resolved using rule %d (%s).\n" % (st, st_actionp[a].number, st_actionp[a]))
1718 _vf.write(" ! reduce/reduce conflict for %s resolved using rule %d (%s).\n" % (a,st_actionp[a].number, st_actionp[a]))
1719 else:
1720 sys.stderr.write("Unknown conflict in state %d\n" % st)
1721 else:
1722 st_action[a] = -p.number
1723 st_actionp[a] = p
1724 else:
1725 i = p.lr_index
1726 a = p.prod[i+1]
1727 if Terminals.has_key(a):
1728 g = lr0_goto(I,a)
1729 j = _lr0_cidhash.get(id(g),-1)
1730 if j >= 0:
1731
1732 actlist.append((a,p,"shift and go to state %d" % j))
1733 r = st_action.get(a,None)
1734 if r is not None:
1735
1736 if r > 0:
1737 if r != j:
1738 sys.stderr.write("Shift/shift conflict in state %d\n" % st)
1739 elif r < 0:
1740
1741
1742
1743
1744 rprec,rlevel = Productions[st_actionp[a].number].prec
1745 sprec,slevel = Precedence.get(a,('right',0))
1746 if (slevel > rlevel) or ((slevel == rlevel) and (rprec != 'left')):
1747
1748 st_action[a] = j
1749 st_actionp[a] = p
1750 if not rlevel:
1751 n_srconflict += 1
1752 _vfc.write("shift/reduce conflict in state %d resolved as shift.\n" % st)
1753 _vf.write(" ! shift/reduce conflict for %s resolved as shift.\n" % a)
1754 elif (slevel == rlevel) and (rprec == 'nonassoc'):
1755 st_action[a] = None
1756 else:
1757
1758 if not slevel and not rlevel:
1759 n_srconflict +=1
1760 _vfc.write("shift/reduce conflict in state %d resolved as reduce.\n" % st)
1761 _vf.write(" ! shift/reduce conflict for %s resolved as reduce.\n" % a)
1762
1763 else:
1764 sys.stderr.write("Unknown conflict in state %d\n" % st)
1765 else:
1766 st_action[a] = j
1767 st_actionp[a] = p
1768
1769 except StandardError,e:
1770 print sys.exc_info()
1771 raise YaccError, "Hosed in lr_parse_table"
1772
1773
1774 if yaccdebug:
1775 _actprint = { }
1776 for a,p,m in actlist:
1777 if st_action.has_key(a):
1778 if p is st_actionp[a]:
1779 _vf.write(" %-15s %s\n" % (a,m))
1780 _actprint[(a,m)] = 1
1781 _vf.write("\n")
1782 for a,p,m in actlist:
1783 if st_action.has_key(a):
1784 if p is not st_actionp[a]:
1785 if not _actprint.has_key((a,m)):
1786 _vf.write(" ! %-15s [ %s ]\n" % (a,m))
1787 _actprint[(a,m)] = 1
1788
1789
1790 if yaccdebug:
1791 _vf.write("\n")
1792 nkeys = { }
1793 for ii in I:
1794 for s in ii.usyms:
1795 if Nonterminals.has_key(s):
1796 nkeys[s] = None
1797 for n in nkeys.keys():
1798 g = lr0_goto(I,n)
1799 j = _lr0_cidhash.get(id(g),-1)
1800 if j >= 0:
1801 st_goto[n] = j
1802 if yaccdebug:
1803 _vf.write(" %-30s shift and go to state %d\n" % (n,j))
1804
1805 action[st] = st_action
1806 actionp[st] = st_actionp
1807 goto[st] = st_goto
1808
1809 st += 1
1810
1811 if yaccdebug:
1812 if n_srconflict == 1:
1813 sys.stderr.write("yacc: %d shift/reduce conflict\n" % n_srconflict)
1814 if n_srconflict > 1:
1815 sys.stderr.write("yacc: %d shift/reduce conflicts\n" % n_srconflict)
1816 if n_rrconflict == 1:
1817 sys.stderr.write("yacc: %d reduce/reduce conflict\n" % n_rrconflict)
1818 if n_rrconflict > 1:
1819 sys.stderr.write("yacc: %d reduce/reduce conflicts\n" % n_rrconflict)
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1832 filename = os.path.join(outputdir,modulename) + ".py"
1833 try:
1834 f = open(filename,"w")
1835
1836 f.write("""
1837 # %s
1838 # This file is automatically generated. Do not edit.
1839
1840 _lr_method = %s
1841
1842 _lr_signature = %s
1843 """ % (filename, repr(_lr_method), repr(Signature.digest())))
1844
1845
1846 smaller = 1
1847
1848
1849 if smaller:
1850 items = { }
1851
1852 for s,nd in _lr_action.items():
1853 for name,v in nd.items():
1854 i = items.get(name)
1855 if not i:
1856 i = ([],[])
1857 items[name] = i
1858 i[0].append(s)
1859 i[1].append(v)
1860
1861 f.write("\n_lr_action_items = {")
1862 for k,v in items.items():
1863 f.write("%r:([" % k)
1864 for i in v[0]:
1865 f.write("%r," % i)
1866 f.write("],[")
1867 for i in v[1]:
1868 f.write("%r," % i)
1869
1870 f.write("]),")
1871 f.write("}\n")
1872
1873 f.write("""
1874 _lr_action = { }
1875 for _k, _v in _lr_action_items.items():
1876 for _x,_y in zip(_v[0],_v[1]):
1877 if not _lr_action.has_key(_x): _lr_action[_x] = { }
1878 _lr_action[_x][_k] = _y
1879 del _lr_action_items
1880 """)
1881
1882 else:
1883 f.write("\n_lr_action = { ");
1884 for k,v in _lr_action.items():
1885 f.write("(%r,%r):%r," % (k[0],k[1],v))
1886 f.write("}\n");
1887
1888 if smaller:
1889
1890 items = { }
1891
1892 for s,nd in _lr_goto.items():
1893 for name,v in nd.items():
1894 i = items.get(name)
1895 if not i:
1896 i = ([],[])
1897 items[name] = i
1898 i[0].append(s)
1899 i[1].append(v)
1900
1901 f.write("\n_lr_goto_items = {")
1902 for k,v in items.items():
1903 f.write("%r:([" % k)
1904 for i in v[0]:
1905 f.write("%r," % i)
1906 f.write("],[")
1907 for i in v[1]:
1908 f.write("%r," % i)
1909
1910 f.write("]),")
1911 f.write("}\n")
1912
1913 f.write("""
1914 _lr_goto = { }
1915 for _k, _v in _lr_goto_items.items():
1916 for _x,_y in zip(_v[0],_v[1]):
1917 if not _lr_goto.has_key(_x): _lr_goto[_x] = { }
1918 _lr_goto[_x][_k] = _y
1919 del _lr_goto_items
1920 """)
1921 else:
1922 f.write("\n_lr_goto = { ");
1923 for k,v in _lr_goto.items():
1924 f.write("(%r,%r):%r," % (k[0],k[1],v))
1925 f.write("}\n");
1926
1927
1928 f.write("_lr_productions = [\n")
1929 for p in Productions:
1930 if p:
1931 if (p.func):
1932 f.write(" (%r,%d,%r,%r,%d),\n" % (p.name, p.len, p.func.__name__,p.file,p.line))
1933 else:
1934 f.write(" (%r,%d,None,None,None),\n" % (p.name, p.len))
1935 else:
1936 f.write(" None,\n")
1937 f.write("]\n")
1938
1939 f.close()
1940
1941 except IOError,e:
1942 print >>sys.stderr, "Unable to create '%s'" % filename
1943 print >>sys.stderr, e
1944 return
1945
1947 global _lr_action, _lr_goto, _lr_productions, _lr_method
1948 try:
1949 exec "import %s as parsetab" % module
1950
1951 if (optimize) or (Signature.digest() == parsetab._lr_signature):
1952 _lr_action = parsetab._lr_action
1953 _lr_goto = parsetab._lr_goto
1954 _lr_productions = parsetab._lr_productions
1955 _lr_method = parsetab._lr_method
1956 return 1
1957 else:
1958 return 0
1959
1960 except (ImportError,AttributeError):
1961 return 0
1962
1963
1964
1965
1966
1967
1968
1969
1971 global yaccdebug
1972 yaccdebug = debug
1973
1974 initialize_vars()
1975 files = { }
1976 error = 0
1977
1978
1979
1980 Signature.update(method)
1981
1982
1983
1984
1985 if module:
1986
1987 if isinstance(module, types.ModuleType):
1988 ldict = module.__dict__
1989 elif isinstance(module, _INSTANCETYPE):
1990 _items = [(k,getattr(module,k)) for k in dir(module)]
1991 ldict = { }
1992 for i in _items:
1993 ldict[i[0]] = i[1]
1994 else:
1995 raise ValueError,"Expected a module"
1996
1997 else:
1998
1999
2000
2001 try:
2002 raise RuntimeError
2003 except RuntimeError:
2004 e,b,t = sys.exc_info()
2005 f = t.tb_frame
2006 f = f.f_back
2007 ldict = f.f_globals
2008
2009
2010 if not start:
2011 start = ldict.get("start",None)
2012 if start:
2013 Signature.update(start)
2014
2015
2016
2017 if (optimize and lr_read_tables(tabmodule,1)):
2018
2019 del Productions[:]
2020 for p in _lr_productions:
2021 if not p:
2022 Productions.append(None)
2023 else:
2024 m = MiniProduction()
2025 m.name = p[0]
2026 m.len = p[1]
2027 m.file = p[3]
2028 m.line = p[4]
2029 if p[2]:
2030 m.func = ldict[p[2]]
2031 Productions.append(m)
2032
2033 else:
2034
2035 if (module and isinstance(module,_INSTANCETYPE)):
2036 tokens = getattr(module,"tokens",None)
2037 else:
2038 tokens = ldict.get("tokens",None)
2039
2040 if not tokens:
2041 raise YaccError,"module does not define a list 'tokens'"
2042 if not (isinstance(tokens,types.ListType) or isinstance(tokens,types.TupleType)):
2043 raise YaccError,"tokens must be a list or tuple."
2044
2045
2046 requires = ldict.get("require",None)
2047 if requires:
2048 if not (isinstance(requires,types.DictType)):
2049 raise YaccError,"require must be a dictionary."
2050
2051 for r,v in requires.items():
2052 try:
2053 if not (isinstance(v,types.ListType)):
2054 raise TypeError
2055 v1 = [x.split(".") for x in v]
2056 Requires[r] = v1
2057 except StandardError:
2058 print >>sys.stderr, "Invalid specification for rule '%s' in require. Expected a list of strings" % r
2059
2060
2061
2062
2063
2064
2065 if 'error' in tokens:
2066 print >>sys.stderr, "yacc: Illegal token 'error'. Is a reserved word."
2067 raise YaccError,"Illegal token name"
2068
2069 for n in tokens:
2070 if Terminals.has_key(n):
2071 print >>sys.stderr, "yacc: Warning. Token '%s' multiply defined." % n
2072 Terminals[n] = [ ]
2073
2074 Terminals['error'] = [ ]
2075
2076
2077 prec = ldict.get("precedence",None)
2078 if prec:
2079 if not (isinstance(prec,types.ListType) or isinstance(prec,types.TupleType)):
2080 raise YaccError,"precedence must be a list or tuple."
2081 add_precedence(prec)
2082 Signature.update(repr(prec))
2083
2084 for n in tokens:
2085 if not Precedence.has_key(n):
2086 Precedence[n] = ('right',0)
2087
2088
2089 ef = ldict.get('p_error',None)
2090 if ef:
2091 if isinstance(ef,types.FunctionType):
2092 ismethod = 0
2093 elif isinstance(ef, types.MethodType):
2094 ismethod = 1
2095 else:
2096 raise YaccError,"'p_error' defined, but is not a function or method."
2097 eline = ef.func_code.co_firstlineno
2098 efile = ef.func_code.co_filename
2099 files[efile] = None
2100
2101 if (ef.func_code.co_argcount != 1+ismethod):
2102 raise YaccError,"%s:%d: p_error() requires 1 argument." % (efile,eline)
2103 global Errorfunc
2104 Errorfunc = ef
2105 else:
2106 print >>sys.stderr, "yacc: Warning. no p_error() function is defined."
2107
2108
2109 symbols = [ldict[f] for f in ldict.keys()
2110 if (type(ldict[f]) in (types.FunctionType, types.MethodType) and ldict[f].__name__[:2] == 'p_'
2111 and ldict[f].__name__ != 'p_error')]
2112
2113
2114 if len(symbols) == 0:
2115 raise YaccError,"no rules of the form p_rulename are defined."
2116
2117
2118 symbols.sort(lambda x,y: cmp(x.func_code.co_firstlineno,y.func_code.co_firstlineno))
2119
2120
2121 for f in symbols:
2122 if (add_function(f)) < 0:
2123 error += 1
2124 else:
2125 files[f.func_code.co_filename] = None
2126
2127
2128 for f in symbols:
2129 if f.__doc__:
2130 Signature.update(f.__doc__)
2131
2132 lr_init_vars()
2133
2134 if error:
2135 raise YaccError,"Unable to construct parser."
2136
2137 if not lr_read_tables(tabmodule):
2138
2139
2140 for filename in files.keys():
2141 if not validate_file(filename):
2142 error = 1
2143
2144
2145 validate_dict(ldict)
2146
2147 if start and not Prodnames.has_key(start):
2148 raise YaccError,"Bad starting symbol '%s'" % start
2149
2150 augment_grammar(start)
2151 error = verify_productions(cycle_check=check_recursion)
2152 otherfunc = [ldict[f] for f in ldict.keys()
2153 if (type(f) in (types.FunctionType,types.MethodType) and ldict[f].__name__[:2] != 'p_')]
2154
2155 if error:
2156 raise YaccError,"Unable to construct parser."
2157
2158 build_lritems()
2159 compute_first1()
2160 compute_follow(start)
2161
2162 if method in ['SLR','LALR']:
2163 lr_parse_table(method)
2164 else:
2165 raise YaccError, "Unknown parsing method '%s'" % method
2166
2167 if write_tables:
2168 lr_write_tables(tabmodule,outputdir)
2169
2170 if yaccdebug:
2171 try:
2172 f = open(os.path.join(outputdir,debugfile),"w")
2173 f.write(_vfc.getvalue())
2174 f.write("\n\n")
2175 f.write(_vf.getvalue())
2176 f.close()
2177 except IOError,e:
2178 print >>sys.stderr, "yacc: can't create '%s'" % debugfile,e
2179
2180
2181
2182
2183 p = Parser("xyzzy")
2184 p.productions = Productions
2185 p.errorfunc = Errorfunc
2186 p.action = _lr_action
2187 p.goto = _lr_goto
2188 p.method = _lr_method
2189 p.require = Requires
2190
2191 global parse
2192 parse = p.parse
2193
2194 global parser
2195 parser = p
2196
2197
2198 if (not optimize):
2199 yacc_cleanup()
2200 return p
2201
2202
2203
2204
2206 global _lr_action, _lr_goto, _lr_method, _lr_goto_cache
2207 del _lr_action, _lr_goto, _lr_method, _lr_goto_cache
2208
2209 global Productions, Prodnames, Prodmap, Terminals
2210 global Nonterminals, First, Follow, Precedence, LRitems
2211 global Errorfunc, Signature, Requires
2212
2213 del Productions, Prodnames, Prodmap, Terminals
2214 del Nonterminals, First, Follow, Precedence, LRitems
2215 del Errorfunc, Signature, Requires
2216
2217 global _vf, _vfc
2218 del _vf, _vfc
2219
2220
2221
2222 -def parse(*args,**kwargs):
2223 raise YaccError, "yacc: No parser built with yacc()"
2224