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