annotate ply-3.8/ply/yacc.py @ 12285:69f123e9b0a2 draft

<b_jonas> STOP
author HackEso <hackeso@esolangs.org>
date Wed, 01 Jan 2020 09:35:37 +0000
parents 343ff337a19b
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7267
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2 # ply: yacc.py
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
4 # Copyright (C) 2001-2015,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
5 # David M. Beazley (Dabeaz LLC)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
6 # All rights reserved.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
7 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
8 # Redistribution and use in source and binary forms, with or without
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
9 # modification, are permitted provided that the following conditions are
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
10 # met:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
11 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
12 # * Redistributions of source code must retain the above copyright notice,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
13 # this list of conditions and the following disclaimer.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
14 # * Redistributions in binary form must reproduce the above copyright notice,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
15 # this list of conditions and the following disclaimer in the documentation
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
16 # and/or other materials provided with the distribution.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
17 # * Neither the name of the David Beazley or Dabeaz LLC may be used to
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
18 # endorse or promote products derived from this software without
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
19 # specific prior written permission.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
20 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
22 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
23 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
24 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
25 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
26 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
27 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
28 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
29 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
30 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
31 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
32 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
33 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
34 # This implements an LR parser that is constructed from grammar rules defined
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
35 # as Python functions. The grammer is specified by supplying the BNF inside
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
36 # Python documentation strings. The inspiration for this technique was borrowed
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
37 # from John Aycock's Spark parsing system. PLY might be viewed as cross between
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
38 # Spark and the GNU bison utility.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
39 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
40 # The current implementation is only somewhat object-oriented. The
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
41 # LR parser itself is defined in terms of an object (which allows multiple
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
42 # parsers to co-exist). However, most of the variables used during table
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
43 # construction are defined in terms of global variables. Users shouldn't
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
44 # notice unless they are trying to define multiple parsers at the same
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
45 # time using threads (in which case they should have their head examined).
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
46 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
47 # This implementation supports both SLR and LALR(1) parsing. LALR(1)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
48 # support was originally implemented by Elias Ioup (ezioup@alumni.uchicago.edu),
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
49 # using the algorithm found in Aho, Sethi, and Ullman "Compilers: Principles,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
50 # Techniques, and Tools" (The Dragon Book). LALR(1) has since been replaced
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
51 # by the more efficient DeRemer and Pennello algorithm.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
52 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
53 # :::::::: WARNING :::::::
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
54 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
55 # Construction of LR parsing tables is fairly complicated and expensive.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
56 # To make this module run fast, a *LOT* of work has been put into
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
57 # optimization---often at the expensive of readability and what might
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
58 # consider to be good Python "coding style." Modify the code at your
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
59 # own risk!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
60 # ----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
61
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
62 import re
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
63 import types
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
64 import sys
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
65 import os.path
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
66 import inspect
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
67 import base64
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
68 import warnings
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
69
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
70 __version__ = '3.8'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
71 __tabversion__ = '3.8'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
72
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
73 #-----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
74 # === User configurable parameters ===
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
75 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
76 # Change these to modify the default behavior of yacc (if you wish)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
77 #-----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
78
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
79 yaccdebug = True # Debugging mode. If set, yacc generates a
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
80 # a 'parser.out' file in the current directory
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
81
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
82 debug_file = 'parser.out' # Default name of the debugging file
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
83 tab_module = 'parsetab' # Default name of the table module
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
84 default_lr = 'LALR' # Default LR table generation method
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
85
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
86 error_count = 3 # Number of symbols that must be shifted to leave recovery mode
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
87
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
88 yaccdevel = False # Set to True if developing yacc. This turns off optimized
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
89 # implementations of certain functions.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
90
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
91 resultlimit = 40 # Size limit of results when running in debug mode.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
92
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
93 pickle_protocol = 0 # Protocol to use when writing pickle files
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
94
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
95 # String type-checking compatibility
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
96 if sys.version_info[0] < 3:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
97 string_types = basestring
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
98 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
99 string_types = str
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
100
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
101 MAXINT = sys.maxsize
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
102
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
103 # This object is a stand-in for a logging object created by the
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
104 # logging module. PLY will use this by default to create things
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
105 # such as the parser.out file. If a user wants more detailed
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
106 # information, they can create their own logging object and pass
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
107 # it into PLY.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
108
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
109 class PlyLogger(object):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
110 def __init__(self, f):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
111 self.f = f
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
112
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
113 def debug(self, msg, *args, **kwargs):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
114 self.f.write((msg % args) + '\n')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
115
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
116 info = debug
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
117
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
118 def warning(self, msg, *args, **kwargs):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
119 self.f.write('WARNING: ' + (msg % args) + '\n')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
120
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
121 def error(self, msg, *args, **kwargs):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
122 self.f.write('ERROR: ' + (msg % args) + '\n')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
123
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
124 critical = debug
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
125
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
126 # Null logger is used when no output is generated. Does nothing.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
127 class NullLogger(object):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
128 def __getattribute__(self, name):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
129 return self
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
130
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
131 def __call__(self, *args, **kwargs):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
132 return self
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
133
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
134 # Exception raised for yacc-related errors
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
135 class YaccError(Exception):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
136 pass
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
137
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
138 # Format the result message that the parser produces when running in debug mode.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
139 def format_result(r):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
140 repr_str = repr(r)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
141 if '\n' in repr_str:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
142 repr_str = repr(repr_str)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
143 if len(repr_str) > resultlimit:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
144 repr_str = repr_str[:resultlimit] + ' ...'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
145 result = '<%s @ 0x%x> (%s)' % (type(r).__name__, id(r), repr_str)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
146 return result
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
147
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
148 # Format stack entries when the parser is running in debug mode
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
149 def format_stack_entry(r):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
150 repr_str = repr(r)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
151 if '\n' in repr_str:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
152 repr_str = repr(repr_str)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
153 if len(repr_str) < 16:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
154 return repr_str
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
155 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
156 return '<%s @ 0x%x>' % (type(r).__name__, id(r))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
157
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
158 # Panic mode error recovery support. This feature is being reworked--much of the
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
159 # code here is to offer a deprecation/backwards compatible transition
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
160
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
161 _errok = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
162 _token = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
163 _restart = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
164 _warnmsg = '''PLY: Don't use global functions errok(), token(), and restart() in p_error().
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
165 Instead, invoke the methods on the associated parser instance:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
166
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
167 def p_error(p):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
168 ...
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
169 # Use parser.errok(), parser.token(), parser.restart()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
170 ...
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
171
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
172 parser = yacc.yacc()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
173 '''
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
174
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
175 def errok():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
176 warnings.warn(_warnmsg)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
177 return _errok()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
178
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
179 def restart():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
180 warnings.warn(_warnmsg)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
181 return _restart()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
182
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
183 def token():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
184 warnings.warn(_warnmsg)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
185 return _token()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
186
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
187 # Utility function to call the p_error() function with some deprecation hacks
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
188 def call_errorfunc(errorfunc, token, parser):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
189 global _errok, _token, _restart
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
190 _errok = parser.errok
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
191 _token = parser.token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
192 _restart = parser.restart
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
193 r = errorfunc(token)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
194 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
195 del _errok, _token, _restart
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
196 except NameError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
197 pass
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
198 return r
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
199
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
200 #-----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
201 # === LR Parsing Engine ===
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
202 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
203 # The following classes are used for the LR parser itself. These are not
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
204 # used during table construction and are independent of the actual LR
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
205 # table generation algorithm
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
206 #-----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
207
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
208 # This class is used to hold non-terminal grammar symbols during parsing.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
209 # It normally has the following attributes set:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
210 # .type = Grammar symbol type
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
211 # .value = Symbol value
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
212 # .lineno = Starting line number
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
213 # .endlineno = Ending line number (optional, set automatically)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
214 # .lexpos = Starting lex position
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
215 # .endlexpos = Ending lex position (optional, set automatically)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
216
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
217 class YaccSymbol:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
218 def __str__(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
219 return self.type
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
220
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
221 def __repr__(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
222 return str(self)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
223
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
224 # This class is a wrapper around the objects actually passed to each
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
225 # grammar rule. Index lookup and assignment actually assign the
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
226 # .value attribute of the underlying YaccSymbol object.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
227 # The lineno() method returns the line number of a given
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
228 # item (or 0 if not defined). The linespan() method returns
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
229 # a tuple of (startline,endline) representing the range of lines
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
230 # for a symbol. The lexspan() method returns a tuple (lexpos,endlexpos)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
231 # representing the range of positional information for a symbol.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
232
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
233 class YaccProduction:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
234 def __init__(self, s, stack=None):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
235 self.slice = s
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
236 self.stack = stack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
237 self.lexer = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
238 self.parser = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
239
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
240 def __getitem__(self, n):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
241 if isinstance(n, slice):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
242 return [s.value for s in self.slice[n]]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
243 elif n >= 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
244 return self.slice[n].value
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
245 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
246 return self.stack[n].value
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
247
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
248 def __setitem__(self, n, v):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
249 self.slice[n].value = v
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
250
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
251 def __getslice__(self, i, j):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
252 return [s.value for s in self.slice[i:j]]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
253
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
254 def __len__(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
255 return len(self.slice)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
256
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
257 def lineno(self, n):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
258 return getattr(self.slice[n], 'lineno', 0)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
259
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
260 def set_lineno(self, n, lineno):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
261 self.slice[n].lineno = lineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
262
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
263 def linespan(self, n):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
264 startline = getattr(self.slice[n], 'lineno', 0)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
265 endline = getattr(self.slice[n], 'endlineno', startline)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
266 return startline, endline
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
267
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
268 def lexpos(self, n):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
269 return getattr(self.slice[n], 'lexpos', 0)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
270
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
271 def lexspan(self, n):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
272 startpos = getattr(self.slice[n], 'lexpos', 0)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
273 endpos = getattr(self.slice[n], 'endlexpos', startpos)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
274 return startpos, endpos
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
275
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
276 def error(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
277 raise SyntaxError
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
278
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
279 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
280 # == LRParser ==
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
281 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
282 # The LR Parsing engine.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
283 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
284
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
285 class LRParser:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
286 def __init__(self, lrtab, errorf):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
287 self.productions = lrtab.lr_productions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
288 self.action = lrtab.lr_action
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
289 self.goto = lrtab.lr_goto
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
290 self.errorfunc = errorf
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
291 self.set_defaulted_states()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
292 self.errorok = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
293
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
294 def errok(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
295 self.errorok = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
296
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
297 def restart(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
298 del self.statestack[:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
299 del self.symstack[:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
300 sym = YaccSymbol()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
301 sym.type = '$end'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
302 self.symstack.append(sym)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
303 self.statestack.append(0)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
304
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
305 # Defaulted state support.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
306 # This method identifies parser states where there is only one possible reduction action.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
307 # For such states, the parser can make a choose to make a rule reduction without consuming
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
308 # the next look-ahead token. This delayed invocation of the tokenizer can be useful in
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
309 # certain kinds of advanced parsing situations where the lexer and parser interact with
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
310 # each other or change states (i.e., manipulation of scope, lexer states, etc.).
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
311 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
312 # See: http://www.gnu.org/software/bison/manual/html_node/Default-Reductions.html#Default-Reductions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
313 def set_defaulted_states(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
314 self.defaulted_states = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
315 for state, actions in self.action.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
316 rules = list(actions.values())
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
317 if len(rules) == 1 and rules[0] < 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
318 self.defaulted_states[state] = rules[0]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
319
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
320 def disable_defaulted_states(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
321 self.defaulted_states = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
322
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
323 def parse(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
324 if debug or yaccdevel:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
325 if isinstance(debug, int):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
326 debug = PlyLogger(sys.stderr)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
327 return self.parsedebug(input, lexer, debug, tracking, tokenfunc)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
328 elif tracking:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
329 return self.parseopt(input, lexer, debug, tracking, tokenfunc)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
330 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
331 return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
332
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
333
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
334 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
335 # parsedebug().
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
336 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
337 # This is the debugging enabled version of parse(). All changes made to the
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
338 # parsing engine should be made here. Optimized versions of this function
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
339 # are automatically created by the ply/ygen.py script. This script cuts out
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
340 # sections enclosed in markers such as this:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
341 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
342 # #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
343 # statements
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
344 # #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
345 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
346 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
347
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
348 def parsedebug(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
349 #--! parsedebug-start
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
350 lookahead = None # Current lookahead symbol
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
351 lookaheadstack = [] # Stack of lookahead symbols
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
352 actions = self.action # Local reference to action table (to avoid lookup on self.)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
353 goto = self.goto # Local reference to goto table (to avoid lookup on self.)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
354 prod = self.productions # Local reference to production list (to avoid lookup on self.)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
355 defaulted_states = self.defaulted_states # Local reference to defaulted states
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
356 pslice = YaccProduction(None) # Production object passed to grammar rules
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
357 errorcount = 0 # Used during error recovery
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
358
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
359 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
360 debug.info('PLY: PARSE DEBUG START')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
361 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
362
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
363 # If no lexer was given, we will try to use the lex module
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
364 if not lexer:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
365 from . import lex
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
366 lexer = lex.lexer
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
367
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
368 # Set up the lexer and parser objects on pslice
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
369 pslice.lexer = lexer
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
370 pslice.parser = self
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
371
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
372 # If input was supplied, pass to lexer
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
373 if input is not None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
374 lexer.input(input)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
375
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
376 if tokenfunc is None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
377 # Tokenize function
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
378 get_token = lexer.token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
379 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
380 get_token = tokenfunc
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
381
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
382 # Set the parser() token method (sometimes used in error recovery)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
383 self.token = get_token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
384
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
385 # Set up the state and symbol stacks
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
386
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
387 statestack = [] # Stack of parsing states
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
388 self.statestack = statestack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
389 symstack = [] # Stack of grammar symbols
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
390 self.symstack = symstack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
391
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
392 pslice.stack = symstack # Put in the production
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
393 errtoken = None # Err token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
394
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
395 # The start state is assumed to be (0,$end)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
396
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
397 statestack.append(0)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
398 sym = YaccSymbol()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
399 sym.type = '$end'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
400 symstack.append(sym)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
401 state = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
402 while True:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
403 # Get the next symbol on the input. If a lookahead symbol
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
404 # is already set, we just use that. Otherwise, we'll pull
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
405 # the next token off of the lookaheadstack or from the lexer
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
406
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
407 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
408 debug.debug('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
409 debug.debug('State : %s', state)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
410 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
411
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
412 if state not in defaulted_states:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
413 if not lookahead:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
414 if not lookaheadstack:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
415 lookahead = get_token() # Get the next token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
416 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
417 lookahead = lookaheadstack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
418 if not lookahead:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
419 lookahead = YaccSymbol()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
420 lookahead.type = '$end'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
421
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
422 # Check the action table
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
423 ltype = lookahead.type
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
424 t = actions[state].get(ltype)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
425 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
426 t = defaulted_states[state]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
427 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
428 debug.debug('Defaulted state %s: Reduce using %d', state, -t)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
429 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
430
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
431 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
432 debug.debug('Stack : %s',
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
433 ('%s . %s' % (' '.join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip())
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
434 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
435
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
436 if t is not None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
437 if t > 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
438 # shift a symbol on the stack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
439 statestack.append(t)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
440 state = t
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
441
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
442 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
443 debug.debug('Action : Shift and goto state %s', t)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
444 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
445
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
446 symstack.append(lookahead)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
447 lookahead = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
448
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
449 # Decrease error count on successful shift
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
450 if errorcount:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
451 errorcount -= 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
452 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
453
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
454 if t < 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
455 # reduce a symbol on the stack, emit a production
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
456 p = prod[-t]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
457 pname = p.name
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
458 plen = p.len
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
459
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
460 # Get production function
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
461 sym = YaccSymbol()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
462 sym.type = pname # Production name
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
463 sym.value = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
464
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
465 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
466 if plen:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
467 debug.info('Action : Reduce rule [%s] with %s and goto state %d', p.str,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
468 '['+','.join([format_stack_entry(_v.value) for _v in symstack[-plen:]])+']',
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
469 goto[statestack[-1-plen]][pname])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
470 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
471 debug.info('Action : Reduce rule [%s] with %s and goto state %d', p.str, [],
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
472 goto[statestack[-1]][pname])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
473
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
474 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
475
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
476 if plen:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
477 targ = symstack[-plen-1:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
478 targ[0] = sym
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
479
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
480 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
481 if tracking:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
482 t1 = targ[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
483 sym.lineno = t1.lineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
484 sym.lexpos = t1.lexpos
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
485 t1 = targ[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
486 sym.endlineno = getattr(t1, 'endlineno', t1.lineno)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
487 sym.endlexpos = getattr(t1, 'endlexpos', t1.lexpos)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
488 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
489
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
490 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
491 # The code enclosed in this section is duplicated
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
492 # below as a performance optimization. Make sure
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
493 # changes get made in both locations.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
494
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
495 pslice.slice = targ
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
496
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
497 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
498 # Call the grammar rule with our special slice object
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
499 del symstack[-plen:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
500 del statestack[-plen:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
501 p.callable(pslice)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
502 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
503 debug.info('Result : %s', format_result(pslice[0]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
504 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
505 symstack.append(sym)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
506 state = goto[statestack[-1]][pname]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
507 statestack.append(state)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
508 except SyntaxError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
509 # If an error was set. Enter error recovery state
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
510 lookaheadstack.append(lookahead)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
511 symstack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
512 statestack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
513 state = statestack[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
514 sym.type = 'error'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
515 lookahead = sym
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
516 errorcount = error_count
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
517 self.errorok = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
518 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
519 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
520
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
521 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
522
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
523 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
524 if tracking:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
525 sym.lineno = lexer.lineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
526 sym.lexpos = lexer.lexpos
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
527 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
528
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
529 targ = [sym]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
530
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
531 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
532 # The code enclosed in this section is duplicated
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
533 # above as a performance optimization. Make sure
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
534 # changes get made in both locations.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
535
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
536 pslice.slice = targ
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
537
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
538 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
539 # Call the grammar rule with our special slice object
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
540 p.callable(pslice)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
541 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
542 debug.info('Result : %s', format_result(pslice[0]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
543 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
544 symstack.append(sym)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
545 state = goto[statestack[-1]][pname]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
546 statestack.append(state)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
547 except SyntaxError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
548 # If an error was set. Enter error recovery state
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
549 lookaheadstack.append(lookahead)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
550 symstack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
551 statestack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
552 state = statestack[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
553 sym.type = 'error'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
554 lookahead = sym
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
555 errorcount = error_count
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
556 self.errorok = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
557 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
558 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
559
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
560 if t == 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
561 n = symstack[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
562 result = getattr(n, 'value', None)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
563 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
564 debug.info('Done : Returning %s', format_result(result))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
565 debug.info('PLY: PARSE DEBUG END')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
566 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
567 return result
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
568
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
569 if t is None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
570
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
571 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
572 debug.error('Error : %s',
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
573 ('%s . %s' % (' '.join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip())
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
574 #--! DEBUG
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
575
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
576 # We have some kind of parsing error here. To handle
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
577 # this, we are going to push the current token onto
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
578 # the tokenstack and replace it with an 'error' token.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
579 # If there are any synchronization rules, they may
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
580 # catch it.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
581 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
582 # In addition to pushing the error token, we call call
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
583 # the user defined p_error() function if this is the
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
584 # first syntax error. This function is only called if
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
585 # errorcount == 0.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
586 if errorcount == 0 or self.errorok:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
587 errorcount = error_count
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
588 self.errorok = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
589 errtoken = lookahead
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
590 if errtoken.type == '$end':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
591 errtoken = None # End of file!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
592 if self.errorfunc:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
593 if errtoken and not hasattr(errtoken, 'lexer'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
594 errtoken.lexer = lexer
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
595 tok = call_errorfunc(self.errorfunc, errtoken, self)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
596 if self.errorok:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
597 # User must have done some kind of panic
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
598 # mode recovery on their own. The
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
599 # returned token is the next lookahead
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
600 lookahead = tok
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
601 errtoken = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
602 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
603 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
604 if errtoken:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
605 if hasattr(errtoken, 'lineno'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
606 lineno = lookahead.lineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
607 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
608 lineno = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
609 if lineno:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
610 sys.stderr.write('yacc: Syntax error at line %d, token=%s\n' % (lineno, errtoken.type))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
611 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
612 sys.stderr.write('yacc: Syntax error, token=%s' % errtoken.type)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
613 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
614 sys.stderr.write('yacc: Parse error in input. EOF\n')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
615 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
616
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
617 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
618 errorcount = error_count
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
619
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
620 # case 1: the statestack only has 1 entry on it. If we're in this state, the
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
621 # entire parse has been rolled back and we're completely hosed. The token is
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
622 # discarded and we just keep going.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
623
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
624 if len(statestack) <= 1 and lookahead.type != '$end':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
625 lookahead = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
626 errtoken = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
627 state = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
628 # Nuke the pushback stack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
629 del lookaheadstack[:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
630 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
631
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
632 # case 2: the statestack has a couple of entries on it, but we're
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
633 # at the end of the file. nuke the top entry and generate an error token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
634
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
635 # Start nuking entries on the stack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
636 if lookahead.type == '$end':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
637 # Whoa. We're really hosed here. Bail out
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
638 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
639
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
640 if lookahead.type != 'error':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
641 sym = symstack[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
642 if sym.type == 'error':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
643 # Hmmm. Error is on top of stack, we'll just nuke input
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
644 # symbol and continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
645 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
646 if tracking:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
647 sym.endlineno = getattr(lookahead, 'lineno', sym.lineno)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
648 sym.endlexpos = getattr(lookahead, 'lexpos', sym.lexpos)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
649 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
650 lookahead = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
651 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
652
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
653 # Create the error symbol for the first time and make it the new lookahead symbol
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
654 t = YaccSymbol()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
655 t.type = 'error'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
656
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
657 if hasattr(lookahead, 'lineno'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
658 t.lineno = t.endlineno = lookahead.lineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
659 if hasattr(lookahead, 'lexpos'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
660 t.lexpos = t.endlexpos = lookahead.lexpos
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
661 t.value = lookahead
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
662 lookaheadstack.append(lookahead)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
663 lookahead = t
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
664 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
665 sym = symstack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
666 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
667 if tracking:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
668 lookahead.lineno = sym.lineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
669 lookahead.lexpos = sym.lexpos
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
670 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
671 statestack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
672 state = statestack[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
673
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
674 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
675
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
676 # Call an error function here
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
677 raise RuntimeError('yacc: internal parser error!!!\n')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
678
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
679 #--! parsedebug-end
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
680
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
681 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
682 # parseopt().
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
683 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
684 # Optimized version of parse() method. DO NOT EDIT THIS CODE DIRECTLY!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
685 # This code is automatically generated by the ply/ygen.py script. Make
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
686 # changes to the parsedebug() method instead.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
687 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
688
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
689 def parseopt(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
690 #--! parseopt-start
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
691 lookahead = None # Current lookahead symbol
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
692 lookaheadstack = [] # Stack of lookahead symbols
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
693 actions = self.action # Local reference to action table (to avoid lookup on self.)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
694 goto = self.goto # Local reference to goto table (to avoid lookup on self.)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
695 prod = self.productions # Local reference to production list (to avoid lookup on self.)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
696 defaulted_states = self.defaulted_states # Local reference to defaulted states
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
697 pslice = YaccProduction(None) # Production object passed to grammar rules
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
698 errorcount = 0 # Used during error recovery
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
699
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
700
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
701 # If no lexer was given, we will try to use the lex module
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
702 if not lexer:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
703 from . import lex
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
704 lexer = lex.lexer
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
705
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
706 # Set up the lexer and parser objects on pslice
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
707 pslice.lexer = lexer
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
708 pslice.parser = self
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
709
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
710 # If input was supplied, pass to lexer
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
711 if input is not None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
712 lexer.input(input)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
713
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
714 if tokenfunc is None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
715 # Tokenize function
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
716 get_token = lexer.token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
717 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
718 get_token = tokenfunc
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
719
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
720 # Set the parser() token method (sometimes used in error recovery)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
721 self.token = get_token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
722
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
723 # Set up the state and symbol stacks
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
724
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
725 statestack = [] # Stack of parsing states
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
726 self.statestack = statestack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
727 symstack = [] # Stack of grammar symbols
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
728 self.symstack = symstack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
729
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
730 pslice.stack = symstack # Put in the production
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
731 errtoken = None # Err token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
732
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
733 # The start state is assumed to be (0,$end)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
734
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
735 statestack.append(0)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
736 sym = YaccSymbol()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
737 sym.type = '$end'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
738 symstack.append(sym)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
739 state = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
740 while True:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
741 # Get the next symbol on the input. If a lookahead symbol
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
742 # is already set, we just use that. Otherwise, we'll pull
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
743 # the next token off of the lookaheadstack or from the lexer
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
744
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
745
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
746 if state not in defaulted_states:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
747 if not lookahead:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
748 if not lookaheadstack:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
749 lookahead = get_token() # Get the next token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
750 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
751 lookahead = lookaheadstack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
752 if not lookahead:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
753 lookahead = YaccSymbol()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
754 lookahead.type = '$end'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
755
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
756 # Check the action table
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
757 ltype = lookahead.type
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
758 t = actions[state].get(ltype)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
759 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
760 t = defaulted_states[state]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
761
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
762
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
763 if t is not None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
764 if t > 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
765 # shift a symbol on the stack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
766 statestack.append(t)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
767 state = t
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
768
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
769
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
770 symstack.append(lookahead)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
771 lookahead = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
772
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
773 # Decrease error count on successful shift
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
774 if errorcount:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
775 errorcount -= 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
776 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
777
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
778 if t < 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
779 # reduce a symbol on the stack, emit a production
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
780 p = prod[-t]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
781 pname = p.name
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
782 plen = p.len
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
783
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
784 # Get production function
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
785 sym = YaccSymbol()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
786 sym.type = pname # Production name
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
787 sym.value = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
788
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
789
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
790 if plen:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
791 targ = symstack[-plen-1:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
792 targ[0] = sym
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
793
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
794 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
795 if tracking:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
796 t1 = targ[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
797 sym.lineno = t1.lineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
798 sym.lexpos = t1.lexpos
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
799 t1 = targ[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
800 sym.endlineno = getattr(t1, 'endlineno', t1.lineno)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
801 sym.endlexpos = getattr(t1, 'endlexpos', t1.lexpos)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
802 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
803
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
804 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
805 # The code enclosed in this section is duplicated
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
806 # below as a performance optimization. Make sure
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
807 # changes get made in both locations.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
808
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
809 pslice.slice = targ
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
810
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
811 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
812 # Call the grammar rule with our special slice object
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
813 del symstack[-plen:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
814 del statestack[-plen:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
815 p.callable(pslice)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
816 symstack.append(sym)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
817 state = goto[statestack[-1]][pname]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
818 statestack.append(state)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
819 except SyntaxError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
820 # If an error was set. Enter error recovery state
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
821 lookaheadstack.append(lookahead)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
822 symstack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
823 statestack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
824 state = statestack[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
825 sym.type = 'error'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
826 lookahead = sym
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
827 errorcount = error_count
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
828 self.errorok = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
829 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
830 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
831
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
832 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
833
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
834 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
835 if tracking:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
836 sym.lineno = lexer.lineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
837 sym.lexpos = lexer.lexpos
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
838 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
839
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
840 targ = [sym]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
841
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
842 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
843 # The code enclosed in this section is duplicated
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
844 # above as a performance optimization. Make sure
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
845 # changes get made in both locations.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
846
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
847 pslice.slice = targ
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
848
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
849 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
850 # Call the grammar rule with our special slice object
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
851 p.callable(pslice)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
852 symstack.append(sym)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
853 state = goto[statestack[-1]][pname]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
854 statestack.append(state)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
855 except SyntaxError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
856 # If an error was set. Enter error recovery state
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
857 lookaheadstack.append(lookahead)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
858 symstack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
859 statestack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
860 state = statestack[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
861 sym.type = 'error'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
862 lookahead = sym
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
863 errorcount = error_count
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
864 self.errorok = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
865 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
866 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
867
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
868 if t == 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
869 n = symstack[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
870 result = getattr(n, 'value', None)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
871 return result
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
872
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
873 if t is None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
874
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
875
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
876 # We have some kind of parsing error here. To handle
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
877 # this, we are going to push the current token onto
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
878 # the tokenstack and replace it with an 'error' token.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
879 # If there are any synchronization rules, they may
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
880 # catch it.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
881 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
882 # In addition to pushing the error token, we call call
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
883 # the user defined p_error() function if this is the
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
884 # first syntax error. This function is only called if
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
885 # errorcount == 0.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
886 if errorcount == 0 or self.errorok:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
887 errorcount = error_count
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
888 self.errorok = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
889 errtoken = lookahead
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
890 if errtoken.type == '$end':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
891 errtoken = None # End of file!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
892 if self.errorfunc:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
893 if errtoken and not hasattr(errtoken, 'lexer'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
894 errtoken.lexer = lexer
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
895 tok = call_errorfunc(self.errorfunc, errtoken, self)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
896 if self.errorok:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
897 # User must have done some kind of panic
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
898 # mode recovery on their own. The
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
899 # returned token is the next lookahead
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
900 lookahead = tok
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
901 errtoken = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
902 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
903 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
904 if errtoken:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
905 if hasattr(errtoken, 'lineno'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
906 lineno = lookahead.lineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
907 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
908 lineno = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
909 if lineno:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
910 sys.stderr.write('yacc: Syntax error at line %d, token=%s\n' % (lineno, errtoken.type))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
911 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
912 sys.stderr.write('yacc: Syntax error, token=%s' % errtoken.type)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
913 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
914 sys.stderr.write('yacc: Parse error in input. EOF\n')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
915 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
916
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
917 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
918 errorcount = error_count
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
919
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
920 # case 1: the statestack only has 1 entry on it. If we're in this state, the
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
921 # entire parse has been rolled back and we're completely hosed. The token is
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
922 # discarded and we just keep going.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
923
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
924 if len(statestack) <= 1 and lookahead.type != '$end':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
925 lookahead = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
926 errtoken = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
927 state = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
928 # Nuke the pushback stack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
929 del lookaheadstack[:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
930 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
931
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
932 # case 2: the statestack has a couple of entries on it, but we're
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
933 # at the end of the file. nuke the top entry and generate an error token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
934
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
935 # Start nuking entries on the stack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
936 if lookahead.type == '$end':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
937 # Whoa. We're really hosed here. Bail out
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
938 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
939
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
940 if lookahead.type != 'error':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
941 sym = symstack[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
942 if sym.type == 'error':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
943 # Hmmm. Error is on top of stack, we'll just nuke input
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
944 # symbol and continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
945 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
946 if tracking:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
947 sym.endlineno = getattr(lookahead, 'lineno', sym.lineno)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
948 sym.endlexpos = getattr(lookahead, 'lexpos', sym.lexpos)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
949 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
950 lookahead = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
951 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
952
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
953 # Create the error symbol for the first time and make it the new lookahead symbol
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
954 t = YaccSymbol()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
955 t.type = 'error'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
956
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
957 if hasattr(lookahead, 'lineno'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
958 t.lineno = t.endlineno = lookahead.lineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
959 if hasattr(lookahead, 'lexpos'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
960 t.lexpos = t.endlexpos = lookahead.lexpos
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
961 t.value = lookahead
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
962 lookaheadstack.append(lookahead)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
963 lookahead = t
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
964 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
965 sym = symstack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
966 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
967 if tracking:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
968 lookahead.lineno = sym.lineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
969 lookahead.lexpos = sym.lexpos
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
970 #--! TRACKING
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
971 statestack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
972 state = statestack[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
973
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
974 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
975
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
976 # Call an error function here
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
977 raise RuntimeError('yacc: internal parser error!!!\n')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
978
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
979 #--! parseopt-end
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
980
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
981 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
982 # parseopt_notrack().
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
983 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
984 # Optimized version of parseopt() with line number tracking removed.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
985 # DO NOT EDIT THIS CODE DIRECTLY. This code is automatically generated
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
986 # by the ply/ygen.py script. Make changes to the parsedebug() method instead.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
987 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
988
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
989 def parseopt_notrack(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
990 #--! parseopt-notrack-start
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
991 lookahead = None # Current lookahead symbol
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
992 lookaheadstack = [] # Stack of lookahead symbols
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
993 actions = self.action # Local reference to action table (to avoid lookup on self.)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
994 goto = self.goto # Local reference to goto table (to avoid lookup on self.)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
995 prod = self.productions # Local reference to production list (to avoid lookup on self.)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
996 defaulted_states = self.defaulted_states # Local reference to defaulted states
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
997 pslice = YaccProduction(None) # Production object passed to grammar rules
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
998 errorcount = 0 # Used during error recovery
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
999
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1000
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1001 # If no lexer was given, we will try to use the lex module
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1002 if not lexer:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1003 from . import lex
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1004 lexer = lex.lexer
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1005
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1006 # Set up the lexer and parser objects on pslice
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1007 pslice.lexer = lexer
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1008 pslice.parser = self
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1009
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1010 # If input was supplied, pass to lexer
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1011 if input is not None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1012 lexer.input(input)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1013
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1014 if tokenfunc is None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1015 # Tokenize function
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1016 get_token = lexer.token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1017 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1018 get_token = tokenfunc
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1019
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1020 # Set the parser() token method (sometimes used in error recovery)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1021 self.token = get_token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1022
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1023 # Set up the state and symbol stacks
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1024
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1025 statestack = [] # Stack of parsing states
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1026 self.statestack = statestack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1027 symstack = [] # Stack of grammar symbols
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1028 self.symstack = symstack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1029
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1030 pslice.stack = symstack # Put in the production
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1031 errtoken = None # Err token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1032
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1033 # The start state is assumed to be (0,$end)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1034
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1035 statestack.append(0)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1036 sym = YaccSymbol()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1037 sym.type = '$end'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1038 symstack.append(sym)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1039 state = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1040 while True:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1041 # Get the next symbol on the input. If a lookahead symbol
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1042 # is already set, we just use that. Otherwise, we'll pull
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1043 # the next token off of the lookaheadstack or from the lexer
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1044
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1045
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1046 if state not in defaulted_states:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1047 if not lookahead:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1048 if not lookaheadstack:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1049 lookahead = get_token() # Get the next token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1050 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1051 lookahead = lookaheadstack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1052 if not lookahead:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1053 lookahead = YaccSymbol()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1054 lookahead.type = '$end'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1055
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1056 # Check the action table
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1057 ltype = lookahead.type
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1058 t = actions[state].get(ltype)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1059 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1060 t = defaulted_states[state]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1061
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1062
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1063 if t is not None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1064 if t > 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1065 # shift a symbol on the stack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1066 statestack.append(t)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1067 state = t
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1068
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1069
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1070 symstack.append(lookahead)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1071 lookahead = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1072
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1073 # Decrease error count on successful shift
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1074 if errorcount:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1075 errorcount -= 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1076 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1077
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1078 if t < 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1079 # reduce a symbol on the stack, emit a production
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1080 p = prod[-t]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1081 pname = p.name
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1082 plen = p.len
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1083
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1084 # Get production function
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1085 sym = YaccSymbol()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1086 sym.type = pname # Production name
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1087 sym.value = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1088
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1089
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1090 if plen:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1091 targ = symstack[-plen-1:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1092 targ[0] = sym
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1093
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1094
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1095 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1096 # The code enclosed in this section is duplicated
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1097 # below as a performance optimization. Make sure
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1098 # changes get made in both locations.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1099
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1100 pslice.slice = targ
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1101
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1102 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1103 # Call the grammar rule with our special slice object
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1104 del symstack[-plen:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1105 del statestack[-plen:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1106 p.callable(pslice)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1107 symstack.append(sym)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1108 state = goto[statestack[-1]][pname]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1109 statestack.append(state)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1110 except SyntaxError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1111 # If an error was set. Enter error recovery state
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1112 lookaheadstack.append(lookahead)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1113 symstack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1114 statestack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1115 state = statestack[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1116 sym.type = 'error'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1117 lookahead = sym
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1118 errorcount = error_count
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1119 self.errorok = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1120 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1121 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1122
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1123 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1124
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1125
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1126 targ = [sym]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1127
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1128 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1129 # The code enclosed in this section is duplicated
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1130 # above as a performance optimization. Make sure
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1131 # changes get made in both locations.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1132
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1133 pslice.slice = targ
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1134
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1135 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1136 # Call the grammar rule with our special slice object
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1137 p.callable(pslice)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1138 symstack.append(sym)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1139 state = goto[statestack[-1]][pname]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1140 statestack.append(state)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1141 except SyntaxError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1142 # If an error was set. Enter error recovery state
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1143 lookaheadstack.append(lookahead)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1144 symstack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1145 statestack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1146 state = statestack[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1147 sym.type = 'error'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1148 lookahead = sym
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1149 errorcount = error_count
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1150 self.errorok = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1151 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1152 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1153
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1154 if t == 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1155 n = symstack[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1156 result = getattr(n, 'value', None)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1157 return result
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1158
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1159 if t is None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1160
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1161
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1162 # We have some kind of parsing error here. To handle
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1163 # this, we are going to push the current token onto
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1164 # the tokenstack and replace it with an 'error' token.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1165 # If there are any synchronization rules, they may
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1166 # catch it.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1167 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1168 # In addition to pushing the error token, we call call
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1169 # the user defined p_error() function if this is the
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1170 # first syntax error. This function is only called if
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1171 # errorcount == 0.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1172 if errorcount == 0 or self.errorok:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1173 errorcount = error_count
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1174 self.errorok = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1175 errtoken = lookahead
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1176 if errtoken.type == '$end':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1177 errtoken = None # End of file!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1178 if self.errorfunc:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1179 if errtoken and not hasattr(errtoken, 'lexer'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1180 errtoken.lexer = lexer
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1181 tok = call_errorfunc(self.errorfunc, errtoken, self)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1182 if self.errorok:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1183 # User must have done some kind of panic
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1184 # mode recovery on their own. The
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1185 # returned token is the next lookahead
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1186 lookahead = tok
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1187 errtoken = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1188 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1189 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1190 if errtoken:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1191 if hasattr(errtoken, 'lineno'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1192 lineno = lookahead.lineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1193 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1194 lineno = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1195 if lineno:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1196 sys.stderr.write('yacc: Syntax error at line %d, token=%s\n' % (lineno, errtoken.type))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1197 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1198 sys.stderr.write('yacc: Syntax error, token=%s' % errtoken.type)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1199 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1200 sys.stderr.write('yacc: Parse error in input. EOF\n')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1201 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1202
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1203 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1204 errorcount = error_count
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1205
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1206 # case 1: the statestack only has 1 entry on it. If we're in this state, the
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1207 # entire parse has been rolled back and we're completely hosed. The token is
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1208 # discarded and we just keep going.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1209
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1210 if len(statestack) <= 1 and lookahead.type != '$end':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1211 lookahead = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1212 errtoken = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1213 state = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1214 # Nuke the pushback stack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1215 del lookaheadstack[:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1216 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1217
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1218 # case 2: the statestack has a couple of entries on it, but we're
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1219 # at the end of the file. nuke the top entry and generate an error token
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1220
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1221 # Start nuking entries on the stack
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1222 if lookahead.type == '$end':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1223 # Whoa. We're really hosed here. Bail out
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1224 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1225
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1226 if lookahead.type != 'error':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1227 sym = symstack[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1228 if sym.type == 'error':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1229 # Hmmm. Error is on top of stack, we'll just nuke input
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1230 # symbol and continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1231 lookahead = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1232 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1233
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1234 # Create the error symbol for the first time and make it the new lookahead symbol
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1235 t = YaccSymbol()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1236 t.type = 'error'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1237
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1238 if hasattr(lookahead, 'lineno'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1239 t.lineno = t.endlineno = lookahead.lineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1240 if hasattr(lookahead, 'lexpos'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1241 t.lexpos = t.endlexpos = lookahead.lexpos
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1242 t.value = lookahead
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1243 lookaheadstack.append(lookahead)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1244 lookahead = t
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1245 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1246 sym = symstack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1247 statestack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1248 state = statestack[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1249
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1250 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1251
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1252 # Call an error function here
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1253 raise RuntimeError('yacc: internal parser error!!!\n')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1254
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1255 #--! parseopt-notrack-end
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1256
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1257 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1258 # === Grammar Representation ===
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1259 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1260 # The following functions, classes, and variables are used to represent and
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1261 # manipulate the rules that make up a grammar.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1262 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1263
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1264 # regex matching identifiers
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1265 _is_identifier = re.compile(r'^[a-zA-Z0-9_-]+$')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1266
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1267 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1268 # class Production:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1269 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1270 # This class stores the raw information about a single production or grammar rule.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1271 # A grammar rule refers to a specification such as this:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1272 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1273 # expr : expr PLUS term
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1274 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1275 # Here are the basic attributes defined on all productions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1276 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1277 # name - Name of the production. For example 'expr'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1278 # prod - A list of symbols on the right side ['expr','PLUS','term']
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1279 # prec - Production precedence level
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1280 # number - Production number.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1281 # func - Function that executes on reduce
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1282 # file - File where production function is defined
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1283 # lineno - Line number where production function is defined
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1284 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1285 # The following attributes are defined or optional.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1286 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1287 # len - Length of the production (number of symbols on right hand side)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1288 # usyms - Set of unique symbols found in the production
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1289 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1290
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1291 class Production(object):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1292 reduced = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1293 def __init__(self, number, name, prod, precedence=('right', 0), func=None, file='', line=0):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1294 self.name = name
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1295 self.prod = tuple(prod)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1296 self.number = number
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1297 self.func = func
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1298 self.callable = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1299 self.file = file
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1300 self.line = line
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1301 self.prec = precedence
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1302
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1303 # Internal settings used during table construction
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1304
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1305 self.len = len(self.prod) # Length of the production
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1306
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1307 # Create a list of unique production symbols used in the production
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1308 self.usyms = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1309 for s in self.prod:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1310 if s not in self.usyms:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1311 self.usyms.append(s)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1312
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1313 # List of all LR items for the production
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1314 self.lr_items = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1315 self.lr_next = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1316
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1317 # Create a string representation
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1318 if self.prod:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1319 self.str = '%s -> %s' % (self.name, ' '.join(self.prod))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1320 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1321 self.str = '%s -> <empty>' % self.name
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1322
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1323 def __str__(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1324 return self.str
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1325
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1326 def __repr__(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1327 return 'Production(' + str(self) + ')'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1328
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1329 def __len__(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1330 return len(self.prod)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1331
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1332 def __nonzero__(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1333 return 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1334
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1335 def __getitem__(self, index):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1336 return self.prod[index]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1337
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1338 # Return the nth lr_item from the production (or None if at the end)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1339 def lr_item(self, n):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1340 if n > len(self.prod):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1341 return None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1342 p = LRItem(self, n)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1343 # Precompute the list of productions immediately following.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1344 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1345 p.lr_after = Prodnames[p.prod[n+1]]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1346 except (IndexError, KeyError):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1347 p.lr_after = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1348 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1349 p.lr_before = p.prod[n-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1350 except IndexError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1351 p.lr_before = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1352 return p
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1353
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1354 # Bind the production function name to a callable
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1355 def bind(self, pdict):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1356 if self.func:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1357 self.callable = pdict[self.func]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1358
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1359 # This class serves as a minimal standin for Production objects when
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1360 # reading table data from files. It only contains information
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1361 # actually used by the LR parsing engine, plus some additional
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1362 # debugging information.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1363 class MiniProduction(object):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1364 def __init__(self, str, name, len, func, file, line):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1365 self.name = name
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1366 self.len = len
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1367 self.func = func
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1368 self.callable = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1369 self.file = file
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1370 self.line = line
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1371 self.str = str
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1372
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1373 def __str__(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1374 return self.str
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1375
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1376 def __repr__(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1377 return 'MiniProduction(%s)' % self.str
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1378
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1379 # Bind the production function name to a callable
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1380 def bind(self, pdict):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1381 if self.func:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1382 self.callable = pdict[self.func]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1383
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1384
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1385 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1386 # class LRItem
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1387 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1388 # This class represents a specific stage of parsing a production rule. For
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1389 # example:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1390 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1391 # expr : expr . PLUS term
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1392 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1393 # In the above, the "." represents the current location of the parse. Here
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1394 # basic attributes:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1395 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1396 # name - Name of the production. For example 'expr'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1397 # prod - A list of symbols on the right side ['expr','.', 'PLUS','term']
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1398 # number - Production number.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1399 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1400 # lr_next Next LR item. Example, if we are ' expr -> expr . PLUS term'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1401 # then lr_next refers to 'expr -> expr PLUS . term'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1402 # lr_index - LR item index (location of the ".") in the prod list.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1403 # lookaheads - LALR lookahead symbols for this item
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1404 # len - Length of the production (number of symbols on right hand side)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1405 # lr_after - List of all productions that immediately follow
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1406 # lr_before - Grammar symbol immediately before
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1407 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1408
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1409 class LRItem(object):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1410 def __init__(self, p, n):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1411 self.name = p.name
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1412 self.prod = list(p.prod)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1413 self.number = p.number
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1414 self.lr_index = n
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1415 self.lookaheads = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1416 self.prod.insert(n, '.')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1417 self.prod = tuple(self.prod)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1418 self.len = len(self.prod)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1419 self.usyms = p.usyms
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1420
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1421 def __str__(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1422 if self.prod:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1423 s = '%s -> %s' % (self.name, ' '.join(self.prod))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1424 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1425 s = '%s -> <empty>' % self.name
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1426 return s
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1427
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1428 def __repr__(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1429 return 'LRItem(' + str(self) + ')'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1430
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1431 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1432 # rightmost_terminal()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1433 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1434 # Return the rightmost terminal from a list of symbols. Used in add_production()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1435 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1436 def rightmost_terminal(symbols, terminals):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1437 i = len(symbols) - 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1438 while i >= 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1439 if symbols[i] in terminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1440 return symbols[i]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1441 i -= 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1442 return None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1443
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1444 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1445 # === GRAMMAR CLASS ===
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1446 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1447 # The following class represents the contents of the specified grammar along
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1448 # with various computed properties such as first sets, follow sets, LR items, etc.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1449 # This data is used for critical parts of the table generation process later.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1450 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1451
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1452 class GrammarError(YaccError):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1453 pass
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1454
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1455 class Grammar(object):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1456 def __init__(self, terminals):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1457 self.Productions = [None] # A list of all of the productions. The first
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1458 # entry is always reserved for the purpose of
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1459 # building an augmented grammar
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1460
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1461 self.Prodnames = {} # A dictionary mapping the names of nonterminals to a list of all
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1462 # productions of that nonterminal.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1463
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1464 self.Prodmap = {} # A dictionary that is only used to detect duplicate
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1465 # productions.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1466
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1467 self.Terminals = {} # A dictionary mapping the names of terminal symbols to a
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1468 # list of the rules where they are used.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1469
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1470 for term in terminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1471 self.Terminals[term] = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1472
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1473 self.Terminals['error'] = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1474
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1475 self.Nonterminals = {} # A dictionary mapping names of nonterminals to a list
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1476 # of rule numbers where they are used.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1477
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1478 self.First = {} # A dictionary of precomputed FIRST(x) symbols
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1479
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1480 self.Follow = {} # A dictionary of precomputed FOLLOW(x) symbols
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1481
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1482 self.Precedence = {} # Precedence rules for each terminal. Contains tuples of the
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1483 # form ('right',level) or ('nonassoc', level) or ('left',level)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1484
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1485 self.UsedPrecedence = set() # Precedence rules that were actually used by the grammer.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1486 # This is only used to provide error checking and to generate
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1487 # a warning about unused precedence rules.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1488
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1489 self.Start = None # Starting symbol for the grammar
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1490
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1491
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1492 def __len__(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1493 return len(self.Productions)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1494
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1495 def __getitem__(self, index):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1496 return self.Productions[index]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1497
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1498 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1499 # set_precedence()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1500 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1501 # Sets the precedence for a given terminal. assoc is the associativity such as
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1502 # 'left','right', or 'nonassoc'. level is a numeric level.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1503 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1504 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1505
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1506 def set_precedence(self, term, assoc, level):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1507 assert self.Productions == [None], 'Must call set_precedence() before add_production()'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1508 if term in self.Precedence:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1509 raise GrammarError('Precedence already specified for terminal %r' % term)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1510 if assoc not in ['left', 'right', 'nonassoc']:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1511 raise GrammarError("Associativity must be one of 'left','right', or 'nonassoc'")
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1512 self.Precedence[term] = (assoc, level)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1513
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1514 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1515 # add_production()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1516 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1517 # Given an action function, this function assembles a production rule and
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1518 # computes its precedence level.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1519 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1520 # The production rule is supplied as a list of symbols. For example,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1521 # a rule such as 'expr : expr PLUS term' has a production name of 'expr' and
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1522 # symbols ['expr','PLUS','term'].
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1523 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1524 # Precedence is determined by the precedence of the right-most non-terminal
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1525 # or the precedence of a terminal specified by %prec.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1526 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1527 # A variety of error checks are performed to make sure production symbols
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1528 # are valid and that %prec is used correctly.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1529 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1530
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1531 def add_production(self, prodname, syms, func=None, file='', line=0):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1532
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1533 if prodname in self.Terminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1534 raise GrammarError('%s:%d: Illegal rule name %r. Already defined as a token' % (file, line, prodname))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1535 if prodname == 'error':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1536 raise GrammarError('%s:%d: Illegal rule name %r. error is a reserved word' % (file, line, prodname))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1537 if not _is_identifier.match(prodname):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1538 raise GrammarError('%s:%d: Illegal rule name %r' % (file, line, prodname))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1539
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1540 # Look for literal tokens
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1541 for n, s in enumerate(syms):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1542 if s[0] in "'\"":
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1543 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1544 c = eval(s)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1545 if (len(c) > 1):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1546 raise GrammarError('%s:%d: Literal token %s in rule %r may only be a single character' %
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1547 (file, line, s, prodname))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1548 if c not in self.Terminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1549 self.Terminals[c] = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1550 syms[n] = c
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1551 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1552 except SyntaxError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1553 pass
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1554 if not _is_identifier.match(s) and s != '%prec':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1555 raise GrammarError('%s:%d: Illegal name %r in rule %r' % (file, line, s, prodname))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1556
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1557 # Determine the precedence level
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1558 if '%prec' in syms:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1559 if syms[-1] == '%prec':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1560 raise GrammarError('%s:%d: Syntax error. Nothing follows %%prec' % (file, line))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1561 if syms[-2] != '%prec':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1562 raise GrammarError('%s:%d: Syntax error. %%prec can only appear at the end of a grammar rule' %
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1563 (file, line))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1564 precname = syms[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1565 prodprec = self.Precedence.get(precname)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1566 if not prodprec:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1567 raise GrammarError('%s:%d: Nothing known about the precedence of %r' % (file, line, precname))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1568 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1569 self.UsedPrecedence.add(precname)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1570 del syms[-2:] # Drop %prec from the rule
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1571 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1572 # If no %prec, precedence is determined by the rightmost terminal symbol
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1573 precname = rightmost_terminal(syms, self.Terminals)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1574 prodprec = self.Precedence.get(precname, ('right', 0))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1575
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1576 # See if the rule is already in the rulemap
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1577 map = '%s -> %s' % (prodname, syms)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1578 if map in self.Prodmap:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1579 m = self.Prodmap[map]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1580 raise GrammarError('%s:%d: Duplicate rule %s. ' % (file, line, m) +
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1581 'Previous definition at %s:%d' % (m.file, m.line))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1582
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1583 # From this point on, everything is valid. Create a new Production instance
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1584 pnumber = len(self.Productions)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1585 if prodname not in self.Nonterminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1586 self.Nonterminals[prodname] = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1587
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1588 # Add the production number to Terminals and Nonterminals
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1589 for t in syms:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1590 if t in self.Terminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1591 self.Terminals[t].append(pnumber)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1592 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1593 if t not in self.Nonterminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1594 self.Nonterminals[t] = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1595 self.Nonterminals[t].append(pnumber)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1596
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1597 # Create a production and add it to the list of productions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1598 p = Production(pnumber, prodname, syms, prodprec, func, file, line)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1599 self.Productions.append(p)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1600 self.Prodmap[map] = p
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1601
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1602 # Add to the global productions list
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1603 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1604 self.Prodnames[prodname].append(p)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1605 except KeyError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1606 self.Prodnames[prodname] = [p]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1607
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1608 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1609 # set_start()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1610 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1611 # Sets the starting symbol and creates the augmented grammar. Production
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1612 # rule 0 is S' -> start where start is the start symbol.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1613 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1614
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1615 def set_start(self, start=None):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1616 if not start:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1617 start = self.Productions[1].name
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1618 if start not in self.Nonterminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1619 raise GrammarError('start symbol %s undefined' % start)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1620 self.Productions[0] = Production(0, "S'", [start])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1621 self.Nonterminals[start].append(0)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1622 self.Start = start
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1623
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1624 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1625 # find_unreachable()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1626 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1627 # Find all of the nonterminal symbols that can't be reached from the starting
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1628 # symbol. Returns a list of nonterminals that can't be reached.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1629 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1630
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1631 def find_unreachable(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1632
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1633 # Mark all symbols that are reachable from a symbol s
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1634 def mark_reachable_from(s):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1635 if s in reachable:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1636 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1637 reachable.add(s)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1638 for p in self.Prodnames.get(s, []):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1639 for r in p.prod:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1640 mark_reachable_from(r)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1641
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1642 reachable = set()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1643 mark_reachable_from(self.Productions[0].prod[0])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1644 return [s for s in self.Nonterminals if s not in reachable]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1645
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1646 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1647 # infinite_cycles()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1648 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1649 # This function looks at the various parsing rules and tries to detect
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1650 # infinite recursion cycles (grammar rules where there is no possible way
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1651 # to derive a string of only terminals).
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1652 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1653
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1654 def infinite_cycles(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1655 terminates = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1656
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1657 # Terminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1658 for t in self.Terminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1659 terminates[t] = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1660
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1661 terminates['$end'] = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1662
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1663 # Nonterminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1664
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1665 # Initialize to false:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1666 for n in self.Nonterminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1667 terminates[n] = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1668
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1669 # Then propagate termination until no change:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1670 while True:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1671 some_change = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1672 for (n, pl) in self.Prodnames.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1673 # Nonterminal n terminates iff any of its productions terminates.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1674 for p in pl:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1675 # Production p terminates iff all of its rhs symbols terminate.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1676 for s in p.prod:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1677 if not terminates[s]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1678 # The symbol s does not terminate,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1679 # so production p does not terminate.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1680 p_terminates = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1681 break
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1682 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1683 # didn't break from the loop,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1684 # so every symbol s terminates
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1685 # so production p terminates.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1686 p_terminates = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1687
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1688 if p_terminates:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1689 # symbol n terminates!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1690 if not terminates[n]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1691 terminates[n] = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1692 some_change = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1693 # Don't need to consider any more productions for this n.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1694 break
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1695
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1696 if not some_change:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1697 break
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1698
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1699 infinite = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1700 for (s, term) in terminates.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1701 if not term:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1702 if s not in self.Prodnames and s not in self.Terminals and s != 'error':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1703 # s is used-but-not-defined, and we've already warned of that,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1704 # so it would be overkill to say that it's also non-terminating.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1705 pass
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1706 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1707 infinite.append(s)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1708
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1709 return infinite
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1710
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1711 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1712 # undefined_symbols()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1713 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1714 # Find all symbols that were used the grammar, but not defined as tokens or
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1715 # grammar rules. Returns a list of tuples (sym, prod) where sym in the symbol
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1716 # and prod is the production where the symbol was used.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1717 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1718 def undefined_symbols(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1719 result = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1720 for p in self.Productions:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1721 if not p:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1722 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1723
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1724 for s in p.prod:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1725 if s not in self.Prodnames and s not in self.Terminals and s != 'error':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1726 result.append((s, p))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1727 return result
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1728
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1729 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1730 # unused_terminals()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1731 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1732 # Find all terminals that were defined, but not used by the grammar. Returns
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1733 # a list of all symbols.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1734 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1735 def unused_terminals(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1736 unused_tok = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1737 for s, v in self.Terminals.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1738 if s != 'error' and not v:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1739 unused_tok.append(s)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1740
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1741 return unused_tok
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1742
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1743 # ------------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1744 # unused_rules()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1745 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1746 # Find all grammar rules that were defined, but not used (maybe not reachable)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1747 # Returns a list of productions.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1748 # ------------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1749
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1750 def unused_rules(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1751 unused_prod = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1752 for s, v in self.Nonterminals.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1753 if not v:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1754 p = self.Prodnames[s][0]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1755 unused_prod.append(p)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1756 return unused_prod
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1757
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1758 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1759 # unused_precedence()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1760 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1761 # Returns a list of tuples (term,precedence) corresponding to precedence
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1762 # rules that were never used by the grammar. term is the name of the terminal
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1763 # on which precedence was applied and precedence is a string such as 'left' or
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1764 # 'right' corresponding to the type of precedence.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1765 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1766
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1767 def unused_precedence(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1768 unused = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1769 for termname in self.Precedence:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1770 if not (termname in self.Terminals or termname in self.UsedPrecedence):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1771 unused.append((termname, self.Precedence[termname][0]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1772
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1773 return unused
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1774
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1775 # -------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1776 # _first()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1777 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1778 # Compute the value of FIRST1(beta) where beta is a tuple of symbols.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1779 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1780 # During execution of compute_first1, the result may be incomplete.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1781 # Afterward (e.g., when called from compute_follow()), it will be complete.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1782 # -------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1783 def _first(self, beta):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1784
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1785 # We are computing First(x1,x2,x3,...,xn)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1786 result = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1787 for x in beta:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1788 x_produces_empty = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1789
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1790 # Add all the non-<empty> symbols of First[x] to the result.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1791 for f in self.First[x]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1792 if f == '<empty>':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1793 x_produces_empty = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1794 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1795 if f not in result:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1796 result.append(f)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1797
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1798 if x_produces_empty:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1799 # We have to consider the next x in beta,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1800 # i.e. stay in the loop.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1801 pass
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1802 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1803 # We don't have to consider any further symbols in beta.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1804 break
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1805 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1806 # There was no 'break' from the loop,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1807 # so x_produces_empty was true for all x in beta,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1808 # so beta produces empty as well.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1809 result.append('<empty>')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1810
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1811 return result
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1812
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1813 # -------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1814 # compute_first()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1815 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1816 # Compute the value of FIRST1(X) for all symbols
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1817 # -------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1818 def compute_first(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1819 if self.First:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1820 return self.First
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1821
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1822 # Terminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1823 for t in self.Terminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1824 self.First[t] = [t]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1825
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1826 self.First['$end'] = ['$end']
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1827
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1828 # Nonterminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1829
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1830 # Initialize to the empty set:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1831 for n in self.Nonterminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1832 self.First[n] = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1833
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1834 # Then propagate symbols until no change:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1835 while True:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1836 some_change = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1837 for n in self.Nonterminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1838 for p in self.Prodnames[n]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1839 for f in self._first(p.prod):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1840 if f not in self.First[n]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1841 self.First[n].append(f)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1842 some_change = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1843 if not some_change:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1844 break
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1845
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1846 return self.First
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1847
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1848 # ---------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1849 # compute_follow()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1850 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1851 # Computes all of the follow sets for every non-terminal symbol. The
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1852 # follow set is the set of all symbols that might follow a given
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1853 # non-terminal. See the Dragon book, 2nd Ed. p. 189.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1854 # ---------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1855 def compute_follow(self, start=None):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1856 # If already computed, return the result
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1857 if self.Follow:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1858 return self.Follow
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1859
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1860 # If first sets not computed yet, do that first.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1861 if not self.First:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1862 self.compute_first()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1863
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1864 # Add '$end' to the follow list of the start symbol
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1865 for k in self.Nonterminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1866 self.Follow[k] = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1867
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1868 if not start:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1869 start = self.Productions[1].name
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1870
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1871 self.Follow[start] = ['$end']
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1872
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1873 while True:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1874 didadd = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1875 for p in self.Productions[1:]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1876 # Here is the production set
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1877 for i, B in enumerate(p.prod):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1878 if B in self.Nonterminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1879 # Okay. We got a non-terminal in a production
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1880 fst = self._first(p.prod[i+1:])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1881 hasempty = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1882 for f in fst:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1883 if f != '<empty>' and f not in self.Follow[B]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1884 self.Follow[B].append(f)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1885 didadd = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1886 if f == '<empty>':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1887 hasempty = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1888 if hasempty or i == (len(p.prod)-1):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1889 # Add elements of follow(a) to follow(b)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1890 for f in self.Follow[p.name]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1891 if f not in self.Follow[B]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1892 self.Follow[B].append(f)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1893 didadd = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1894 if not didadd:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1895 break
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1896 return self.Follow
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1897
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1898
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1899 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1900 # build_lritems()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1901 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1902 # This function walks the list of productions and builds a complete set of the
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1903 # LR items. The LR items are stored in two ways: First, they are uniquely
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1904 # numbered and placed in the list _lritems. Second, a linked list of LR items
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1905 # is built for each production. For example:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1906 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1907 # E -> E PLUS E
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1908 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1909 # Creates the list
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1910 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1911 # [E -> . E PLUS E, E -> E . PLUS E, E -> E PLUS . E, E -> E PLUS E . ]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1912 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1913
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1914 def build_lritems(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1915 for p in self.Productions:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1916 lastlri = p
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1917 i = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1918 lr_items = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1919 while True:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1920 if i > len(p):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1921 lri = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1922 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1923 lri = LRItem(p, i)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1924 # Precompute the list of productions immediately following
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1925 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1926 lri.lr_after = self.Prodnames[lri.prod[i+1]]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1927 except (IndexError, KeyError):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1928 lri.lr_after = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1929 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1930 lri.lr_before = lri.prod[i-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1931 except IndexError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1932 lri.lr_before = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1933
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1934 lastlri.lr_next = lri
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1935 if not lri:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1936 break
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1937 lr_items.append(lri)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1938 lastlri = lri
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1939 i += 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1940 p.lr_items = lr_items
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1941
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1942 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1943 # == Class LRTable ==
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1944 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1945 # This basic class represents a basic table of LR parsing information.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1946 # Methods for generating the tables are not defined here. They are defined
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1947 # in the derived class LRGeneratedTable.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1948 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1949
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1950 class VersionError(YaccError):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1951 pass
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1952
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1953 class LRTable(object):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1954 def __init__(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1955 self.lr_action = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1956 self.lr_goto = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1957 self.lr_productions = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1958 self.lr_method = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1959
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1960 def read_table(self, module):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1961 if isinstance(module, types.ModuleType):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1962 parsetab = module
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1963 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1964 exec('import %s' % module)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1965 parsetab = sys.modules[module]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1966
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1967 if parsetab._tabversion != __tabversion__:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1968 raise VersionError('yacc table file version is out of date')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1969
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1970 self.lr_action = parsetab._lr_action
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1971 self.lr_goto = parsetab._lr_goto
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1972
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1973 self.lr_productions = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1974 for p in parsetab._lr_productions:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1975 self.lr_productions.append(MiniProduction(*p))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1976
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1977 self.lr_method = parsetab._lr_method
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1978 return parsetab._lr_signature
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1979
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1980 def read_pickle(self, filename):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1981 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1982 import cPickle as pickle
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1983 except ImportError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1984 import pickle
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1985
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1986 if not os.path.exists(filename):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1987 raise ImportError
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1988
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1989 in_f = open(filename, 'rb')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1990
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1991 tabversion = pickle.load(in_f)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1992 if tabversion != __tabversion__:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1993 raise VersionError('yacc table file version is out of date')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1994 self.lr_method = pickle.load(in_f)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1995 signature = pickle.load(in_f)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1996 self.lr_action = pickle.load(in_f)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1997 self.lr_goto = pickle.load(in_f)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1998 productions = pickle.load(in_f)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
1999
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2000 self.lr_productions = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2001 for p in productions:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2002 self.lr_productions.append(MiniProduction(*p))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2003
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2004 in_f.close()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2005 return signature
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2006
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2007 # Bind all production function names to callable objects in pdict
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2008 def bind_callables(self, pdict):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2009 for p in self.lr_productions:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2010 p.bind(pdict)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2011
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2012
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2013 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2014 # === LR Generator ===
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2015 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2016 # The following classes and functions are used to generate LR parsing tables on
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2017 # a grammar.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2018 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2019
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2020 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2021 # digraph()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2022 # traverse()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2023 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2024 # The following two functions are used to compute set valued functions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2025 # of the form:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2026 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2027 # F(x) = F'(x) U U{F(y) | x R y}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2028 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2029 # This is used to compute the values of Read() sets as well as FOLLOW sets
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2030 # in LALR(1) generation.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2031 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2032 # Inputs: X - An input set
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2033 # R - A relation
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2034 # FP - Set-valued function
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2035 # ------------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2036
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2037 def digraph(X, R, FP):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2038 N = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2039 for x in X:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2040 N[x] = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2041 stack = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2042 F = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2043 for x in X:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2044 if N[x] == 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2045 traverse(x, N, stack, F, X, R, FP)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2046 return F
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2047
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2048 def traverse(x, N, stack, F, X, R, FP):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2049 stack.append(x)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2050 d = len(stack)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2051 N[x] = d
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2052 F[x] = FP(x) # F(X) <- F'(x)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2053
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2054 rel = R(x) # Get y's related to x
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2055 for y in rel:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2056 if N[y] == 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2057 traverse(y, N, stack, F, X, R, FP)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2058 N[x] = min(N[x], N[y])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2059 for a in F.get(y, []):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2060 if a not in F[x]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2061 F[x].append(a)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2062 if N[x] == d:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2063 N[stack[-1]] = MAXINT
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2064 F[stack[-1]] = F[x]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2065 element = stack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2066 while element != x:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2067 N[stack[-1]] = MAXINT
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2068 F[stack[-1]] = F[x]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2069 element = stack.pop()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2070
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2071 class LALRError(YaccError):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2072 pass
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2073
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2074 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2075 # == LRGeneratedTable ==
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2076 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2077 # This class implements the LR table generation algorithm. There are no
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2078 # public methods except for write()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2079 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2080
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2081 class LRGeneratedTable(LRTable):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2082 def __init__(self, grammar, method='LALR', log=None):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2083 if method not in ['SLR', 'LALR']:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2084 raise LALRError('Unsupported method %s' % method)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2085
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2086 self.grammar = grammar
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2087 self.lr_method = method
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2088
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2089 # Set up the logger
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2090 if not log:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2091 log = NullLogger()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2092 self.log = log
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2093
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2094 # Internal attributes
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2095 self.lr_action = {} # Action table
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2096 self.lr_goto = {} # Goto table
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2097 self.lr_productions = grammar.Productions # Copy of grammar Production array
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2098 self.lr_goto_cache = {} # Cache of computed gotos
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2099 self.lr0_cidhash = {} # Cache of closures
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2100
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2101 self._add_count = 0 # Internal counter used to detect cycles
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2102
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2103 # Diagonistic information filled in by the table generator
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2104 self.sr_conflict = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2105 self.rr_conflict = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2106 self.conflicts = [] # List of conflicts
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2107
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2108 self.sr_conflicts = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2109 self.rr_conflicts = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2110
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2111 # Build the tables
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2112 self.grammar.build_lritems()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2113 self.grammar.compute_first()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2114 self.grammar.compute_follow()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2115 self.lr_parse_table()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2116
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2117 # Compute the LR(0) closure operation on I, where I is a set of LR(0) items.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2118
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2119 def lr0_closure(self, I):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2120 self._add_count += 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2121
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2122 # Add everything in I to J
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2123 J = I[:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2124 didadd = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2125 while didadd:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2126 didadd = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2127 for j in J:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2128 for x in j.lr_after:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2129 if getattr(x, 'lr0_added', 0) == self._add_count:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2130 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2131 # Add B --> .G to J
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2132 J.append(x.lr_next)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2133 x.lr0_added = self._add_count
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2134 didadd = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2135
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2136 return J
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2137
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2138 # Compute the LR(0) goto function goto(I,X) where I is a set
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2139 # of LR(0) items and X is a grammar symbol. This function is written
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2140 # in a way that guarantees uniqueness of the generated goto sets
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2141 # (i.e. the same goto set will never be returned as two different Python
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2142 # objects). With uniqueness, we can later do fast set comparisons using
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2143 # id(obj) instead of element-wise comparison.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2144
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2145 def lr0_goto(self, I, x):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2146 # First we look for a previously cached entry
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2147 g = self.lr_goto_cache.get((id(I), x))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2148 if g:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2149 return g
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2150
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2151 # Now we generate the goto set in a way that guarantees uniqueness
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2152 # of the result
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2153
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2154 s = self.lr_goto_cache.get(x)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2155 if not s:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2156 s = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2157 self.lr_goto_cache[x] = s
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2158
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2159 gs = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2160 for p in I:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2161 n = p.lr_next
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2162 if n and n.lr_before == x:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2163 s1 = s.get(id(n))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2164 if not s1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2165 s1 = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2166 s[id(n)] = s1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2167 gs.append(n)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2168 s = s1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2169 g = s.get('$end')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2170 if not g:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2171 if gs:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2172 g = self.lr0_closure(gs)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2173 s['$end'] = g
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2174 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2175 s['$end'] = gs
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2176 self.lr_goto_cache[(id(I), x)] = g
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2177 return g
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2178
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2179 # Compute the LR(0) sets of item function
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2180 def lr0_items(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2181 C = [self.lr0_closure([self.grammar.Productions[0].lr_next])]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2182 i = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2183 for I in C:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2184 self.lr0_cidhash[id(I)] = i
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2185 i += 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2186
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2187 # Loop over the items in C and each grammar symbols
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2188 i = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2189 while i < len(C):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2190 I = C[i]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2191 i += 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2192
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2193 # Collect all of the symbols that could possibly be in the goto(I,X) sets
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2194 asyms = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2195 for ii in I:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2196 for s in ii.usyms:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2197 asyms[s] = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2198
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2199 for x in asyms:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2200 g = self.lr0_goto(I, x)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2201 if not g or id(g) in self.lr0_cidhash:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2202 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2203 self.lr0_cidhash[id(g)] = len(C)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2204 C.append(g)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2205
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2206 return C
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2207
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2208 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2209 # ==== LALR(1) Parsing ====
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2210 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2211 # LALR(1) parsing is almost exactly the same as SLR except that instead of
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2212 # relying upon Follow() sets when performing reductions, a more selective
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2213 # lookahead set that incorporates the state of the LR(0) machine is utilized.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2214 # Thus, we mainly just have to focus on calculating the lookahead sets.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2215 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2216 # The method used here is due to DeRemer and Pennelo (1982).
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2217 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2218 # DeRemer, F. L., and T. J. Pennelo: "Efficient Computation of LALR(1)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2219 # Lookahead Sets", ACM Transactions on Programming Languages and Systems,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2220 # Vol. 4, No. 4, Oct. 1982, pp. 615-649
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2221 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2222 # Further details can also be found in:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2223 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2224 # J. Tremblay and P. Sorenson, "The Theory and Practice of Compiler Writing",
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2225 # McGraw-Hill Book Company, (1985).
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2226 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2227 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2228
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2229 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2230 # compute_nullable_nonterminals()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2231 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2232 # Creates a dictionary containing all of the non-terminals that might produce
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2233 # an empty production.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2234 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2235
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2236 def compute_nullable_nonterminals(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2237 nullable = set()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2238 num_nullable = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2239 while True:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2240 for p in self.grammar.Productions[1:]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2241 if p.len == 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2242 nullable.add(p.name)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2243 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2244 for t in p.prod:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2245 if t not in nullable:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2246 break
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2247 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2248 nullable.add(p.name)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2249 if len(nullable) == num_nullable:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2250 break
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2251 num_nullable = len(nullable)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2252 return nullable
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2253
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2254 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2255 # find_nonterminal_trans(C)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2256 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2257 # Given a set of LR(0) items, this functions finds all of the non-terminal
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2258 # transitions. These are transitions in which a dot appears immediately before
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2259 # a non-terminal. Returns a list of tuples of the form (state,N) where state
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2260 # is the state number and N is the nonterminal symbol.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2261 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2262 # The input C is the set of LR(0) items.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2263 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2264
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2265 def find_nonterminal_transitions(self, C):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2266 trans = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2267 for stateno, state in enumerate(C):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2268 for p in state:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2269 if p.lr_index < p.len - 1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2270 t = (stateno, p.prod[p.lr_index+1])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2271 if t[1] in self.grammar.Nonterminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2272 if t not in trans:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2273 trans.append(t)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2274 return trans
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2275
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2276 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2277 # dr_relation()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2278 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2279 # Computes the DR(p,A) relationships for non-terminal transitions. The input
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2280 # is a tuple (state,N) where state is a number and N is a nonterminal symbol.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2281 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2282 # Returns a list of terminals.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2283 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2284
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2285 def dr_relation(self, C, trans, nullable):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2286 dr_set = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2287 state, N = trans
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2288 terms = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2289
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2290 g = self.lr0_goto(C[state], N)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2291 for p in g:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2292 if p.lr_index < p.len - 1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2293 a = p.prod[p.lr_index+1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2294 if a in self.grammar.Terminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2295 if a not in terms:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2296 terms.append(a)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2297
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2298 # This extra bit is to handle the start state
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2299 if state == 0 and N == self.grammar.Productions[0].prod[0]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2300 terms.append('$end')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2301
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2302 return terms
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2303
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2304 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2305 # reads_relation()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2306 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2307 # Computes the READS() relation (p,A) READS (t,C).
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2308 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2309
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2310 def reads_relation(self, C, trans, empty):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2311 # Look for empty transitions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2312 rel = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2313 state, N = trans
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2314
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2315 g = self.lr0_goto(C[state], N)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2316 j = self.lr0_cidhash.get(id(g), -1)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2317 for p in g:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2318 if p.lr_index < p.len - 1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2319 a = p.prod[p.lr_index + 1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2320 if a in empty:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2321 rel.append((j, a))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2322
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2323 return rel
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2324
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2325 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2326 # compute_lookback_includes()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2327 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2328 # Determines the lookback and includes relations
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2329 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2330 # LOOKBACK:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2331 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2332 # This relation is determined by running the LR(0) state machine forward.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2333 # For example, starting with a production "N : . A B C", we run it forward
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2334 # to obtain "N : A B C ." We then build a relationship between this final
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2335 # state and the starting state. These relationships are stored in a dictionary
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2336 # lookdict.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2337 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2338 # INCLUDES:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2339 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2340 # Computes the INCLUDE() relation (p,A) INCLUDES (p',B).
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2341 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2342 # This relation is used to determine non-terminal transitions that occur
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2343 # inside of other non-terminal transition states. (p,A) INCLUDES (p', B)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2344 # if the following holds:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2345 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2346 # B -> LAT, where T -> epsilon and p' -L-> p
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2347 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2348 # L is essentially a prefix (which may be empty), T is a suffix that must be
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2349 # able to derive an empty string. State p' must lead to state p with the string L.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2350 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2351 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2352
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2353 def compute_lookback_includes(self, C, trans, nullable):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2354 lookdict = {} # Dictionary of lookback relations
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2355 includedict = {} # Dictionary of include relations
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2356
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2357 # Make a dictionary of non-terminal transitions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2358 dtrans = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2359 for t in trans:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2360 dtrans[t] = 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2361
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2362 # Loop over all transitions and compute lookbacks and includes
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2363 for state, N in trans:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2364 lookb = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2365 includes = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2366 for p in C[state]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2367 if p.name != N:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2368 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2369
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2370 # Okay, we have a name match. We now follow the production all the way
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2371 # through the state machine until we get the . on the right hand side
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2372
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2373 lr_index = p.lr_index
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2374 j = state
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2375 while lr_index < p.len - 1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2376 lr_index = lr_index + 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2377 t = p.prod[lr_index]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2378
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2379 # Check to see if this symbol and state are a non-terminal transition
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2380 if (j, t) in dtrans:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2381 # Yes. Okay, there is some chance that this is an includes relation
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2382 # the only way to know for certain is whether the rest of the
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2383 # production derives empty
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2384
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2385 li = lr_index + 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2386 while li < p.len:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2387 if p.prod[li] in self.grammar.Terminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2388 break # No forget it
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2389 if p.prod[li] not in nullable:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2390 break
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2391 li = li + 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2392 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2393 # Appears to be a relation between (j,t) and (state,N)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2394 includes.append((j, t))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2395
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2396 g = self.lr0_goto(C[j], t) # Go to next set
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2397 j = self.lr0_cidhash.get(id(g), -1) # Go to next state
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2398
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2399 # When we get here, j is the final state, now we have to locate the production
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2400 for r in C[j]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2401 if r.name != p.name:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2402 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2403 if r.len != p.len:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2404 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2405 i = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2406 # This look is comparing a production ". A B C" with "A B C ."
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2407 while i < r.lr_index:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2408 if r.prod[i] != p.prod[i+1]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2409 break
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2410 i = i + 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2411 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2412 lookb.append((j, r))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2413 for i in includes:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2414 if i not in includedict:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2415 includedict[i] = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2416 includedict[i].append((state, N))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2417 lookdict[(state, N)] = lookb
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2418
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2419 return lookdict, includedict
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2420
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2421 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2422 # compute_read_sets()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2423 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2424 # Given a set of LR(0) items, this function computes the read sets.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2425 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2426 # Inputs: C = Set of LR(0) items
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2427 # ntrans = Set of nonterminal transitions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2428 # nullable = Set of empty transitions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2429 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2430 # Returns a set containing the read sets
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2431 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2432
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2433 def compute_read_sets(self, C, ntrans, nullable):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2434 FP = lambda x: self.dr_relation(C, x, nullable)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2435 R = lambda x: self.reads_relation(C, x, nullable)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2436 F = digraph(ntrans, R, FP)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2437 return F
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2438
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2439 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2440 # compute_follow_sets()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2441 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2442 # Given a set of LR(0) items, a set of non-terminal transitions, a readset,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2443 # and an include set, this function computes the follow sets
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2444 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2445 # Follow(p,A) = Read(p,A) U U {Follow(p',B) | (p,A) INCLUDES (p',B)}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2446 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2447 # Inputs:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2448 # ntrans = Set of nonterminal transitions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2449 # readsets = Readset (previously computed)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2450 # inclsets = Include sets (previously computed)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2451 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2452 # Returns a set containing the follow sets
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2453 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2454
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2455 def compute_follow_sets(self, ntrans, readsets, inclsets):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2456 FP = lambda x: readsets[x]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2457 R = lambda x: inclsets.get(x, [])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2458 F = digraph(ntrans, R, FP)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2459 return F
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2460
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2461 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2462 # add_lookaheads()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2463 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2464 # Attaches the lookahead symbols to grammar rules.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2465 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2466 # Inputs: lookbacks - Set of lookback relations
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2467 # followset - Computed follow set
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2468 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2469 # This function directly attaches the lookaheads to productions contained
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2470 # in the lookbacks set
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2471 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2472
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2473 def add_lookaheads(self, lookbacks, followset):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2474 for trans, lb in lookbacks.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2475 # Loop over productions in lookback
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2476 for state, p in lb:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2477 if state not in p.lookaheads:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2478 p.lookaheads[state] = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2479 f = followset.get(trans, [])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2480 for a in f:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2481 if a not in p.lookaheads[state]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2482 p.lookaheads[state].append(a)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2483
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2484 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2485 # add_lalr_lookaheads()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2486 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2487 # This function does all of the work of adding lookahead information for use
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2488 # with LALR parsing
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2489 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2490
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2491 def add_lalr_lookaheads(self, C):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2492 # Determine all of the nullable nonterminals
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2493 nullable = self.compute_nullable_nonterminals()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2494
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2495 # Find all non-terminal transitions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2496 trans = self.find_nonterminal_transitions(C)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2497
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2498 # Compute read sets
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2499 readsets = self.compute_read_sets(C, trans, nullable)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2500
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2501 # Compute lookback/includes relations
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2502 lookd, included = self.compute_lookback_includes(C, trans, nullable)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2503
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2504 # Compute LALR FOLLOW sets
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2505 followsets = self.compute_follow_sets(trans, readsets, included)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2506
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2507 # Add all of the lookaheads
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2508 self.add_lookaheads(lookd, followsets)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2509
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2510 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2511 # lr_parse_table()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2512 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2513 # This function constructs the parse tables for SLR or LALR
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2514 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2515 def lr_parse_table(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2516 Productions = self.grammar.Productions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2517 Precedence = self.grammar.Precedence
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2518 goto = self.lr_goto # Goto array
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2519 action = self.lr_action # Action array
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2520 log = self.log # Logger for output
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2521
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2522 actionp = {} # Action production array (temporary)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2523
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2524 log.info('Parsing method: %s', self.lr_method)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2525
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2526 # Step 1: Construct C = { I0, I1, ... IN}, collection of LR(0) items
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2527 # This determines the number of states
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2528
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2529 C = self.lr0_items()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2530
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2531 if self.lr_method == 'LALR':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2532 self.add_lalr_lookaheads(C)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2533
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2534 # Build the parser table, state by state
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2535 st = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2536 for I in C:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2537 # Loop over each production in I
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2538 actlist = [] # List of actions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2539 st_action = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2540 st_actionp = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2541 st_goto = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2542 log.info('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2543 log.info('state %d', st)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2544 log.info('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2545 for p in I:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2546 log.info(' (%d) %s', p.number, p)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2547 log.info('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2548
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2549 for p in I:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2550 if p.len == p.lr_index + 1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2551 if p.name == "S'":
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2552 # Start symbol. Accept!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2553 st_action['$end'] = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2554 st_actionp['$end'] = p
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2555 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2556 # We are at the end of a production. Reduce!
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2557 if self.lr_method == 'LALR':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2558 laheads = p.lookaheads[st]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2559 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2560 laheads = self.grammar.Follow[p.name]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2561 for a in laheads:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2562 actlist.append((a, p, 'reduce using rule %d (%s)' % (p.number, p)))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2563 r = st_action.get(a)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2564 if r is not None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2565 # Whoa. Have a shift/reduce or reduce/reduce conflict
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2566 if r > 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2567 # Need to decide on shift or reduce here
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2568 # By default we favor shifting. Need to add
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2569 # some precedence rules here.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2570 sprec, slevel = Productions[st_actionp[a].number].prec
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2571 rprec, rlevel = Precedence.get(a, ('right', 0))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2572 if (slevel < rlevel) or ((slevel == rlevel) and (rprec == 'left')):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2573 # We really need to reduce here.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2574 st_action[a] = -p.number
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2575 st_actionp[a] = p
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2576 if not slevel and not rlevel:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2577 log.info(' ! shift/reduce conflict for %s resolved as reduce', a)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2578 self.sr_conflicts.append((st, a, 'reduce'))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2579 Productions[p.number].reduced += 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2580 elif (slevel == rlevel) and (rprec == 'nonassoc'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2581 st_action[a] = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2582 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2583 # Hmmm. Guess we'll keep the shift
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2584 if not rlevel:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2585 log.info(' ! shift/reduce conflict for %s resolved as shift', a)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2586 self.sr_conflicts.append((st, a, 'shift'))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2587 elif r < 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2588 # Reduce/reduce conflict. In this case, we favor the rule
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2589 # that was defined first in the grammar file
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2590 oldp = Productions[-r]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2591 pp = Productions[p.number]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2592 if oldp.line > pp.line:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2593 st_action[a] = -p.number
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2594 st_actionp[a] = p
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2595 chosenp, rejectp = pp, oldp
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2596 Productions[p.number].reduced += 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2597 Productions[oldp.number].reduced -= 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2598 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2599 chosenp, rejectp = oldp, pp
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2600 self.rr_conflicts.append((st, chosenp, rejectp))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2601 log.info(' ! reduce/reduce conflict for %s resolved using rule %d (%s)',
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2602 a, st_actionp[a].number, st_actionp[a])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2603 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2604 raise LALRError('Unknown conflict in state %d' % st)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2605 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2606 st_action[a] = -p.number
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2607 st_actionp[a] = p
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2608 Productions[p.number].reduced += 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2609 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2610 i = p.lr_index
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2611 a = p.prod[i+1] # Get symbol right after the "."
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2612 if a in self.grammar.Terminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2613 g = self.lr0_goto(I, a)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2614 j = self.lr0_cidhash.get(id(g), -1)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2615 if j >= 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2616 # We are in a shift state
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2617 actlist.append((a, p, 'shift and go to state %d' % j))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2618 r = st_action.get(a)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2619 if r is not None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2620 # Whoa have a shift/reduce or shift/shift conflict
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2621 if r > 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2622 if r != j:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2623 raise LALRError('Shift/shift conflict in state %d' % st)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2624 elif r < 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2625 # Do a precedence check.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2626 # - if precedence of reduce rule is higher, we reduce.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2627 # - if precedence of reduce is same and left assoc, we reduce.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2628 # - otherwise we shift
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2629 rprec, rlevel = Productions[st_actionp[a].number].prec
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2630 sprec, slevel = Precedence.get(a, ('right', 0))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2631 if (slevel > rlevel) or ((slevel == rlevel) and (rprec == 'right')):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2632 # We decide to shift here... highest precedence to shift
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2633 Productions[st_actionp[a].number].reduced -= 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2634 st_action[a] = j
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2635 st_actionp[a] = p
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2636 if not rlevel:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2637 log.info(' ! shift/reduce conflict for %s resolved as shift', a)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2638 self.sr_conflicts.append((st, a, 'shift'))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2639 elif (slevel == rlevel) and (rprec == 'nonassoc'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2640 st_action[a] = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2641 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2642 # Hmmm. Guess we'll keep the reduce
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2643 if not slevel and not rlevel:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2644 log.info(' ! shift/reduce conflict for %s resolved as reduce', a)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2645 self.sr_conflicts.append((st, a, 'reduce'))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2646
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2647 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2648 raise LALRError('Unknown conflict in state %d' % st)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2649 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2650 st_action[a] = j
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2651 st_actionp[a] = p
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2652
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2653 # Print the actions associated with each terminal
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2654 _actprint = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2655 for a, p, m in actlist:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2656 if a in st_action:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2657 if p is st_actionp[a]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2658 log.info(' %-15s %s', a, m)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2659 _actprint[(a, m)] = 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2660 log.info('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2661 # Print the actions that were not used. (debugging)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2662 not_used = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2663 for a, p, m in actlist:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2664 if a in st_action:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2665 if p is not st_actionp[a]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2666 if not (a, m) in _actprint:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2667 log.debug(' ! %-15s [ %s ]', a, m)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2668 not_used = 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2669 _actprint[(a, m)] = 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2670 if not_used:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2671 log.debug('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2672
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2673 # Construct the goto table for this state
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2674
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2675 nkeys = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2676 for ii in I:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2677 for s in ii.usyms:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2678 if s in self.grammar.Nonterminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2679 nkeys[s] = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2680 for n in nkeys:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2681 g = self.lr0_goto(I, n)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2682 j = self.lr0_cidhash.get(id(g), -1)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2683 if j >= 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2684 st_goto[n] = j
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2685 log.info(' %-30s shift and go to state %d', n, j)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2686
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2687 action[st] = st_action
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2688 actionp[st] = st_actionp
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2689 goto[st] = st_goto
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2690 st += 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2691
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2692 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2693 # write()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2694 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2695 # This function writes the LR parsing tables to a file
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2696 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2697
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2698 def write_table(self, tabmodule, outputdir='', signature=''):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2699 if isinstance(tabmodule, types.ModuleType):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2700 raise IOError("Won't overwrite existing tabmodule")
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2701
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2702 basemodulename = tabmodule.split('.')[-1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2703 filename = os.path.join(outputdir, basemodulename) + '.py'
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2704 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2705 f = open(filename, 'w')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2706
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2707 f.write('''
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2708 # %s
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2709 # This file is automatically generated. Do not edit.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2710 _tabversion = %r
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2711
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2712 _lr_method = %r
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2713
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2714 _lr_signature = %r
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2715 ''' % (os.path.basename(filename), __tabversion__, self.lr_method, signature))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2716
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2717 # Change smaller to 0 to go back to original tables
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2718 smaller = 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2719
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2720 # Factor out names to try and make smaller
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2721 if smaller:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2722 items = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2723
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2724 for s, nd in self.lr_action.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2725 for name, v in nd.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2726 i = items.get(name)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2727 if not i:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2728 i = ([], [])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2729 items[name] = i
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2730 i[0].append(s)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2731 i[1].append(v)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2732
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2733 f.write('\n_lr_action_items = {')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2734 for k, v in items.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2735 f.write('%r:([' % k)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2736 for i in v[0]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2737 f.write('%r,' % i)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2738 f.write('],[')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2739 for i in v[1]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2740 f.write('%r,' % i)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2741
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2742 f.write(']),')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2743 f.write('}\n')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2744
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2745 f.write('''
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2746 _lr_action = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2747 for _k, _v in _lr_action_items.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2748 for _x,_y in zip(_v[0],_v[1]):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2749 if not _x in _lr_action: _lr_action[_x] = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2750 _lr_action[_x][_k] = _y
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2751 del _lr_action_items
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2752 ''')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2753
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2754 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2755 f.write('\n_lr_action = { ')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2756 for k, v in self.lr_action.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2757 f.write('(%r,%r):%r,' % (k[0], k[1], v))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2758 f.write('}\n')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2759
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2760 if smaller:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2761 # Factor out names to try and make smaller
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2762 items = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2763
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2764 for s, nd in self.lr_goto.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2765 for name, v in nd.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2766 i = items.get(name)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2767 if not i:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2768 i = ([], [])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2769 items[name] = i
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2770 i[0].append(s)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2771 i[1].append(v)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2772
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2773 f.write('\n_lr_goto_items = {')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2774 for k, v in items.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2775 f.write('%r:([' % k)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2776 for i in v[0]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2777 f.write('%r,' % i)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2778 f.write('],[')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2779 for i in v[1]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2780 f.write('%r,' % i)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2781
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2782 f.write(']),')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2783 f.write('}\n')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2784
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2785 f.write('''
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2786 _lr_goto = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2787 for _k, _v in _lr_goto_items.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2788 for _x, _y in zip(_v[0], _v[1]):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2789 if not _x in _lr_goto: _lr_goto[_x] = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2790 _lr_goto[_x][_k] = _y
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2791 del _lr_goto_items
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2792 ''')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2793 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2794 f.write('\n_lr_goto = { ')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2795 for k, v in self.lr_goto.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2796 f.write('(%r,%r):%r,' % (k[0], k[1], v))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2797 f.write('}\n')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2798
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2799 # Write production table
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2800 f.write('_lr_productions = [\n')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2801 for p in self.lr_productions:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2802 if p.func:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2803 f.write(' (%r,%r,%d,%r,%r,%d),\n' % (p.str, p.name, p.len,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2804 p.func, os.path.basename(p.file), p.line))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2805 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2806 f.write(' (%r,%r,%d,None,None,None),\n' % (str(p), p.name, p.len))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2807 f.write(']\n')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2808 f.close()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2809
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2810 except IOError as e:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2811 raise
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2812
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2813
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2814 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2815 # pickle_table()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2816 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2817 # This function pickles the LR parsing tables to a supplied file object
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2818 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2819
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2820 def pickle_table(self, filename, signature=''):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2821 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2822 import cPickle as pickle
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2823 except ImportError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2824 import pickle
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2825 with open(filename, 'wb') as outf:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2826 pickle.dump(__tabversion__, outf, pickle_protocol)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2827 pickle.dump(self.lr_method, outf, pickle_protocol)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2828 pickle.dump(signature, outf, pickle_protocol)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2829 pickle.dump(self.lr_action, outf, pickle_protocol)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2830 pickle.dump(self.lr_goto, outf, pickle_protocol)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2831
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2832 outp = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2833 for p in self.lr_productions:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2834 if p.func:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2835 outp.append((p.str, p.name, p.len, p.func, os.path.basename(p.file), p.line))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2836 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2837 outp.append((str(p), p.name, p.len, None, None, None))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2838 pickle.dump(outp, outf, pickle_protocol)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2839
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2840 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2841 # === INTROSPECTION ===
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2842 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2843 # The following functions and classes are used to implement the PLY
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2844 # introspection features followed by the yacc() function itself.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2845 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2846
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2847 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2848 # get_caller_module_dict()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2849 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2850 # This function returns a dictionary containing all of the symbols defined within
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2851 # a caller further down the call stack. This is used to get the environment
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2852 # associated with the yacc() call if none was provided.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2853 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2854
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2855 def get_caller_module_dict(levels):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2856 f = sys._getframe(levels)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2857 ldict = f.f_globals.copy()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2858 if f.f_globals != f.f_locals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2859 ldict.update(f.f_locals)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2860 return ldict
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2861
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2862 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2863 # parse_grammar()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2864 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2865 # This takes a raw grammar rule string and parses it into production data
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2866 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2867 def parse_grammar(doc, file, line):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2868 grammar = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2869 # Split the doc string into lines
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2870 pstrings = doc.splitlines()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2871 lastp = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2872 dline = line
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2873 for ps in pstrings:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2874 dline += 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2875 p = ps.split()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2876 if not p:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2877 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2878 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2879 if p[0] == '|':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2880 # This is a continuation of a previous rule
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2881 if not lastp:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2882 raise SyntaxError("%s:%d: Misplaced '|'" % (file, dline))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2883 prodname = lastp
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2884 syms = p[1:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2885 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2886 prodname = p[0]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2887 lastp = prodname
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2888 syms = p[2:]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2889 assign = p[1]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2890 if assign != ':' and assign != '::=':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2891 raise SyntaxError("%s:%d: Syntax error. Expected ':'" % (file, dline))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2892
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2893 grammar.append((file, dline, prodname, syms))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2894 except SyntaxError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2895 raise
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2896 except Exception:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2897 raise SyntaxError('%s:%d: Syntax error in rule %r' % (file, dline, ps.strip()))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2898
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2899 return grammar
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2900
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2901 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2902 # ParserReflect()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2903 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2904 # This class represents information extracted for building a parser including
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2905 # start symbol, error function, tokens, precedence list, action functions,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2906 # etc.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2907 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2908 class ParserReflect(object):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2909 def __init__(self, pdict, log=None):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2910 self.pdict = pdict
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2911 self.start = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2912 self.error_func = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2913 self.tokens = None
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2914 self.modules = set()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2915 self.grammar = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2916 self.error = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2917
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2918 if log is None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2919 self.log = PlyLogger(sys.stderr)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2920 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2921 self.log = log
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2922
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2923 # Get all of the basic information
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2924 def get_all(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2925 self.get_start()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2926 self.get_error_func()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2927 self.get_tokens()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2928 self.get_precedence()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2929 self.get_pfunctions()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2930
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2931 # Validate all of the information
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2932 def validate_all(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2933 self.validate_start()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2934 self.validate_error_func()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2935 self.validate_tokens()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2936 self.validate_precedence()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2937 self.validate_pfunctions()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2938 self.validate_modules()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2939 return self.error
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2940
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2941 # Compute a signature over the grammar
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2942 def signature(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2943 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2944 from hashlib import md5
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2945 except ImportError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2946 from md5 import md5
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2947 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2948 sig = md5()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2949 if self.start:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2950 sig.update(self.start.encode('latin-1'))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2951 if self.prec:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2952 sig.update(''.join([''.join(p) for p in self.prec]).encode('latin-1'))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2953 if self.tokens:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2954 sig.update(' '.join(self.tokens).encode('latin-1'))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2955 for f in self.pfuncs:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2956 if f[3]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2957 sig.update(f[3].encode('latin-1'))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2958 except (TypeError, ValueError):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2959 pass
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2960
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2961 digest = base64.b16encode(sig.digest())
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2962 if sys.version_info[0] >= 3:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2963 digest = digest.decode('latin-1')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2964 return digest
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2965
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2966 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2967 # validate_modules()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2968 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2969 # This method checks to see if there are duplicated p_rulename() functions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2970 # in the parser module file. Without this function, it is really easy for
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2971 # users to make mistakes by cutting and pasting code fragments (and it's a real
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2972 # bugger to try and figure out why the resulting parser doesn't work). Therefore,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2973 # we just do a little regular expression pattern matching of def statements
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2974 # to try and detect duplicates.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2975 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2976
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2977 def validate_modules(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2978 # Match def p_funcname(
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2979 fre = re.compile(r'\s*def\s+(p_[a-zA-Z_0-9]*)\(')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2980
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2981 for module in self.modules:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2982 lines, linen = inspect.getsourcelines(module)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2983
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2984 counthash = {}
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2985 for linen, line in enumerate(lines):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2986 linen += 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2987 m = fre.match(line)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2988 if m:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2989 name = m.group(1)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2990 prev = counthash.get(name)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2991 if not prev:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2992 counthash[name] = linen
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2993 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2994 filename = inspect.getsourcefile(module)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2995 self.log.warning('%s:%d: Function %s redefined. Previously defined on line %d',
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2996 filename, linen, name, prev)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2997
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2998 # Get the start symbol
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
2999 def get_start(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3000 self.start = self.pdict.get('start')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3001
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3002 # Validate the start symbol
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3003 def validate_start(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3004 if self.start is not None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3005 if not isinstance(self.start, string_types):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3006 self.log.error("'start' must be a string")
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3007
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3008 # Look for error handler
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3009 def get_error_func(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3010 self.error_func = self.pdict.get('p_error')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3011
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3012 # Validate the error function
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3013 def validate_error_func(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3014 if self.error_func:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3015 if isinstance(self.error_func, types.FunctionType):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3016 ismethod = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3017 elif isinstance(self.error_func, types.MethodType):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3018 ismethod = 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3019 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3020 self.log.error("'p_error' defined, but is not a function or method")
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3021 self.error = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3022 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3023
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3024 eline = self.error_func.__code__.co_firstlineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3025 efile = self.error_func.__code__.co_filename
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3026 module = inspect.getmodule(self.error_func)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3027 self.modules.add(module)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3028
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3029 argcount = self.error_func.__code__.co_argcount - ismethod
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3030 if argcount != 1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3031 self.log.error('%s:%d: p_error() requires 1 argument', efile, eline)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3032 self.error = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3033
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3034 # Get the tokens map
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3035 def get_tokens(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3036 tokens = self.pdict.get('tokens')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3037 if not tokens:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3038 self.log.error('No token list is defined')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3039 self.error = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3040 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3041
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3042 if not isinstance(tokens, (list, tuple)):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3043 self.log.error('tokens must be a list or tuple')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3044 self.error = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3045 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3046
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3047 if not tokens:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3048 self.log.error('tokens is empty')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3049 self.error = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3050 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3051
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3052 self.tokens = tokens
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3053
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3054 # Validate the tokens
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3055 def validate_tokens(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3056 # Validate the tokens.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3057 if 'error' in self.tokens:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3058 self.log.error("Illegal token name 'error'. Is a reserved word")
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3059 self.error = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3060 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3061
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3062 terminals = set()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3063 for n in self.tokens:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3064 if n in terminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3065 self.log.warning('Token %r multiply defined', n)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3066 terminals.add(n)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3067
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3068 # Get the precedence map (if any)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3069 def get_precedence(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3070 self.prec = self.pdict.get('precedence')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3071
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3072 # Validate and parse the precedence map
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3073 def validate_precedence(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3074 preclist = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3075 if self.prec:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3076 if not isinstance(self.prec, (list, tuple)):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3077 self.log.error('precedence must be a list or tuple')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3078 self.error = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3079 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3080 for level, p in enumerate(self.prec):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3081 if not isinstance(p, (list, tuple)):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3082 self.log.error('Bad precedence table')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3083 self.error = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3084 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3085
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3086 if len(p) < 2:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3087 self.log.error('Malformed precedence entry %s. Must be (assoc, term, ..., term)', p)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3088 self.error = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3089 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3090 assoc = p[0]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3091 if not isinstance(assoc, string_types):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3092 self.log.error('precedence associativity must be a string')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3093 self.error = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3094 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3095 for term in p[1:]:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3096 if not isinstance(term, string_types):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3097 self.log.error('precedence items must be strings')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3098 self.error = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3099 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3100 preclist.append((term, assoc, level+1))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3101 self.preclist = preclist
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3102
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3103 # Get all p_functions from the grammar
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3104 def get_pfunctions(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3105 p_functions = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3106 for name, item in self.pdict.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3107 if not name.startswith('p_') or name == 'p_error':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3108 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3109 if isinstance(item, (types.FunctionType, types.MethodType)):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3110 line = item.__code__.co_firstlineno
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3111 module = inspect.getmodule(item)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3112 p_functions.append((line, module, name, item.__doc__))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3113
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3114 # Sort all of the actions by line number; make sure to stringify
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3115 # modules to make them sortable, since `line` may not uniquely sort all
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3116 # p functions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3117 p_functions.sort(key=lambda p_function: (
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3118 p_function[0],
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3119 str(p_function[1]),
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3120 p_function[2],
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3121 p_function[3]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3122 self.pfuncs = p_functions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3123
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3124 # Validate all of the p_functions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3125 def validate_pfunctions(self):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3126 grammar = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3127 # Check for non-empty symbols
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3128 if len(self.pfuncs) == 0:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3129 self.log.error('no rules of the form p_rulename are defined')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3130 self.error = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3131 return
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3132
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3133 for line, module, name, doc in self.pfuncs:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3134 file = inspect.getsourcefile(module)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3135 func = self.pdict[name]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3136 if isinstance(func, types.MethodType):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3137 reqargs = 2
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3138 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3139 reqargs = 1
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3140 if func.__code__.co_argcount > reqargs:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3141 self.log.error('%s:%d: Rule %r has too many arguments', file, line, func.__name__)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3142 self.error = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3143 elif func.__code__.co_argcount < reqargs:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3144 self.log.error('%s:%d: Rule %r requires an argument', file, line, func.__name__)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3145 self.error = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3146 elif not func.__doc__:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3147 self.log.warning('%s:%d: No documentation string specified in function %r (ignored)',
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3148 file, line, func.__name__)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3149 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3150 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3151 parsed_g = parse_grammar(doc, file, line)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3152 for g in parsed_g:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3153 grammar.append((name, g))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3154 except SyntaxError as e:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3155 self.log.error(str(e))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3156 self.error = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3157
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3158 # Looks like a valid grammar rule
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3159 # Mark the file in which defined.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3160 self.modules.add(module)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3161
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3162 # Secondary validation step that looks for p_ definitions that are not functions
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3163 # or functions that look like they might be grammar rules.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3164
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3165 for n, v in self.pdict.items():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3166 if n.startswith('p_') and isinstance(v, (types.FunctionType, types.MethodType)):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3167 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3168 if n.startswith('t_'):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3169 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3170 if n.startswith('p_') and n != 'p_error':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3171 self.log.warning('%r not defined as a function', n)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3172 if ((isinstance(v, types.FunctionType) and v.__code__.co_argcount == 1) or
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3173 (isinstance(v, types.MethodType) and v.__func__.__code__.co_argcount == 2)):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3174 if v.__doc__:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3175 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3176 doc = v.__doc__.split(' ')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3177 if doc[1] == ':':
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3178 self.log.warning('%s:%d: Possible grammar rule %r defined without p_ prefix',
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3179 v.__code__.co_filename, v.__code__.co_firstlineno, n)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3180 except IndexError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3181 pass
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3182
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3183 self.grammar = grammar
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3184
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3185 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3186 # yacc(module)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3187 #
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3188 # Build a parser
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3189 # -----------------------------------------------------------------------------
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3190
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3191 def yacc(method='LALR', debug=yaccdebug, module=None, tabmodule=tab_module, start=None,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3192 check_recursion=True, optimize=False, write_tables=True, debugfile=debug_file,
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3193 outputdir=None, debuglog=None, errorlog=None, picklefile=None):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3194
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3195 if tabmodule is None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3196 tabmodule = tab_module
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3197
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3198 # Reference to the parsing method of the last built parser
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3199 global parse
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3200
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3201 # If pickling is enabled, table files are not created
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3202 if picklefile:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3203 write_tables = 0
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3204
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3205 if errorlog is None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3206 errorlog = PlyLogger(sys.stderr)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3207
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3208 # Get the module dictionary used for the parser
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3209 if module:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3210 _items = [(k, getattr(module, k)) for k in dir(module)]
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3211 pdict = dict(_items)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3212 # If no __file__ attribute is available, try to obtain it from the __module__ instead
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3213 if '__file__' not in pdict:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3214 pdict['__file__'] = sys.modules[pdict['__module__']].__file__
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3215 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3216 pdict = get_caller_module_dict(2)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3217
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3218 if outputdir is None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3219 # If no output directory is set, the location of the output files
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3220 # is determined according to the following rules:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3221 # - If tabmodule specifies a package, files go into that package directory
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3222 # - Otherwise, files go in the same directory as the specifying module
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3223 if isinstance(tabmodule, types.ModuleType):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3224 srcfile = tabmodule.__file__
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3225 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3226 if '.' not in tabmodule:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3227 srcfile = pdict['__file__']
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3228 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3229 parts = tabmodule.split('.')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3230 pkgname = '.'.join(parts[:-1])
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3231 exec('import %s' % pkgname)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3232 srcfile = getattr(sys.modules[pkgname], '__file__', '')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3233 outputdir = os.path.dirname(srcfile)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3234
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3235 # Determine if the module is package of a package or not.
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3236 # If so, fix the tabmodule setting so that tables load correctly
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3237 pkg = pdict.get('__package__')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3238 if pkg and isinstance(tabmodule, str):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3239 if '.' not in tabmodule:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3240 tabmodule = pkg + '.' + tabmodule
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3241
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3242
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3243
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3244 # Set start symbol if it's specified directly using an argument
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3245 if start is not None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3246 pdict['start'] = start
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3247
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3248 # Collect parser information from the dictionary
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3249 pinfo = ParserReflect(pdict, log=errorlog)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3250 pinfo.get_all()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3251
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3252 if pinfo.error:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3253 raise YaccError('Unable to build parser')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3254
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3255 # Check signature against table files (if any)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3256 signature = pinfo.signature()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3257
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3258 # Read the tables
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3259 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3260 lr = LRTable()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3261 if picklefile:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3262 read_signature = lr.read_pickle(picklefile)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3263 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3264 read_signature = lr.read_table(tabmodule)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3265 if optimize or (read_signature == signature):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3266 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3267 lr.bind_callables(pinfo.pdict)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3268 parser = LRParser(lr, pinfo.error_func)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3269 parse = parser.parse
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3270 return parser
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3271 except Exception as e:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3272 errorlog.warning('There was a problem loading the table file: %r', e)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3273 except VersionError as e:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3274 errorlog.warning(str(e))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3275 except ImportError:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3276 pass
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3277
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3278 if debuglog is None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3279 if debug:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3280 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3281 debuglog = PlyLogger(open(os.path.join(outputdir, debugfile), 'w'))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3282 except IOError as e:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3283 errorlog.warning("Couldn't open %r. %s" % (debugfile, e))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3284 debuglog = NullLogger()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3285 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3286 debuglog = NullLogger()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3287
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3288 debuglog.info('Created by PLY version %s (http://www.dabeaz.com/ply)', __version__)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3289
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3290 errors = False
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3291
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3292 # Validate the parser information
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3293 if pinfo.validate_all():
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3294 raise YaccError('Unable to build parser')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3295
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3296 if not pinfo.error_func:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3297 errorlog.warning('no p_error() function is defined')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3298
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3299 # Create a grammar object
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3300 grammar = Grammar(pinfo.tokens)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3301
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3302 # Set precedence level for terminals
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3303 for term, assoc, level in pinfo.preclist:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3304 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3305 grammar.set_precedence(term, assoc, level)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3306 except GrammarError as e:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3307 errorlog.warning('%s', e)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3308
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3309 # Add productions to the grammar
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3310 for funcname, gram in pinfo.grammar:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3311 file, line, prodname, syms = gram
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3312 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3313 grammar.add_production(prodname, syms, funcname, file, line)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3314 except GrammarError as e:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3315 errorlog.error('%s', e)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3316 errors = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3317
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3318 # Set the grammar start symbols
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3319 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3320 if start is None:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3321 grammar.set_start(pinfo.start)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3322 else:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3323 grammar.set_start(start)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3324 except GrammarError as e:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3325 errorlog.error(str(e))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3326 errors = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3327
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3328 if errors:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3329 raise YaccError('Unable to build parser')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3330
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3331 # Verify the grammar structure
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3332 undefined_symbols = grammar.undefined_symbols()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3333 for sym, prod in undefined_symbols:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3334 errorlog.error('%s:%d: Symbol %r used, but not defined as a token or a rule', prod.file, prod.line, sym)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3335 errors = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3336
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3337 unused_terminals = grammar.unused_terminals()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3338 if unused_terminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3339 debuglog.info('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3340 debuglog.info('Unused terminals:')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3341 debuglog.info('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3342 for term in unused_terminals:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3343 errorlog.warning('Token %r defined, but not used', term)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3344 debuglog.info(' %s', term)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3345
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3346 # Print out all productions to the debug log
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3347 if debug:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3348 debuglog.info('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3349 debuglog.info('Grammar')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3350 debuglog.info('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3351 for n, p in enumerate(grammar.Productions):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3352 debuglog.info('Rule %-5d %s', n, p)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3353
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3354 # Find unused non-terminals
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3355 unused_rules = grammar.unused_rules()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3356 for prod in unused_rules:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3357 errorlog.warning('%s:%d: Rule %r defined, but not used', prod.file, prod.line, prod.name)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3358
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3359 if len(unused_terminals) == 1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3360 errorlog.warning('There is 1 unused token')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3361 if len(unused_terminals) > 1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3362 errorlog.warning('There are %d unused tokens', len(unused_terminals))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3363
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3364 if len(unused_rules) == 1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3365 errorlog.warning('There is 1 unused rule')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3366 if len(unused_rules) > 1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3367 errorlog.warning('There are %d unused rules', len(unused_rules))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3368
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3369 if debug:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3370 debuglog.info('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3371 debuglog.info('Terminals, with rules where they appear')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3372 debuglog.info('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3373 terms = list(grammar.Terminals)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3374 terms.sort()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3375 for term in terms:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3376 debuglog.info('%-20s : %s', term, ' '.join([str(s) for s in grammar.Terminals[term]]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3377
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3378 debuglog.info('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3379 debuglog.info('Nonterminals, with rules where they appear')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3380 debuglog.info('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3381 nonterms = list(grammar.Nonterminals)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3382 nonterms.sort()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3383 for nonterm in nonterms:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3384 debuglog.info('%-20s : %s', nonterm, ' '.join([str(s) for s in grammar.Nonterminals[nonterm]]))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3385 debuglog.info('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3386
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3387 if check_recursion:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3388 unreachable = grammar.find_unreachable()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3389 for u in unreachable:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3390 errorlog.warning('Symbol %r is unreachable', u)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3391
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3392 infinite = grammar.infinite_cycles()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3393 for inf in infinite:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3394 errorlog.error('Infinite recursion detected for symbol %r', inf)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3395 errors = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3396
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3397 unused_prec = grammar.unused_precedence()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3398 for term, assoc in unused_prec:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3399 errorlog.error('Precedence rule %r defined for unknown symbol %r', assoc, term)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3400 errors = True
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3401
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3402 if errors:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3403 raise YaccError('Unable to build parser')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3404
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3405 # Run the LRGeneratedTable on the grammar
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3406 if debug:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3407 errorlog.debug('Generating %s tables', method)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3408
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3409 lr = LRGeneratedTable(grammar, method, debuglog)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3410
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3411 if debug:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3412 num_sr = len(lr.sr_conflicts)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3413
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3414 # Report shift/reduce and reduce/reduce conflicts
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3415 if num_sr == 1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3416 errorlog.warning('1 shift/reduce conflict')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3417 elif num_sr > 1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3418 errorlog.warning('%d shift/reduce conflicts', num_sr)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3419
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3420 num_rr = len(lr.rr_conflicts)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3421 if num_rr == 1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3422 errorlog.warning('1 reduce/reduce conflict')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3423 elif num_rr > 1:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3424 errorlog.warning('%d reduce/reduce conflicts', num_rr)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3425
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3426 # Write out conflicts to the output file
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3427 if debug and (lr.sr_conflicts or lr.rr_conflicts):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3428 debuglog.warning('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3429 debuglog.warning('Conflicts:')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3430 debuglog.warning('')
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3431
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3432 for state, tok, resolution in lr.sr_conflicts:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3433 debuglog.warning('shift/reduce conflict for %s in state %d resolved as %s', tok, state, resolution)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3434
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3435 already_reported = set()
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3436 for state, rule, rejected in lr.rr_conflicts:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3437 if (state, id(rule), id(rejected)) in already_reported:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3438 continue
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3439 debuglog.warning('reduce/reduce conflict in state %d resolved using rule (%s)', state, rule)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3440 debuglog.warning('rejected rule (%s) in state %d', rejected, state)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3441 errorlog.warning('reduce/reduce conflict in state %d resolved using rule (%s)', state, rule)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3442 errorlog.warning('rejected rule (%s) in state %d', rejected, state)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3443 already_reported.add((state, id(rule), id(rejected)))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3444
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3445 warned_never = []
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3446 for state, rule, rejected in lr.rr_conflicts:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3447 if not rejected.reduced and (rejected not in warned_never):
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3448 debuglog.warning('Rule (%s) is never reduced', rejected)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3449 errorlog.warning('Rule (%s) is never reduced', rejected)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3450 warned_never.append(rejected)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3451
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3452 # Write the table file if requested
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3453 if write_tables:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3454 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3455 lr.write_table(tabmodule, outputdir, signature)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3456 except IOError as e:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3457 errorlog.warning("Couldn't create %r. %s" % (tabmodule, e))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3458
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3459 # Write a pickled version of the tables
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3460 if picklefile:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3461 try:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3462 lr.pickle_table(picklefile, signature)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3463 except IOError as e:
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3464 errorlog.warning("Couldn't create %r. %s" % (picklefile, e))
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3465
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3466 # Build the parser
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3467 lr.bind_callables(pinfo.pdict)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3468 parser = LRParser(lr, pinfo.error_func)
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3469
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3470 parse = parser.parse
343ff337a19b <ais523> ` tar -xf ply-3.8.tar.gz
HackBot
parents:
diff changeset
3471 return parser