annotate ply-3.8/build/lib.linux-x86_64-2.7/ply/yacc.py @ 12285:69f123e9b0a2 draft

<b_jonas> STOP
author HackEso <hackeso@esolangs.org>
date Wed, 01 Jan 2020 09:35:37 +0000
parents a1845676eaa0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7268
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2 # ply: yacc.py
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
4 # Copyright (C) 2001-2015,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
5 # David M. Beazley (Dabeaz LLC)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
6 # All rights reserved.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
7 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
8 # Redistribution and use in source and binary forms, with or without
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
9 # modification, are permitted provided that the following conditions are
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
10 # met:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
11 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
12 # * Redistributions of source code must retain the above copyright notice,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
13 # this list of conditions and the following disclaimer.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
14 # * Redistributions in binary form must reproduce the above copyright notice,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
15 # this list of conditions and the following disclaimer in the documentation
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
16 # and/or other materials provided with the distribution.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
17 # * Neither the name of the David Beazley or Dabeaz LLC may be used to
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
18 # endorse or promote products derived from this software without
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
19 # specific prior written permission.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
20 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
22 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
23 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
24 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
25 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
26 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
27 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
28 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
29 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
30 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
31 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
32 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
33 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
34 # This implements an LR parser that is constructed from grammar rules defined
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
35 # as Python functions. The grammer is specified by supplying the BNF inside
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
36 # Python documentation strings. The inspiration for this technique was borrowed
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
37 # from John Aycock's Spark parsing system. PLY might be viewed as cross between
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
38 # Spark and the GNU bison utility.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
39 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
40 # The current implementation is only somewhat object-oriented. The
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
41 # LR parser itself is defined in terms of an object (which allows multiple
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
42 # parsers to co-exist). However, most of the variables used during table
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
43 # construction are defined in terms of global variables. Users shouldn't
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
44 # notice unless they are trying to define multiple parsers at the same
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
45 # time using threads (in which case they should have their head examined).
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
46 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
47 # This implementation supports both SLR and LALR(1) parsing. LALR(1)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
48 # support was originally implemented by Elias Ioup (ezioup@alumni.uchicago.edu),
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
49 # using the algorithm found in Aho, Sethi, and Ullman "Compilers: Principles,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
50 # Techniques, and Tools" (The Dragon Book). LALR(1) has since been replaced
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
51 # by the more efficient DeRemer and Pennello algorithm.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
52 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
53 # :::::::: WARNING :::::::
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
54 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
55 # Construction of LR parsing tables is fairly complicated and expensive.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
56 # To make this module run fast, a *LOT* of work has been put into
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
57 # optimization---often at the expensive of readability and what might
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
58 # consider to be good Python "coding style." Modify the code at your
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
59 # own risk!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
60 # ----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
61
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
62 import re
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
63 import types
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
64 import sys
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
65 import os.path
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
66 import inspect
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
67 import base64
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
68 import warnings
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
69
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
70 __version__ = '3.8'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
71 __tabversion__ = '3.8'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
72
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
73 #-----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
74 # === User configurable parameters ===
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
75 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
76 # Change these to modify the default behavior of yacc (if you wish)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
77 #-----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
78
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
79 yaccdebug = True # Debugging mode. If set, yacc generates a
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
80 # a 'parser.out' file in the current directory
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
81
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
82 debug_file = 'parser.out' # Default name of the debugging file
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
83 tab_module = 'parsetab' # Default name of the table module
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
84 default_lr = 'LALR' # Default LR table generation method
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
85
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
86 error_count = 3 # Number of symbols that must be shifted to leave recovery mode
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
87
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
88 yaccdevel = False # Set to True if developing yacc. This turns off optimized
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
89 # implementations of certain functions.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
90
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
91 resultlimit = 40 # Size limit of results when running in debug mode.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
92
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
93 pickle_protocol = 0 # Protocol to use when writing pickle files
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
94
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
95 # String type-checking compatibility
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
96 if sys.version_info[0] < 3:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
97 string_types = basestring
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
98 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
99 string_types = str
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
100
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
101 MAXINT = sys.maxsize
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
102
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
103 # This object is a stand-in for a logging object created by the
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
104 # logging module. PLY will use this by default to create things
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
105 # such as the parser.out file. If a user wants more detailed
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
106 # information, they can create their own logging object and pass
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
107 # it into PLY.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
108
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
109 class PlyLogger(object):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
110 def __init__(self, f):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
111 self.f = f
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
112
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
113 def debug(self, msg, *args, **kwargs):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
114 self.f.write((msg % args) + '\n')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
115
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
116 info = debug
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
117
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
118 def warning(self, msg, *args, **kwargs):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
119 self.f.write('WARNING: ' + (msg % args) + '\n')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
120
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
121 def error(self, msg, *args, **kwargs):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
122 self.f.write('ERROR: ' + (msg % args) + '\n')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
123
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
124 critical = debug
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
125
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
126 # Null logger is used when no output is generated. Does nothing.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
127 class NullLogger(object):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
128 def __getattribute__(self, name):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
129 return self
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
130
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
131 def __call__(self, *args, **kwargs):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
132 return self
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
133
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
134 # Exception raised for yacc-related errors
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
135 class YaccError(Exception):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
136 pass
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
137
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
138 # Format the result message that the parser produces when running in debug mode.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
139 def format_result(r):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
140 repr_str = repr(r)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
141 if '\n' in repr_str:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
142 repr_str = repr(repr_str)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
143 if len(repr_str) > resultlimit:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
144 repr_str = repr_str[:resultlimit] + ' ...'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
145 result = '<%s @ 0x%x> (%s)' % (type(r).__name__, id(r), repr_str)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
146 return result
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
147
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
148 # Format stack entries when the parser is running in debug mode
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
149 def format_stack_entry(r):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
150 repr_str = repr(r)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
151 if '\n' in repr_str:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
152 repr_str = repr(repr_str)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
153 if len(repr_str) < 16:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
154 return repr_str
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
155 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
156 return '<%s @ 0x%x>' % (type(r).__name__, id(r))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
157
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
158 # Panic mode error recovery support. This feature is being reworked--much of the
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
159 # code here is to offer a deprecation/backwards compatible transition
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
160
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
161 _errok = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
162 _token = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
163 _restart = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
164 _warnmsg = '''PLY: Don't use global functions errok(), token(), and restart() in p_error().
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
165 Instead, invoke the methods on the associated parser instance:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
166
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
167 def p_error(p):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
168 ...
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
169 # Use parser.errok(), parser.token(), parser.restart()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
170 ...
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
171
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
172 parser = yacc.yacc()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
173 '''
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
174
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
175 def errok():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
176 warnings.warn(_warnmsg)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
177 return _errok()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
178
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
179 def restart():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
180 warnings.warn(_warnmsg)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
181 return _restart()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
182
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
183 def token():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
184 warnings.warn(_warnmsg)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
185 return _token()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
186
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
187 # Utility function to call the p_error() function with some deprecation hacks
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
188 def call_errorfunc(errorfunc, token, parser):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
189 global _errok, _token, _restart
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
190 _errok = parser.errok
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
191 _token = parser.token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
192 _restart = parser.restart
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
193 r = errorfunc(token)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
194 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
195 del _errok, _token, _restart
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
196 except NameError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
197 pass
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
198 return r
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
199
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
200 #-----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
201 # === LR Parsing Engine ===
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
202 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
203 # The following classes are used for the LR parser itself. These are not
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
204 # used during table construction and are independent of the actual LR
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
205 # table generation algorithm
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
206 #-----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
207
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
208 # This class is used to hold non-terminal grammar symbols during parsing.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
209 # It normally has the following attributes set:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
210 # .type = Grammar symbol type
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
211 # .value = Symbol value
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
212 # .lineno = Starting line number
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
213 # .endlineno = Ending line number (optional, set automatically)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
214 # .lexpos = Starting lex position
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
215 # .endlexpos = Ending lex position (optional, set automatically)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
216
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
217 class YaccSymbol:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
218 def __str__(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
219 return self.type
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
220
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
221 def __repr__(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
222 return str(self)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
223
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
224 # This class is a wrapper around the objects actually passed to each
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
225 # grammar rule. Index lookup and assignment actually assign the
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
226 # .value attribute of the underlying YaccSymbol object.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
227 # The lineno() method returns the line number of a given
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
228 # item (or 0 if not defined). The linespan() method returns
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
229 # a tuple of (startline,endline) representing the range of lines
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
230 # for a symbol. The lexspan() method returns a tuple (lexpos,endlexpos)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
231 # representing the range of positional information for a symbol.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
232
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
233 class YaccProduction:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
234 def __init__(self, s, stack=None):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
235 self.slice = s
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
236 self.stack = stack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
237 self.lexer = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
238 self.parser = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
239
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
240 def __getitem__(self, n):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
241 if isinstance(n, slice):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
242 return [s.value for s in self.slice[n]]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
243 elif n >= 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
244 return self.slice[n].value
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
245 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
246 return self.stack[n].value
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
247
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
248 def __setitem__(self, n, v):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
249 self.slice[n].value = v
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
250
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
251 def __getslice__(self, i, j):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
252 return [s.value for s in self.slice[i:j]]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
253
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
254 def __len__(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
255 return len(self.slice)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
256
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
257 def lineno(self, n):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
258 return getattr(self.slice[n], 'lineno', 0)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
259
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
260 def set_lineno(self, n, lineno):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
261 self.slice[n].lineno = lineno
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
262
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
263 def linespan(self, n):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
264 startline = getattr(self.slice[n], 'lineno', 0)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
265 endline = getattr(self.slice[n], 'endlineno', startline)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
266 return startline, endline
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
267
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
268 def lexpos(self, n):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
269 return getattr(self.slice[n], 'lexpos', 0)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
270
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
271 def lexspan(self, n):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
272 startpos = getattr(self.slice[n], 'lexpos', 0)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
273 endpos = getattr(self.slice[n], 'endlexpos', startpos)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
274 return startpos, endpos
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
275
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
276 def error(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
277 raise SyntaxError
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
278
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
279 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
280 # == LRParser ==
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
281 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
282 # The LR Parsing engine.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
283 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
284
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
285 class LRParser:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
286 def __init__(self, lrtab, errorf):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
287 self.productions = lrtab.lr_productions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
288 self.action = lrtab.lr_action
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
289 self.goto = lrtab.lr_goto
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
290 self.errorfunc = errorf
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
291 self.set_defaulted_states()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
292 self.errorok = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
293
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
294 def errok(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
295 self.errorok = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
296
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
297 def restart(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
298 del self.statestack[:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
299 del self.symstack[:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
300 sym = YaccSymbol()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
301 sym.type = '$end'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
302 self.symstack.append(sym)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
303 self.statestack.append(0)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
304
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
305 # Defaulted state support.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
306 # This method identifies parser states where there is only one possible reduction action.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
307 # For such states, the parser can make a choose to make a rule reduction without consuming
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
308 # the next look-ahead token. This delayed invocation of the tokenizer can be useful in
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
309 # certain kinds of advanced parsing situations where the lexer and parser interact with
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
310 # each other or change states (i.e., manipulation of scope, lexer states, etc.).
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
311 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
312 # See: http://www.gnu.org/software/bison/manual/html_node/Default-Reductions.html#Default-Reductions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
313 def set_defaulted_states(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
314 self.defaulted_states = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
315 for state, actions in self.action.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
316 rules = list(actions.values())
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
317 if len(rules) == 1 and rules[0] < 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
318 self.defaulted_states[state] = rules[0]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
319
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
320 def disable_defaulted_states(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
321 self.defaulted_states = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
322
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
323 def parse(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
324 if debug or yaccdevel:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
325 if isinstance(debug, int):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
326 debug = PlyLogger(sys.stderr)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
327 return self.parsedebug(input, lexer, debug, tracking, tokenfunc)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
328 elif tracking:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
329 return self.parseopt(input, lexer, debug, tracking, tokenfunc)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
330 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
331 return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
332
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
333
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
334 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
335 # parsedebug().
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
336 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
337 # This is the debugging enabled version of parse(). All changes made to the
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
338 # parsing engine should be made here. Optimized versions of this function
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
339 # are automatically created by the ply/ygen.py script. This script cuts out
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
340 # sections enclosed in markers such as this:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
341 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
342 # #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
343 # statements
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
344 # #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
345 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
346 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
347
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
348 def parsedebug(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
349 #--! parsedebug-start
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
350 lookahead = None # Current lookahead symbol
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
351 lookaheadstack = [] # Stack of lookahead symbols
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
352 actions = self.action # Local reference to action table (to avoid lookup on self.)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
353 goto = self.goto # Local reference to goto table (to avoid lookup on self.)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
354 prod = self.productions # Local reference to production list (to avoid lookup on self.)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
355 defaulted_states = self.defaulted_states # Local reference to defaulted states
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
356 pslice = YaccProduction(None) # Production object passed to grammar rules
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
357 errorcount = 0 # Used during error recovery
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
358
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
359 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
360 debug.info('PLY: PARSE DEBUG START')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
361 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
362
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
363 # If no lexer was given, we will try to use the lex module
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
364 if not lexer:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
365 from . import lex
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
366 lexer = lex.lexer
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
367
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
368 # Set up the lexer and parser objects on pslice
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
369 pslice.lexer = lexer
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
370 pslice.parser = self
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
371
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
372 # If input was supplied, pass to lexer
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
373 if input is not None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
374 lexer.input(input)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
375
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
376 if tokenfunc is None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
377 # Tokenize function
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
378 get_token = lexer.token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
379 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
380 get_token = tokenfunc
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
381
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
382 # Set the parser() token method (sometimes used in error recovery)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
383 self.token = get_token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
384
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
385 # Set up the state and symbol stacks
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
386
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
387 statestack = [] # Stack of parsing states
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
388 self.statestack = statestack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
389 symstack = [] # Stack of grammar symbols
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
390 self.symstack = symstack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
391
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
392 pslice.stack = symstack # Put in the production
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
393 errtoken = None # Err token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
394
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
395 # The start state is assumed to be (0,$end)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
396
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
397 statestack.append(0)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
398 sym = YaccSymbol()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
399 sym.type = '$end'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
400 symstack.append(sym)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
401 state = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
402 while True:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
403 # Get the next symbol on the input. If a lookahead symbol
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
404 # is already set, we just use that. Otherwise, we'll pull
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
405 # the next token off of the lookaheadstack or from the lexer
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
406
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
407 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
408 debug.debug('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
409 debug.debug('State : %s', state)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
410 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
411
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
412 if state not in defaulted_states:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
413 if not lookahead:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
414 if not lookaheadstack:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
415 lookahead = get_token() # Get the next token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
416 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
417 lookahead = lookaheadstack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
418 if not lookahead:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
419 lookahead = YaccSymbol()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
420 lookahead.type = '$end'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
421
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
422 # Check the action table
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
423 ltype = lookahead.type
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
424 t = actions[state].get(ltype)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
425 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
426 t = defaulted_states[state]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
427 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
428 debug.debug('Defaulted state %s: Reduce using %d', state, -t)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
429 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
430
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
431 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
432 debug.debug('Stack : %s',
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
433 ('%s . %s' % (' '.join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip())
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
434 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
435
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
436 if t is not None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
437 if t > 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
438 # shift a symbol on the stack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
439 statestack.append(t)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
440 state = t
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
441
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
442 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
443 debug.debug('Action : Shift and goto state %s', t)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
444 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
445
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
446 symstack.append(lookahead)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
447 lookahead = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
448
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
449 # Decrease error count on successful shift
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
450 if errorcount:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
451 errorcount -= 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
452 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
453
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
454 if t < 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
455 # reduce a symbol on the stack, emit a production
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
456 p = prod[-t]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
457 pname = p.name
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
458 plen = p.len
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
459
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
460 # Get production function
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
461 sym = YaccSymbol()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
462 sym.type = pname # Production name
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
463 sym.value = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
464
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
465 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
466 if plen:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
467 debug.info('Action : Reduce rule [%s] with %s and goto state %d', p.str,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
468 '['+','.join([format_stack_entry(_v.value) for _v in symstack[-plen:]])+']',
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
469 goto[statestack[-1-plen]][pname])
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
470 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
471 debug.info('Action : Reduce rule [%s] with %s and goto state %d', p.str, [],
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
472 goto[statestack[-1]][pname])
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
473
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
474 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
475
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
476 if plen:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
477 targ = symstack[-plen-1:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
478 targ[0] = sym
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
479
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
480 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
481 if tracking:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
482 t1 = targ[1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
483 sym.lineno = t1.lineno
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
484 sym.lexpos = t1.lexpos
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
485 t1 = targ[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
486 sym.endlineno = getattr(t1, 'endlineno', t1.lineno)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
487 sym.endlexpos = getattr(t1, 'endlexpos', t1.lexpos)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
488 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
489
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
490 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
491 # The code enclosed in this section is duplicated
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
492 # below as a performance optimization. Make sure
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
493 # changes get made in both locations.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
494
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
495 pslice.slice = targ
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
496
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
497 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
498 # Call the grammar rule with our special slice object
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
499 del symstack[-plen:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
500 del statestack[-plen:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
501 p.callable(pslice)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
502 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
503 debug.info('Result : %s', format_result(pslice[0]))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
504 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
505 symstack.append(sym)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
506 state = goto[statestack[-1]][pname]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
507 statestack.append(state)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
508 except SyntaxError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
509 # If an error was set. Enter error recovery state
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
510 lookaheadstack.append(lookahead)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
511 symstack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
512 statestack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
513 state = statestack[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
514 sym.type = 'error'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
515 lookahead = sym
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
516 errorcount = error_count
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
517 self.errorok = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
518 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
519 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
520
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
521 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
522
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
523 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
524 if tracking:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
525 sym.lineno = lexer.lineno
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
526 sym.lexpos = lexer.lexpos
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
527 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
528
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
529 targ = [sym]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
530
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
531 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
532 # The code enclosed in this section is duplicated
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
533 # above as a performance optimization. Make sure
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
534 # changes get made in both locations.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
535
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
536 pslice.slice = targ
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
537
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
538 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
539 # Call the grammar rule with our special slice object
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
540 p.callable(pslice)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
541 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
542 debug.info('Result : %s', format_result(pslice[0]))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
543 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
544 symstack.append(sym)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
545 state = goto[statestack[-1]][pname]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
546 statestack.append(state)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
547 except SyntaxError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
548 # If an error was set. Enter error recovery state
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
549 lookaheadstack.append(lookahead)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
550 symstack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
551 statestack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
552 state = statestack[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
553 sym.type = 'error'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
554 lookahead = sym
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
555 errorcount = error_count
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
556 self.errorok = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
557 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
558 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
559
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
560 if t == 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
561 n = symstack[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
562 result = getattr(n, 'value', None)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
563 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
564 debug.info('Done : Returning %s', format_result(result))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
565 debug.info('PLY: PARSE DEBUG END')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
566 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
567 return result
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
568
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
569 if t is None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
570
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
571 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
572 debug.error('Error : %s',
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
573 ('%s . %s' % (' '.join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip())
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
574 #--! DEBUG
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
575
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
576 # We have some kind of parsing error here. To handle
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
577 # this, we are going to push the current token onto
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
578 # the tokenstack and replace it with an 'error' token.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
579 # If there are any synchronization rules, they may
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
580 # catch it.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
581 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
582 # In addition to pushing the error token, we call call
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
583 # the user defined p_error() function if this is the
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
584 # first syntax error. This function is only called if
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
585 # errorcount == 0.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
586 if errorcount == 0 or self.errorok:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
587 errorcount = error_count
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
588 self.errorok = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
589 errtoken = lookahead
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
590 if errtoken.type == '$end':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
591 errtoken = None # End of file!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
592 if self.errorfunc:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
593 if errtoken and not hasattr(errtoken, 'lexer'):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
594 errtoken.lexer = lexer
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
595 tok = call_errorfunc(self.errorfunc, errtoken, self)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
596 if self.errorok:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
597 # User must have done some kind of panic
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
598 # mode recovery on their own. The
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
599 # returned token is the next lookahead
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
600 lookahead = tok
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
601 errtoken = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
602 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
603 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
604 if errtoken:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
605 if hasattr(errtoken, 'lineno'):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
606 lineno = lookahead.lineno
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
607 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
608 lineno = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
609 if lineno:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
610 sys.stderr.write('yacc: Syntax error at line %d, token=%s\n' % (lineno, errtoken.type))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
611 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
612 sys.stderr.write('yacc: Syntax error, token=%s' % errtoken.type)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
613 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
614 sys.stderr.write('yacc: Parse error in input. EOF\n')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
615 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
616
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
617 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
618 errorcount = error_count
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
619
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
620 # case 1: the statestack only has 1 entry on it. If we're in this state, the
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
621 # entire parse has been rolled back and we're completely hosed. The token is
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
622 # discarded and we just keep going.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
623
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
624 if len(statestack) <= 1 and lookahead.type != '$end':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
625 lookahead = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
626 errtoken = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
627 state = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
628 # Nuke the pushback stack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
629 del lookaheadstack[:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
630 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
631
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
632 # case 2: the statestack has a couple of entries on it, but we're
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
633 # at the end of the file. nuke the top entry and generate an error token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
634
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
635 # Start nuking entries on the stack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
636 if lookahead.type == '$end':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
637 # Whoa. We're really hosed here. Bail out
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
638 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
639
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
640 if lookahead.type != 'error':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
641 sym = symstack[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
642 if sym.type == 'error':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
643 # Hmmm. Error is on top of stack, we'll just nuke input
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
644 # symbol and continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
645 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
646 if tracking:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
647 sym.endlineno = getattr(lookahead, 'lineno', sym.lineno)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
648 sym.endlexpos = getattr(lookahead, 'lexpos', sym.lexpos)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
649 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
650 lookahead = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
651 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
652
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
653 # Create the error symbol for the first time and make it the new lookahead symbol
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
654 t = YaccSymbol()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
655 t.type = 'error'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
656
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
657 if hasattr(lookahead, 'lineno'):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
658 t.lineno = t.endlineno = lookahead.lineno
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
659 if hasattr(lookahead, 'lexpos'):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
660 t.lexpos = t.endlexpos = lookahead.lexpos
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
661 t.value = lookahead
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
662 lookaheadstack.append(lookahead)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
663 lookahead = t
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
664 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
665 sym = symstack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
666 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
667 if tracking:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
668 lookahead.lineno = sym.lineno
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
669 lookahead.lexpos = sym.lexpos
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
670 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
671 statestack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
672 state = statestack[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
673
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
674 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
675
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
676 # Call an error function here
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
677 raise RuntimeError('yacc: internal parser error!!!\n')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
678
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
679 #--! parsedebug-end
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
680
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
681 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
682 # parseopt().
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
683 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
684 # Optimized version of parse() method. DO NOT EDIT THIS CODE DIRECTLY!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
685 # This code is automatically generated by the ply/ygen.py script. Make
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
686 # changes to the parsedebug() method instead.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
687 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
688
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
689 def parseopt(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
690 #--! parseopt-start
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
691 lookahead = None # Current lookahead symbol
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
692 lookaheadstack = [] # Stack of lookahead symbols
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
693 actions = self.action # Local reference to action table (to avoid lookup on self.)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
694 goto = self.goto # Local reference to goto table (to avoid lookup on self.)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
695 prod = self.productions # Local reference to production list (to avoid lookup on self.)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
696 defaulted_states = self.defaulted_states # Local reference to defaulted states
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
697 pslice = YaccProduction(None) # Production object passed to grammar rules
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
698 errorcount = 0 # Used during error recovery
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
699
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
700
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
701 # If no lexer was given, we will try to use the lex module
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
702 if not lexer:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
703 from . import lex
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
704 lexer = lex.lexer
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
705
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
706 # Set up the lexer and parser objects on pslice
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
707 pslice.lexer = lexer
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
708 pslice.parser = self
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
709
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
710 # If input was supplied, pass to lexer
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
711 if input is not None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
712 lexer.input(input)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
713
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
714 if tokenfunc is None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
715 # Tokenize function
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
716 get_token = lexer.token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
717 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
718 get_token = tokenfunc
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
719
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
720 # Set the parser() token method (sometimes used in error recovery)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
721 self.token = get_token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
722
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
723 # Set up the state and symbol stacks
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
724
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
725 statestack = [] # Stack of parsing states
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
726 self.statestack = statestack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
727 symstack = [] # Stack of grammar symbols
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
728 self.symstack = symstack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
729
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
730 pslice.stack = symstack # Put in the production
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
731 errtoken = None # Err token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
732
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
733 # The start state is assumed to be (0,$end)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
734
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
735 statestack.append(0)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
736 sym = YaccSymbol()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
737 sym.type = '$end'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
738 symstack.append(sym)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
739 state = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
740 while True:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
741 # Get the next symbol on the input. If a lookahead symbol
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
742 # is already set, we just use that. Otherwise, we'll pull
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
743 # the next token off of the lookaheadstack or from the lexer
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
744
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
745
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
746 if state not in defaulted_states:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
747 if not lookahead:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
748 if not lookaheadstack:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
749 lookahead = get_token() # Get the next token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
750 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
751 lookahead = lookaheadstack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
752 if not lookahead:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
753 lookahead = YaccSymbol()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
754 lookahead.type = '$end'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
755
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
756 # Check the action table
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
757 ltype = lookahead.type
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
758 t = actions[state].get(ltype)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
759 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
760 t = defaulted_states[state]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
761
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
762
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
763 if t is not None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
764 if t > 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
765 # shift a symbol on the stack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
766 statestack.append(t)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
767 state = t
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
768
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
769
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
770 symstack.append(lookahead)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
771 lookahead = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
772
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
773 # Decrease error count on successful shift
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
774 if errorcount:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
775 errorcount -= 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
776 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
777
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
778 if t < 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
779 # reduce a symbol on the stack, emit a production
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
780 p = prod[-t]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
781 pname = p.name
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
782 plen = p.len
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
783
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
784 # Get production function
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
785 sym = YaccSymbol()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
786 sym.type = pname # Production name
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
787 sym.value = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
788
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
789
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
790 if plen:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
791 targ = symstack[-plen-1:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
792 targ[0] = sym
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
793
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
794 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
795 if tracking:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
796 t1 = targ[1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
797 sym.lineno = t1.lineno
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
798 sym.lexpos = t1.lexpos
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
799 t1 = targ[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
800 sym.endlineno = getattr(t1, 'endlineno', t1.lineno)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
801 sym.endlexpos = getattr(t1, 'endlexpos', t1.lexpos)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
802 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
803
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
804 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
805 # The code enclosed in this section is duplicated
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
806 # below as a performance optimization. Make sure
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
807 # changes get made in both locations.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
808
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
809 pslice.slice = targ
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
810
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
811 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
812 # Call the grammar rule with our special slice object
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
813 del symstack[-plen:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
814 del statestack[-plen:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
815 p.callable(pslice)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
816 symstack.append(sym)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
817 state = goto[statestack[-1]][pname]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
818 statestack.append(state)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
819 except SyntaxError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
820 # If an error was set. Enter error recovery state
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
821 lookaheadstack.append(lookahead)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
822 symstack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
823 statestack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
824 state = statestack[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
825 sym.type = 'error'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
826 lookahead = sym
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
827 errorcount = error_count
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
828 self.errorok = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
829 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
830 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
831
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
832 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
833
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
834 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
835 if tracking:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
836 sym.lineno = lexer.lineno
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
837 sym.lexpos = lexer.lexpos
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
838 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
839
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
840 targ = [sym]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
841
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
842 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
843 # The code enclosed in this section is duplicated
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
844 # above as a performance optimization. Make sure
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
845 # changes get made in both locations.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
846
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
847 pslice.slice = targ
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
848
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
849 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
850 # Call the grammar rule with our special slice object
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
851 p.callable(pslice)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
852 symstack.append(sym)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
853 state = goto[statestack[-1]][pname]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
854 statestack.append(state)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
855 except SyntaxError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
856 # If an error was set. Enter error recovery state
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
857 lookaheadstack.append(lookahead)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
858 symstack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
859 statestack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
860 state = statestack[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
861 sym.type = 'error'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
862 lookahead = sym
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
863 errorcount = error_count
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
864 self.errorok = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
865 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
866 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
867
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
868 if t == 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
869 n = symstack[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
870 result = getattr(n, 'value', None)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
871 return result
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
872
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
873 if t is None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
874
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
875
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
876 # We have some kind of parsing error here. To handle
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
877 # this, we are going to push the current token onto
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
878 # the tokenstack and replace it with an 'error' token.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
879 # If there are any synchronization rules, they may
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
880 # catch it.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
881 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
882 # In addition to pushing the error token, we call call
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
883 # the user defined p_error() function if this is the
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
884 # first syntax error. This function is only called if
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
885 # errorcount == 0.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
886 if errorcount == 0 or self.errorok:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
887 errorcount = error_count
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
888 self.errorok = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
889 errtoken = lookahead
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
890 if errtoken.type == '$end':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
891 errtoken = None # End of file!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
892 if self.errorfunc:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
893 if errtoken and not hasattr(errtoken, 'lexer'):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
894 errtoken.lexer = lexer
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
895 tok = call_errorfunc(self.errorfunc, errtoken, self)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
896 if self.errorok:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
897 # User must have done some kind of panic
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
898 # mode recovery on their own. The
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
899 # returned token is the next lookahead
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
900 lookahead = tok
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
901 errtoken = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
902 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
903 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
904 if errtoken:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
905 if hasattr(errtoken, 'lineno'):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
906 lineno = lookahead.lineno
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
907 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
908 lineno = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
909 if lineno:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
910 sys.stderr.write('yacc: Syntax error at line %d, token=%s\n' % (lineno, errtoken.type))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
911 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
912 sys.stderr.write('yacc: Syntax error, token=%s' % errtoken.type)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
913 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
914 sys.stderr.write('yacc: Parse error in input. EOF\n')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
915 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
916
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
917 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
918 errorcount = error_count
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
919
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
920 # case 1: the statestack only has 1 entry on it. If we're in this state, the
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
921 # entire parse has been rolled back and we're completely hosed. The token is
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
922 # discarded and we just keep going.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
923
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
924 if len(statestack) <= 1 and lookahead.type != '$end':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
925 lookahead = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
926 errtoken = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
927 state = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
928 # Nuke the pushback stack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
929 del lookaheadstack[:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
930 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
931
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
932 # case 2: the statestack has a couple of entries on it, but we're
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
933 # at the end of the file. nuke the top entry and generate an error token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
934
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
935 # Start nuking entries on the stack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
936 if lookahead.type == '$end':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
937 # Whoa. We're really hosed here. Bail out
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
938 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
939
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
940 if lookahead.type != 'error':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
941 sym = symstack[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
942 if sym.type == 'error':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
943 # Hmmm. Error is on top of stack, we'll just nuke input
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
944 # symbol and continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
945 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
946 if tracking:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
947 sym.endlineno = getattr(lookahead, 'lineno', sym.lineno)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
948 sym.endlexpos = getattr(lookahead, 'lexpos', sym.lexpos)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
949 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
950 lookahead = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
951 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
952
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
953 # Create the error symbol for the first time and make it the new lookahead symbol
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
954 t = YaccSymbol()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
955 t.type = 'error'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
956
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
957 if hasattr(lookahead, 'lineno'):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
958 t.lineno = t.endlineno = lookahead.lineno
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
959 if hasattr(lookahead, 'lexpos'):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
960 t.lexpos = t.endlexpos = lookahead.lexpos
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
961 t.value = lookahead
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
962 lookaheadstack.append(lookahead)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
963 lookahead = t
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
964 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
965 sym = symstack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
966 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
967 if tracking:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
968 lookahead.lineno = sym.lineno
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
969 lookahead.lexpos = sym.lexpos
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
970 #--! TRACKING
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
971 statestack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
972 state = statestack[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
973
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
974 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
975
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
976 # Call an error function here
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
977 raise RuntimeError('yacc: internal parser error!!!\n')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
978
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
979 #--! parseopt-end
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
980
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
981 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
982 # parseopt_notrack().
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
983 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
984 # Optimized version of parseopt() with line number tracking removed.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
985 # DO NOT EDIT THIS CODE DIRECTLY. This code is automatically generated
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
986 # by the ply/ygen.py script. Make changes to the parsedebug() method instead.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
987 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
988
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
989 def parseopt_notrack(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
990 #--! parseopt-notrack-start
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
991 lookahead = None # Current lookahead symbol
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
992 lookaheadstack = [] # Stack of lookahead symbols
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
993 actions = self.action # Local reference to action table (to avoid lookup on self.)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
994 goto = self.goto # Local reference to goto table (to avoid lookup on self.)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
995 prod = self.productions # Local reference to production list (to avoid lookup on self.)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
996 defaulted_states = self.defaulted_states # Local reference to defaulted states
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
997 pslice = YaccProduction(None) # Production object passed to grammar rules
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
998 errorcount = 0 # Used during error recovery
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
999
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1000
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1001 # If no lexer was given, we will try to use the lex module
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1002 if not lexer:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1003 from . import lex
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1004 lexer = lex.lexer
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1005
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1006 # Set up the lexer and parser objects on pslice
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1007 pslice.lexer = lexer
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1008 pslice.parser = self
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1009
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1010 # If input was supplied, pass to lexer
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1011 if input is not None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1012 lexer.input(input)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1013
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1014 if tokenfunc is None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1015 # Tokenize function
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1016 get_token = lexer.token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1017 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1018 get_token = tokenfunc
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1019
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1020 # Set the parser() token method (sometimes used in error recovery)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1021 self.token = get_token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1022
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1023 # Set up the state and symbol stacks
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1024
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1025 statestack = [] # Stack of parsing states
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1026 self.statestack = statestack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1027 symstack = [] # Stack of grammar symbols
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1028 self.symstack = symstack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1029
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1030 pslice.stack = symstack # Put in the production
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1031 errtoken = None # Err token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1032
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1033 # The start state is assumed to be (0,$end)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1034
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1035 statestack.append(0)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1036 sym = YaccSymbol()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1037 sym.type = '$end'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1038 symstack.append(sym)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1039 state = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1040 while True:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1041 # Get the next symbol on the input. If a lookahead symbol
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1042 # is already set, we just use that. Otherwise, we'll pull
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1043 # the next token off of the lookaheadstack or from the lexer
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1044
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1045
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1046 if state not in defaulted_states:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1047 if not lookahead:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1048 if not lookaheadstack:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1049 lookahead = get_token() # Get the next token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1050 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1051 lookahead = lookaheadstack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1052 if not lookahead:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1053 lookahead = YaccSymbol()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1054 lookahead.type = '$end'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1055
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1056 # Check the action table
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1057 ltype = lookahead.type
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1058 t = actions[state].get(ltype)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1059 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1060 t = defaulted_states[state]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1061
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1062
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1063 if t is not None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1064 if t > 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1065 # shift a symbol on the stack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1066 statestack.append(t)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1067 state = t
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1068
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1069
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1070 symstack.append(lookahead)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1071 lookahead = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1072
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1073 # Decrease error count on successful shift
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1074 if errorcount:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1075 errorcount -= 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1076 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1077
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1078 if t < 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1079 # reduce a symbol on the stack, emit a production
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1080 p = prod[-t]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1081 pname = p.name
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1082 plen = p.len
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1083
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1084 # Get production function
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1085 sym = YaccSymbol()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1086 sym.type = pname # Production name
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1087 sym.value = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1088
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1089
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1090 if plen:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1091 targ = symstack[-plen-1:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1092 targ[0] = sym
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1093
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1094
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1095 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1096 # The code enclosed in this section is duplicated
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1097 # below as a performance optimization. Make sure
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1098 # changes get made in both locations.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1099
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1100 pslice.slice = targ
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1101
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1102 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1103 # Call the grammar rule with our special slice object
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1104 del symstack[-plen:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1105 del statestack[-plen:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1106 p.callable(pslice)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1107 symstack.append(sym)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1108 state = goto[statestack[-1]][pname]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1109 statestack.append(state)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1110 except SyntaxError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1111 # If an error was set. Enter error recovery state
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1112 lookaheadstack.append(lookahead)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1113 symstack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1114 statestack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1115 state = statestack[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1116 sym.type = 'error'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1117 lookahead = sym
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1118 errorcount = error_count
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1119 self.errorok = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1120 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1121 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1122
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1123 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1124
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1125
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1126 targ = [sym]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1127
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1128 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1129 # The code enclosed in this section is duplicated
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1130 # above as a performance optimization. Make sure
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1131 # changes get made in both locations.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1132
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1133 pslice.slice = targ
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1134
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1135 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1136 # Call the grammar rule with our special slice object
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1137 p.callable(pslice)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1138 symstack.append(sym)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1139 state = goto[statestack[-1]][pname]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1140 statestack.append(state)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1141 except SyntaxError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1142 # If an error was set. Enter error recovery state
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1143 lookaheadstack.append(lookahead)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1144 symstack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1145 statestack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1146 state = statestack[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1147 sym.type = 'error'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1148 lookahead = sym
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1149 errorcount = error_count
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1150 self.errorok = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1151 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1152 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1153
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1154 if t == 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1155 n = symstack[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1156 result = getattr(n, 'value', None)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1157 return result
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1158
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1159 if t is None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1160
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1161
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1162 # We have some kind of parsing error here. To handle
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1163 # this, we are going to push the current token onto
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1164 # the tokenstack and replace it with an 'error' token.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1165 # If there are any synchronization rules, they may
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1166 # catch it.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1167 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1168 # In addition to pushing the error token, we call call
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1169 # the user defined p_error() function if this is the
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1170 # first syntax error. This function is only called if
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1171 # errorcount == 0.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1172 if errorcount == 0 or self.errorok:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1173 errorcount = error_count
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1174 self.errorok = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1175 errtoken = lookahead
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1176 if errtoken.type == '$end':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1177 errtoken = None # End of file!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1178 if self.errorfunc:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1179 if errtoken and not hasattr(errtoken, 'lexer'):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1180 errtoken.lexer = lexer
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1181 tok = call_errorfunc(self.errorfunc, errtoken, self)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1182 if self.errorok:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1183 # User must have done some kind of panic
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1184 # mode recovery on their own. The
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1185 # returned token is the next lookahead
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1186 lookahead = tok
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1187 errtoken = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1188 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1189 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1190 if errtoken:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1191 if hasattr(errtoken, 'lineno'):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1192 lineno = lookahead.lineno
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1193 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1194 lineno = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1195 if lineno:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1196 sys.stderr.write('yacc: Syntax error at line %d, token=%s\n' % (lineno, errtoken.type))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1197 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1198 sys.stderr.write('yacc: Syntax error, token=%s' % errtoken.type)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1199 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1200 sys.stderr.write('yacc: Parse error in input. EOF\n')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1201 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1202
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1203 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1204 errorcount = error_count
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1205
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1206 # case 1: the statestack only has 1 entry on it. If we're in this state, the
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1207 # entire parse has been rolled back and we're completely hosed. The token is
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1208 # discarded and we just keep going.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1209
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1210 if len(statestack) <= 1 and lookahead.type != '$end':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1211 lookahead = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1212 errtoken = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1213 state = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1214 # Nuke the pushback stack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1215 del lookaheadstack[:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1216 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1217
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1218 # case 2: the statestack has a couple of entries on it, but we're
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1219 # at the end of the file. nuke the top entry and generate an error token
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1220
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1221 # Start nuking entries on the stack
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1222 if lookahead.type == '$end':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1223 # Whoa. We're really hosed here. Bail out
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1224 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1225
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1226 if lookahead.type != 'error':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1227 sym = symstack[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1228 if sym.type == 'error':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1229 # Hmmm. Error is on top of stack, we'll just nuke input
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1230 # symbol and continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1231 lookahead = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1232 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1233
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1234 # Create the error symbol for the first time and make it the new lookahead symbol
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1235 t = YaccSymbol()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1236 t.type = 'error'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1237
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1238 if hasattr(lookahead, 'lineno'):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1239 t.lineno = t.endlineno = lookahead.lineno
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1240 if hasattr(lookahead, 'lexpos'):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1241 t.lexpos = t.endlexpos = lookahead.lexpos
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1242 t.value = lookahead
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1243 lookaheadstack.append(lookahead)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1244 lookahead = t
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1245 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1246 sym = symstack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1247 statestack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1248 state = statestack[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1249
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1250 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1251
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1252 # Call an error function here
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1253 raise RuntimeError('yacc: internal parser error!!!\n')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1254
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1255 #--! parseopt-notrack-end
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1256
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1257 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1258 # === Grammar Representation ===
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1259 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1260 # The following functions, classes, and variables are used to represent and
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1261 # manipulate the rules that make up a grammar.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1262 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1263
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1264 # regex matching identifiers
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1265 _is_identifier = re.compile(r'^[a-zA-Z0-9_-]+$')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1266
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1267 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1268 # class Production:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1269 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1270 # This class stores the raw information about a single production or grammar rule.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1271 # A grammar rule refers to a specification such as this:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1272 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1273 # expr : expr PLUS term
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1274 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1275 # Here are the basic attributes defined on all productions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1276 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1277 # name - Name of the production. For example 'expr'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1278 # prod - A list of symbols on the right side ['expr','PLUS','term']
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1279 # prec - Production precedence level
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1280 # number - Production number.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1281 # func - Function that executes on reduce
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1282 # file - File where production function is defined
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1283 # lineno - Line number where production function is defined
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1284 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1285 # The following attributes are defined or optional.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1286 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1287 # len - Length of the production (number of symbols on right hand side)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1288 # usyms - Set of unique symbols found in the production
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1289 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1290
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1291 class Production(object):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1292 reduced = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1293 def __init__(self, number, name, prod, precedence=('right', 0), func=None, file='', line=0):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1294 self.name = name
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1295 self.prod = tuple(prod)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1296 self.number = number
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1297 self.func = func
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1298 self.callable = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1299 self.file = file
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1300 self.line = line
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1301 self.prec = precedence
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1302
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1303 # Internal settings used during table construction
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1304
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1305 self.len = len(self.prod) # Length of the production
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1306
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1307 # Create a list of unique production symbols used in the production
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1308 self.usyms = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1309 for s in self.prod:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1310 if s not in self.usyms:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1311 self.usyms.append(s)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1312
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1313 # List of all LR items for the production
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1314 self.lr_items = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1315 self.lr_next = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1316
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1317 # Create a string representation
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1318 if self.prod:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1319 self.str = '%s -> %s' % (self.name, ' '.join(self.prod))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1320 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1321 self.str = '%s -> <empty>' % self.name
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1322
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1323 def __str__(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1324 return self.str
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1325
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1326 def __repr__(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1327 return 'Production(' + str(self) + ')'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1328
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1329 def __len__(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1330 return len(self.prod)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1331
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1332 def __nonzero__(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1333 return 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1334
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1335 def __getitem__(self, index):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1336 return self.prod[index]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1337
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1338 # Return the nth lr_item from the production (or None if at the end)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1339 def lr_item(self, n):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1340 if n > len(self.prod):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1341 return None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1342 p = LRItem(self, n)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1343 # Precompute the list of productions immediately following.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1344 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1345 p.lr_after = Prodnames[p.prod[n+1]]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1346 except (IndexError, KeyError):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1347 p.lr_after = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1348 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1349 p.lr_before = p.prod[n-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1350 except IndexError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1351 p.lr_before = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1352 return p
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1353
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1354 # Bind the production function name to a callable
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1355 def bind(self, pdict):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1356 if self.func:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1357 self.callable = pdict[self.func]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1358
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1359 # This class serves as a minimal standin for Production objects when
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1360 # reading table data from files. It only contains information
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1361 # actually used by the LR parsing engine, plus some additional
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1362 # debugging information.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1363 class MiniProduction(object):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1364 def __init__(self, str, name, len, func, file, line):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1365 self.name = name
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1366 self.len = len
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1367 self.func = func
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1368 self.callable = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1369 self.file = file
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1370 self.line = line
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1371 self.str = str
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1372
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1373 def __str__(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1374 return self.str
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1375
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1376 def __repr__(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1377 return 'MiniProduction(%s)' % self.str
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1378
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1379 # Bind the production function name to a callable
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1380 def bind(self, pdict):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1381 if self.func:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1382 self.callable = pdict[self.func]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1383
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1384
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1385 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1386 # class LRItem
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1387 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1388 # This class represents a specific stage of parsing a production rule. For
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1389 # example:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1390 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1391 # expr : expr . PLUS term
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1392 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1393 # In the above, the "." represents the current location of the parse. Here
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1394 # basic attributes:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1395 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1396 # name - Name of the production. For example 'expr'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1397 # prod - A list of symbols on the right side ['expr','.', 'PLUS','term']
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1398 # number - Production number.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1399 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1400 # lr_next Next LR item. Example, if we are ' expr -> expr . PLUS term'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1401 # then lr_next refers to 'expr -> expr PLUS . term'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1402 # lr_index - LR item index (location of the ".") in the prod list.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1403 # lookaheads - LALR lookahead symbols for this item
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1404 # len - Length of the production (number of symbols on right hand side)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1405 # lr_after - List of all productions that immediately follow
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1406 # lr_before - Grammar symbol immediately before
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1407 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1408
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1409 class LRItem(object):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1410 def __init__(self, p, n):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1411 self.name = p.name
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1412 self.prod = list(p.prod)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1413 self.number = p.number
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1414 self.lr_index = n
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1415 self.lookaheads = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1416 self.prod.insert(n, '.')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1417 self.prod = tuple(self.prod)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1418 self.len = len(self.prod)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1419 self.usyms = p.usyms
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1420
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1421 def __str__(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1422 if self.prod:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1423 s = '%s -> %s' % (self.name, ' '.join(self.prod))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1424 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1425 s = '%s -> <empty>' % self.name
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1426 return s
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1427
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1428 def __repr__(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1429 return 'LRItem(' + str(self) + ')'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1430
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1431 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1432 # rightmost_terminal()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1433 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1434 # Return the rightmost terminal from a list of symbols. Used in add_production()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1435 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1436 def rightmost_terminal(symbols, terminals):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1437 i = len(symbols) - 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1438 while i >= 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1439 if symbols[i] in terminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1440 return symbols[i]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1441 i -= 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1442 return None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1443
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1444 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1445 # === GRAMMAR CLASS ===
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1446 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1447 # The following class represents the contents of the specified grammar along
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1448 # with various computed properties such as first sets, follow sets, LR items, etc.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1449 # This data is used for critical parts of the table generation process later.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1450 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1451
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1452 class GrammarError(YaccError):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1453 pass
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1454
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1455 class Grammar(object):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1456 def __init__(self, terminals):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1457 self.Productions = [None] # A list of all of the productions. The first
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1458 # entry is always reserved for the purpose of
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1459 # building an augmented grammar
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1460
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1461 self.Prodnames = {} # A dictionary mapping the names of nonterminals to a list of all
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1462 # productions of that nonterminal.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1463
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1464 self.Prodmap = {} # A dictionary that is only used to detect duplicate
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1465 # productions.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1466
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1467 self.Terminals = {} # A dictionary mapping the names of terminal symbols to a
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1468 # list of the rules where they are used.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1469
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1470 for term in terminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1471 self.Terminals[term] = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1472
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1473 self.Terminals['error'] = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1474
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1475 self.Nonterminals = {} # A dictionary mapping names of nonterminals to a list
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1476 # of rule numbers where they are used.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1477
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1478 self.First = {} # A dictionary of precomputed FIRST(x) symbols
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1479
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1480 self.Follow = {} # A dictionary of precomputed FOLLOW(x) symbols
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1481
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1482 self.Precedence = {} # Precedence rules for each terminal. Contains tuples of the
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1483 # form ('right',level) or ('nonassoc', level) or ('left',level)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1484
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1485 self.UsedPrecedence = set() # Precedence rules that were actually used by the grammer.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1486 # This is only used to provide error checking and to generate
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1487 # a warning about unused precedence rules.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1488
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1489 self.Start = None # Starting symbol for the grammar
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1490
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1491
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1492 def __len__(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1493 return len(self.Productions)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1494
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1495 def __getitem__(self, index):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1496 return self.Productions[index]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1497
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1498 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1499 # set_precedence()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1500 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1501 # Sets the precedence for a given terminal. assoc is the associativity such as
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1502 # 'left','right', or 'nonassoc'. level is a numeric level.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1503 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1504 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1505
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1506 def set_precedence(self, term, assoc, level):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1507 assert self.Productions == [None], 'Must call set_precedence() before add_production()'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1508 if term in self.Precedence:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1509 raise GrammarError('Precedence already specified for terminal %r' % term)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1510 if assoc not in ['left', 'right', 'nonassoc']:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1511 raise GrammarError("Associativity must be one of 'left','right', or 'nonassoc'")
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1512 self.Precedence[term] = (assoc, level)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1513
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1514 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1515 # add_production()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1516 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1517 # Given an action function, this function assembles a production rule and
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1518 # computes its precedence level.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1519 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1520 # The production rule is supplied as a list of symbols. For example,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1521 # a rule such as 'expr : expr PLUS term' has a production name of 'expr' and
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1522 # symbols ['expr','PLUS','term'].
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1523 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1524 # Precedence is determined by the precedence of the right-most non-terminal
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1525 # or the precedence of a terminal specified by %prec.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1526 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1527 # A variety of error checks are performed to make sure production symbols
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1528 # are valid and that %prec is used correctly.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1529 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1530
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1531 def add_production(self, prodname, syms, func=None, file='', line=0):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1532
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1533 if prodname in self.Terminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1534 raise GrammarError('%s:%d: Illegal rule name %r. Already defined as a token' % (file, line, prodname))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1535 if prodname == 'error':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1536 raise GrammarError('%s:%d: Illegal rule name %r. error is a reserved word' % (file, line, prodname))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1537 if not _is_identifier.match(prodname):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1538 raise GrammarError('%s:%d: Illegal rule name %r' % (file, line, prodname))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1539
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1540 # Look for literal tokens
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1541 for n, s in enumerate(syms):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1542 if s[0] in "'\"":
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1543 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1544 c = eval(s)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1545 if (len(c) > 1):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1546 raise GrammarError('%s:%d: Literal token %s in rule %r may only be a single character' %
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1547 (file, line, s, prodname))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1548 if c not in self.Terminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1549 self.Terminals[c] = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1550 syms[n] = c
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1551 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1552 except SyntaxError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1553 pass
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1554 if not _is_identifier.match(s) and s != '%prec':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1555 raise GrammarError('%s:%d: Illegal name %r in rule %r' % (file, line, s, prodname))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1556
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1557 # Determine the precedence level
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1558 if '%prec' in syms:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1559 if syms[-1] == '%prec':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1560 raise GrammarError('%s:%d: Syntax error. Nothing follows %%prec' % (file, line))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1561 if syms[-2] != '%prec':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1562 raise GrammarError('%s:%d: Syntax error. %%prec can only appear at the end of a grammar rule' %
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1563 (file, line))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1564 precname = syms[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1565 prodprec = self.Precedence.get(precname)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1566 if not prodprec:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1567 raise GrammarError('%s:%d: Nothing known about the precedence of %r' % (file, line, precname))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1568 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1569 self.UsedPrecedence.add(precname)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1570 del syms[-2:] # Drop %prec from the rule
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1571 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1572 # If no %prec, precedence is determined by the rightmost terminal symbol
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1573 precname = rightmost_terminal(syms, self.Terminals)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1574 prodprec = self.Precedence.get(precname, ('right', 0))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1575
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1576 # See if the rule is already in the rulemap
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1577 map = '%s -> %s' % (prodname, syms)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1578 if map in self.Prodmap:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1579 m = self.Prodmap[map]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1580 raise GrammarError('%s:%d: Duplicate rule %s. ' % (file, line, m) +
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1581 'Previous definition at %s:%d' % (m.file, m.line))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1582
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1583 # From this point on, everything is valid. Create a new Production instance
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1584 pnumber = len(self.Productions)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1585 if prodname not in self.Nonterminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1586 self.Nonterminals[prodname] = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1587
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1588 # Add the production number to Terminals and Nonterminals
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1589 for t in syms:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1590 if t in self.Terminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1591 self.Terminals[t].append(pnumber)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1592 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1593 if t not in self.Nonterminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1594 self.Nonterminals[t] = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1595 self.Nonterminals[t].append(pnumber)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1596
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1597 # Create a production and add it to the list of productions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1598 p = Production(pnumber, prodname, syms, prodprec, func, file, line)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1599 self.Productions.append(p)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1600 self.Prodmap[map] = p
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1601
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1602 # Add to the global productions list
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1603 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1604 self.Prodnames[prodname].append(p)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1605 except KeyError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1606 self.Prodnames[prodname] = [p]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1607
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1608 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1609 # set_start()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1610 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1611 # Sets the starting symbol and creates the augmented grammar. Production
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1612 # rule 0 is S' -> start where start is the start symbol.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1613 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1614
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1615 def set_start(self, start=None):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1616 if not start:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1617 start = self.Productions[1].name
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1618 if start not in self.Nonterminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1619 raise GrammarError('start symbol %s undefined' % start)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1620 self.Productions[0] = Production(0, "S'", [start])
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1621 self.Nonterminals[start].append(0)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1622 self.Start = start
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1623
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1624 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1625 # find_unreachable()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1626 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1627 # Find all of the nonterminal symbols that can't be reached from the starting
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1628 # symbol. Returns a list of nonterminals that can't be reached.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1629 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1630
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1631 def find_unreachable(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1632
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1633 # Mark all symbols that are reachable from a symbol s
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1634 def mark_reachable_from(s):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1635 if s in reachable:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1636 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1637 reachable.add(s)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1638 for p in self.Prodnames.get(s, []):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1639 for r in p.prod:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1640 mark_reachable_from(r)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1641
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1642 reachable = set()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1643 mark_reachable_from(self.Productions[0].prod[0])
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1644 return [s for s in self.Nonterminals if s not in reachable]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1645
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1646 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1647 # infinite_cycles()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1648 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1649 # This function looks at the various parsing rules and tries to detect
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1650 # infinite recursion cycles (grammar rules where there is no possible way
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1651 # to derive a string of only terminals).
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1652 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1653
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1654 def infinite_cycles(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1655 terminates = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1656
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1657 # Terminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1658 for t in self.Terminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1659 terminates[t] = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1660
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1661 terminates['$end'] = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1662
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1663 # Nonterminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1664
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1665 # Initialize to false:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1666 for n in self.Nonterminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1667 terminates[n] = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1668
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1669 # Then propagate termination until no change:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1670 while True:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1671 some_change = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1672 for (n, pl) in self.Prodnames.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1673 # Nonterminal n terminates iff any of its productions terminates.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1674 for p in pl:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1675 # Production p terminates iff all of its rhs symbols terminate.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1676 for s in p.prod:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1677 if not terminates[s]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1678 # The symbol s does not terminate,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1679 # so production p does not terminate.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1680 p_terminates = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1681 break
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1682 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1683 # didn't break from the loop,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1684 # so every symbol s terminates
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1685 # so production p terminates.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1686 p_terminates = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1687
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1688 if p_terminates:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1689 # symbol n terminates!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1690 if not terminates[n]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1691 terminates[n] = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1692 some_change = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1693 # Don't need to consider any more productions for this n.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1694 break
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1695
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1696 if not some_change:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1697 break
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1698
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1699 infinite = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1700 for (s, term) in terminates.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1701 if not term:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1702 if s not in self.Prodnames and s not in self.Terminals and s != 'error':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1703 # s is used-but-not-defined, and we've already warned of that,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1704 # so it would be overkill to say that it's also non-terminating.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1705 pass
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1706 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1707 infinite.append(s)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1708
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1709 return infinite
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1710
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1711 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1712 # undefined_symbols()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1713 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1714 # Find all symbols that were used the grammar, but not defined as tokens or
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1715 # grammar rules. Returns a list of tuples (sym, prod) where sym in the symbol
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1716 # and prod is the production where the symbol was used.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1717 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1718 def undefined_symbols(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1719 result = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1720 for p in self.Productions:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1721 if not p:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1722 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1723
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1724 for s in p.prod:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1725 if s not in self.Prodnames and s not in self.Terminals and s != 'error':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1726 result.append((s, p))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1727 return result
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1728
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1729 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1730 # unused_terminals()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1731 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1732 # Find all terminals that were defined, but not used by the grammar. Returns
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1733 # a list of all symbols.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1734 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1735 def unused_terminals(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1736 unused_tok = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1737 for s, v in self.Terminals.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1738 if s != 'error' and not v:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1739 unused_tok.append(s)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1740
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1741 return unused_tok
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1742
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1743 # ------------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1744 # unused_rules()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1745 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1746 # Find all grammar rules that were defined, but not used (maybe not reachable)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1747 # Returns a list of productions.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1748 # ------------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1749
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1750 def unused_rules(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1751 unused_prod = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1752 for s, v in self.Nonterminals.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1753 if not v:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1754 p = self.Prodnames[s][0]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1755 unused_prod.append(p)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1756 return unused_prod
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1757
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1758 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1759 # unused_precedence()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1760 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1761 # Returns a list of tuples (term,precedence) corresponding to precedence
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1762 # rules that were never used by the grammar. term is the name of the terminal
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1763 # on which precedence was applied and precedence is a string such as 'left' or
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1764 # 'right' corresponding to the type of precedence.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1765 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1766
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1767 def unused_precedence(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1768 unused = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1769 for termname in self.Precedence:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1770 if not (termname in self.Terminals or termname in self.UsedPrecedence):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1771 unused.append((termname, self.Precedence[termname][0]))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1772
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1773 return unused
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1774
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1775 # -------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1776 # _first()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1777 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1778 # Compute the value of FIRST1(beta) where beta is a tuple of symbols.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1779 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1780 # During execution of compute_first1, the result may be incomplete.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1781 # Afterward (e.g., when called from compute_follow()), it will be complete.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1782 # -------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1783 def _first(self, beta):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1784
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1785 # We are computing First(x1,x2,x3,...,xn)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1786 result = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1787 for x in beta:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1788 x_produces_empty = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1789
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1790 # Add all the non-<empty> symbols of First[x] to the result.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1791 for f in self.First[x]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1792 if f == '<empty>':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1793 x_produces_empty = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1794 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1795 if f not in result:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1796 result.append(f)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1797
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1798 if x_produces_empty:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1799 # We have to consider the next x in beta,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1800 # i.e. stay in the loop.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1801 pass
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1802 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1803 # We don't have to consider any further symbols in beta.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1804 break
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1805 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1806 # There was no 'break' from the loop,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1807 # so x_produces_empty was true for all x in beta,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1808 # so beta produces empty as well.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1809 result.append('<empty>')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1810
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1811 return result
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1812
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1813 # -------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1814 # compute_first()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1815 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1816 # Compute the value of FIRST1(X) for all symbols
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1817 # -------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1818 def compute_first(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1819 if self.First:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1820 return self.First
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1821
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1822 # Terminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1823 for t in self.Terminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1824 self.First[t] = [t]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1825
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1826 self.First['$end'] = ['$end']
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1827
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1828 # Nonterminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1829
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1830 # Initialize to the empty set:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1831 for n in self.Nonterminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1832 self.First[n] = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1833
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1834 # Then propagate symbols until no change:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1835 while True:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1836 some_change = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1837 for n in self.Nonterminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1838 for p in self.Prodnames[n]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1839 for f in self._first(p.prod):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1840 if f not in self.First[n]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1841 self.First[n].append(f)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1842 some_change = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1843 if not some_change:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1844 break
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1845
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1846 return self.First
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1847
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1848 # ---------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1849 # compute_follow()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1850 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1851 # Computes all of the follow sets for every non-terminal symbol. The
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1852 # follow set is the set of all symbols that might follow a given
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1853 # non-terminal. See the Dragon book, 2nd Ed. p. 189.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1854 # ---------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1855 def compute_follow(self, start=None):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1856 # If already computed, return the result
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1857 if self.Follow:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1858 return self.Follow
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1859
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1860 # If first sets not computed yet, do that first.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1861 if not self.First:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1862 self.compute_first()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1863
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1864 # Add '$end' to the follow list of the start symbol
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1865 for k in self.Nonterminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1866 self.Follow[k] = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1867
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1868 if not start:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1869 start = self.Productions[1].name
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1870
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1871 self.Follow[start] = ['$end']
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1872
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1873 while True:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1874 didadd = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1875 for p in self.Productions[1:]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1876 # Here is the production set
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1877 for i, B in enumerate(p.prod):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1878 if B in self.Nonterminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1879 # Okay. We got a non-terminal in a production
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1880 fst = self._first(p.prod[i+1:])
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1881 hasempty = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1882 for f in fst:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1883 if f != '<empty>' and f not in self.Follow[B]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1884 self.Follow[B].append(f)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1885 didadd = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1886 if f == '<empty>':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1887 hasempty = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1888 if hasempty or i == (len(p.prod)-1):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1889 # Add elements of follow(a) to follow(b)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1890 for f in self.Follow[p.name]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1891 if f not in self.Follow[B]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1892 self.Follow[B].append(f)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1893 didadd = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1894 if not didadd:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1895 break
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1896 return self.Follow
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1897
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1898
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1899 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1900 # build_lritems()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1901 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1902 # This function walks the list of productions and builds a complete set of the
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1903 # LR items. The LR items are stored in two ways: First, they are uniquely
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1904 # numbered and placed in the list _lritems. Second, a linked list of LR items
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1905 # is built for each production. For example:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1906 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1907 # E -> E PLUS E
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1908 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1909 # Creates the list
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1910 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1911 # [E -> . E PLUS E, E -> E . PLUS E, E -> E PLUS . E, E -> E PLUS E . ]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1912 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1913
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1914 def build_lritems(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1915 for p in self.Productions:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1916 lastlri = p
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1917 i = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1918 lr_items = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1919 while True:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1920 if i > len(p):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1921 lri = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1922 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1923 lri = LRItem(p, i)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1924 # Precompute the list of productions immediately following
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1925 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1926 lri.lr_after = self.Prodnames[lri.prod[i+1]]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1927 except (IndexError, KeyError):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1928 lri.lr_after = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1929 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1930 lri.lr_before = lri.prod[i-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1931 except IndexError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1932 lri.lr_before = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1933
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1934 lastlri.lr_next = lri
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1935 if not lri:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1936 break
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1937 lr_items.append(lri)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1938 lastlri = lri
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1939 i += 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1940 p.lr_items = lr_items
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1941
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1942 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1943 # == Class LRTable ==
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1944 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1945 # This basic class represents a basic table of LR parsing information.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1946 # Methods for generating the tables are not defined here. They are defined
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1947 # in the derived class LRGeneratedTable.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1948 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1949
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1950 class VersionError(YaccError):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1951 pass
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1952
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1953 class LRTable(object):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1954 def __init__(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1955 self.lr_action = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1956 self.lr_goto = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1957 self.lr_productions = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1958 self.lr_method = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1959
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1960 def read_table(self, module):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1961 if isinstance(module, types.ModuleType):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1962 parsetab = module
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1963 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1964 exec('import %s' % module)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1965 parsetab = sys.modules[module]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1966
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1967 if parsetab._tabversion != __tabversion__:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1968 raise VersionError('yacc table file version is out of date')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1969
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1970 self.lr_action = parsetab._lr_action
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1971 self.lr_goto = parsetab._lr_goto
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1972
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1973 self.lr_productions = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1974 for p in parsetab._lr_productions:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1975 self.lr_productions.append(MiniProduction(*p))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1976
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1977 self.lr_method = parsetab._lr_method
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1978 return parsetab._lr_signature
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1979
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1980 def read_pickle(self, filename):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1981 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1982 import cPickle as pickle
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1983 except ImportError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1984 import pickle
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1985
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1986 if not os.path.exists(filename):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1987 raise ImportError
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1988
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1989 in_f = open(filename, 'rb')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1990
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1991 tabversion = pickle.load(in_f)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1992 if tabversion != __tabversion__:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1993 raise VersionError('yacc table file version is out of date')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1994 self.lr_method = pickle.load(in_f)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1995 signature = pickle.load(in_f)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1996 self.lr_action = pickle.load(in_f)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1997 self.lr_goto = pickle.load(in_f)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1998 productions = pickle.load(in_f)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
1999
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2000 self.lr_productions = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2001 for p in productions:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2002 self.lr_productions.append(MiniProduction(*p))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2003
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2004 in_f.close()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2005 return signature
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2006
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2007 # Bind all production function names to callable objects in pdict
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2008 def bind_callables(self, pdict):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2009 for p in self.lr_productions:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2010 p.bind(pdict)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2011
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2012
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2013 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2014 # === LR Generator ===
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2015 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2016 # The following classes and functions are used to generate LR parsing tables on
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2017 # a grammar.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2018 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2019
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2020 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2021 # digraph()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2022 # traverse()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2023 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2024 # The following two functions are used to compute set valued functions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2025 # of the form:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2026 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2027 # F(x) = F'(x) U U{F(y) | x R y}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2028 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2029 # This is used to compute the values of Read() sets as well as FOLLOW sets
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2030 # in LALR(1) generation.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2031 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2032 # Inputs: X - An input set
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2033 # R - A relation
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2034 # FP - Set-valued function
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2035 # ------------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2036
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2037 def digraph(X, R, FP):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2038 N = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2039 for x in X:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2040 N[x] = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2041 stack = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2042 F = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2043 for x in X:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2044 if N[x] == 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2045 traverse(x, N, stack, F, X, R, FP)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2046 return F
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2047
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2048 def traverse(x, N, stack, F, X, R, FP):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2049 stack.append(x)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2050 d = len(stack)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2051 N[x] = d
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2052 F[x] = FP(x) # F(X) <- F'(x)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2053
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2054 rel = R(x) # Get y's related to x
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2055 for y in rel:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2056 if N[y] == 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2057 traverse(y, N, stack, F, X, R, FP)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2058 N[x] = min(N[x], N[y])
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2059 for a in F.get(y, []):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2060 if a not in F[x]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2061 F[x].append(a)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2062 if N[x] == d:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2063 N[stack[-1]] = MAXINT
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2064 F[stack[-1]] = F[x]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2065 element = stack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2066 while element != x:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2067 N[stack[-1]] = MAXINT
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2068 F[stack[-1]] = F[x]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2069 element = stack.pop()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2070
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2071 class LALRError(YaccError):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2072 pass
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2073
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2074 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2075 # == LRGeneratedTable ==
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2076 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2077 # This class implements the LR table generation algorithm. There are no
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2078 # public methods except for write()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2079 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2080
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2081 class LRGeneratedTable(LRTable):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2082 def __init__(self, grammar, method='LALR', log=None):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2083 if method not in ['SLR', 'LALR']:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2084 raise LALRError('Unsupported method %s' % method)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2085
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2086 self.grammar = grammar
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2087 self.lr_method = method
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2088
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2089 # Set up the logger
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2090 if not log:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2091 log = NullLogger()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2092 self.log = log
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2093
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2094 # Internal attributes
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2095 self.lr_action = {} # Action table
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2096 self.lr_goto = {} # Goto table
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2097 self.lr_productions = grammar.Productions # Copy of grammar Production array
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2098 self.lr_goto_cache = {} # Cache of computed gotos
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2099 self.lr0_cidhash = {} # Cache of closures
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2100
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2101 self._add_count = 0 # Internal counter used to detect cycles
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2102
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2103 # Diagonistic information filled in by the table generator
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2104 self.sr_conflict = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2105 self.rr_conflict = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2106 self.conflicts = [] # List of conflicts
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2107
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2108 self.sr_conflicts = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2109 self.rr_conflicts = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2110
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2111 # Build the tables
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2112 self.grammar.build_lritems()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2113 self.grammar.compute_first()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2114 self.grammar.compute_follow()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2115 self.lr_parse_table()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2116
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2117 # Compute the LR(0) closure operation on I, where I is a set of LR(0) items.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2118
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2119 def lr0_closure(self, I):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2120 self._add_count += 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2121
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2122 # Add everything in I to J
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2123 J = I[:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2124 didadd = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2125 while didadd:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2126 didadd = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2127 for j in J:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2128 for x in j.lr_after:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2129 if getattr(x, 'lr0_added', 0) == self._add_count:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2130 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2131 # Add B --> .G to J
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2132 J.append(x.lr_next)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2133 x.lr0_added = self._add_count
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2134 didadd = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2135
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2136 return J
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2137
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2138 # Compute the LR(0) goto function goto(I,X) where I is a set
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2139 # of LR(0) items and X is a grammar symbol. This function is written
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2140 # in a way that guarantees uniqueness of the generated goto sets
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2141 # (i.e. the same goto set will never be returned as two different Python
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2142 # objects). With uniqueness, we can later do fast set comparisons using
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2143 # id(obj) instead of element-wise comparison.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2144
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2145 def lr0_goto(self, I, x):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2146 # First we look for a previously cached entry
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2147 g = self.lr_goto_cache.get((id(I), x))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2148 if g:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2149 return g
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2150
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2151 # Now we generate the goto set in a way that guarantees uniqueness
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2152 # of the result
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2153
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2154 s = self.lr_goto_cache.get(x)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2155 if not s:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2156 s = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2157 self.lr_goto_cache[x] = s
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2158
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2159 gs = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2160 for p in I:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2161 n = p.lr_next
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2162 if n and n.lr_before == x:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2163 s1 = s.get(id(n))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2164 if not s1:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2165 s1 = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2166 s[id(n)] = s1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2167 gs.append(n)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2168 s = s1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2169 g = s.get('$end')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2170 if not g:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2171 if gs:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2172 g = self.lr0_closure(gs)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2173 s['$end'] = g
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2174 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2175 s['$end'] = gs
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2176 self.lr_goto_cache[(id(I), x)] = g
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2177 return g
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2178
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2179 # Compute the LR(0) sets of item function
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2180 def lr0_items(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2181 C = [self.lr0_closure([self.grammar.Productions[0].lr_next])]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2182 i = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2183 for I in C:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2184 self.lr0_cidhash[id(I)] = i
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2185 i += 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2186
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2187 # Loop over the items in C and each grammar symbols
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2188 i = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2189 while i < len(C):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2190 I = C[i]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2191 i += 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2192
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2193 # Collect all of the symbols that could possibly be in the goto(I,X) sets
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2194 asyms = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2195 for ii in I:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2196 for s in ii.usyms:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2197 asyms[s] = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2198
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2199 for x in asyms:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2200 g = self.lr0_goto(I, x)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2201 if not g or id(g) in self.lr0_cidhash:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2202 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2203 self.lr0_cidhash[id(g)] = len(C)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2204 C.append(g)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2205
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2206 return C
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2207
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2208 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2209 # ==== LALR(1) Parsing ====
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2210 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2211 # LALR(1) parsing is almost exactly the same as SLR except that instead of
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2212 # relying upon Follow() sets when performing reductions, a more selective
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2213 # lookahead set that incorporates the state of the LR(0) machine is utilized.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2214 # Thus, we mainly just have to focus on calculating the lookahead sets.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2215 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2216 # The method used here is due to DeRemer and Pennelo (1982).
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2217 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2218 # DeRemer, F. L., and T. J. Pennelo: "Efficient Computation of LALR(1)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2219 # Lookahead Sets", ACM Transactions on Programming Languages and Systems,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2220 # Vol. 4, No. 4, Oct. 1982, pp. 615-649
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2221 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2222 # Further details can also be found in:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2223 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2224 # J. Tremblay and P. Sorenson, "The Theory and Practice of Compiler Writing",
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2225 # McGraw-Hill Book Company, (1985).
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2226 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2227 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2228
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2229 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2230 # compute_nullable_nonterminals()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2231 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2232 # Creates a dictionary containing all of the non-terminals that might produce
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2233 # an empty production.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2234 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2235
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2236 def compute_nullable_nonterminals(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2237 nullable = set()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2238 num_nullable = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2239 while True:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2240 for p in self.grammar.Productions[1:]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2241 if p.len == 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2242 nullable.add(p.name)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2243 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2244 for t in p.prod:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2245 if t not in nullable:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2246 break
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2247 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2248 nullable.add(p.name)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2249 if len(nullable) == num_nullable:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2250 break
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2251 num_nullable = len(nullable)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2252 return nullable
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2253
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2254 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2255 # find_nonterminal_trans(C)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2256 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2257 # Given a set of LR(0) items, this functions finds all of the non-terminal
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2258 # transitions. These are transitions in which a dot appears immediately before
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2259 # a non-terminal. Returns a list of tuples of the form (state,N) where state
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2260 # is the state number and N is the nonterminal symbol.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2261 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2262 # The input C is the set of LR(0) items.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2263 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2264
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2265 def find_nonterminal_transitions(self, C):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2266 trans = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2267 for stateno, state in enumerate(C):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2268 for p in state:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2269 if p.lr_index < p.len - 1:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2270 t = (stateno, p.prod[p.lr_index+1])
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2271 if t[1] in self.grammar.Nonterminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2272 if t not in trans:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2273 trans.append(t)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2274 return trans
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2275
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2276 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2277 # dr_relation()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2278 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2279 # Computes the DR(p,A) relationships for non-terminal transitions. The input
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2280 # is a tuple (state,N) where state is a number and N is a nonterminal symbol.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2281 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2282 # Returns a list of terminals.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2283 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2284
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2285 def dr_relation(self, C, trans, nullable):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2286 dr_set = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2287 state, N = trans
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2288 terms = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2289
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2290 g = self.lr0_goto(C[state], N)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2291 for p in g:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2292 if p.lr_index < p.len - 1:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2293 a = p.prod[p.lr_index+1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2294 if a in self.grammar.Terminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2295 if a not in terms:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2296 terms.append(a)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2297
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2298 # This extra bit is to handle the start state
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2299 if state == 0 and N == self.grammar.Productions[0].prod[0]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2300 terms.append('$end')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2301
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2302 return terms
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2303
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2304 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2305 # reads_relation()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2306 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2307 # Computes the READS() relation (p,A) READS (t,C).
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2308 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2309
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2310 def reads_relation(self, C, trans, empty):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2311 # Look for empty transitions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2312 rel = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2313 state, N = trans
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2314
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2315 g = self.lr0_goto(C[state], N)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2316 j = self.lr0_cidhash.get(id(g), -1)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2317 for p in g:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2318 if p.lr_index < p.len - 1:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2319 a = p.prod[p.lr_index + 1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2320 if a in empty:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2321 rel.append((j, a))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2322
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2323 return rel
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2324
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2325 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2326 # compute_lookback_includes()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2327 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2328 # Determines the lookback and includes relations
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2329 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2330 # LOOKBACK:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2331 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2332 # This relation is determined by running the LR(0) state machine forward.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2333 # For example, starting with a production "N : . A B C", we run it forward
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2334 # to obtain "N : A B C ." We then build a relationship between this final
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2335 # state and the starting state. These relationships are stored in a dictionary
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2336 # lookdict.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2337 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2338 # INCLUDES:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2339 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2340 # Computes the INCLUDE() relation (p,A) INCLUDES (p',B).
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2341 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2342 # This relation is used to determine non-terminal transitions that occur
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2343 # inside of other non-terminal transition states. (p,A) INCLUDES (p', B)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2344 # if the following holds:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2345 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2346 # B -> LAT, where T -> epsilon and p' -L-> p
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2347 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2348 # L is essentially a prefix (which may be empty), T is a suffix that must be
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2349 # able to derive an empty string. State p' must lead to state p with the string L.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2350 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2351 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2352
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2353 def compute_lookback_includes(self, C, trans, nullable):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2354 lookdict = {} # Dictionary of lookback relations
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2355 includedict = {} # Dictionary of include relations
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2356
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2357 # Make a dictionary of non-terminal transitions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2358 dtrans = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2359 for t in trans:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2360 dtrans[t] = 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2361
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2362 # Loop over all transitions and compute lookbacks and includes
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2363 for state, N in trans:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2364 lookb = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2365 includes = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2366 for p in C[state]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2367 if p.name != N:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2368 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2369
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2370 # Okay, we have a name match. We now follow the production all the way
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2371 # through the state machine until we get the . on the right hand side
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2372
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2373 lr_index = p.lr_index
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2374 j = state
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2375 while lr_index < p.len - 1:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2376 lr_index = lr_index + 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2377 t = p.prod[lr_index]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2378
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2379 # Check to see if this symbol and state are a non-terminal transition
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2380 if (j, t) in dtrans:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2381 # Yes. Okay, there is some chance that this is an includes relation
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2382 # the only way to know for certain is whether the rest of the
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2383 # production derives empty
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2384
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2385 li = lr_index + 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2386 while li < p.len:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2387 if p.prod[li] in self.grammar.Terminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2388 break # No forget it
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2389 if p.prod[li] not in nullable:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2390 break
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2391 li = li + 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2392 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2393 # Appears to be a relation between (j,t) and (state,N)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2394 includes.append((j, t))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2395
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2396 g = self.lr0_goto(C[j], t) # Go to next set
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2397 j = self.lr0_cidhash.get(id(g), -1) # Go to next state
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2398
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2399 # When we get here, j is the final state, now we have to locate the production
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2400 for r in C[j]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2401 if r.name != p.name:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2402 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2403 if r.len != p.len:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2404 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2405 i = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2406 # This look is comparing a production ". A B C" with "A B C ."
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2407 while i < r.lr_index:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2408 if r.prod[i] != p.prod[i+1]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2409 break
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2410 i = i + 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2411 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2412 lookb.append((j, r))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2413 for i in includes:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2414 if i not in includedict:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2415 includedict[i] = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2416 includedict[i].append((state, N))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2417 lookdict[(state, N)] = lookb
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2418
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2419 return lookdict, includedict
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2420
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2421 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2422 # compute_read_sets()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2423 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2424 # Given a set of LR(0) items, this function computes the read sets.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2425 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2426 # Inputs: C = Set of LR(0) items
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2427 # ntrans = Set of nonterminal transitions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2428 # nullable = Set of empty transitions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2429 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2430 # Returns a set containing the read sets
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2431 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2432
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2433 def compute_read_sets(self, C, ntrans, nullable):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2434 FP = lambda x: self.dr_relation(C, x, nullable)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2435 R = lambda x: self.reads_relation(C, x, nullable)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2436 F = digraph(ntrans, R, FP)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2437 return F
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2438
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2439 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2440 # compute_follow_sets()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2441 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2442 # Given a set of LR(0) items, a set of non-terminal transitions, a readset,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2443 # and an include set, this function computes the follow sets
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2444 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2445 # Follow(p,A) = Read(p,A) U U {Follow(p',B) | (p,A) INCLUDES (p',B)}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2446 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2447 # Inputs:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2448 # ntrans = Set of nonterminal transitions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2449 # readsets = Readset (previously computed)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2450 # inclsets = Include sets (previously computed)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2451 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2452 # Returns a set containing the follow sets
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2453 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2454
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2455 def compute_follow_sets(self, ntrans, readsets, inclsets):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2456 FP = lambda x: readsets[x]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2457 R = lambda x: inclsets.get(x, [])
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2458 F = digraph(ntrans, R, FP)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2459 return F
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2460
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2461 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2462 # add_lookaheads()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2463 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2464 # Attaches the lookahead symbols to grammar rules.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2465 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2466 # Inputs: lookbacks - Set of lookback relations
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2467 # followset - Computed follow set
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2468 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2469 # This function directly attaches the lookaheads to productions contained
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2470 # in the lookbacks set
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2471 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2472
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2473 def add_lookaheads(self, lookbacks, followset):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2474 for trans, lb in lookbacks.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2475 # Loop over productions in lookback
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2476 for state, p in lb:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2477 if state not in p.lookaheads:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2478 p.lookaheads[state] = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2479 f = followset.get(trans, [])
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2480 for a in f:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2481 if a not in p.lookaheads[state]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2482 p.lookaheads[state].append(a)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2483
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2484 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2485 # add_lalr_lookaheads()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2486 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2487 # This function does all of the work of adding lookahead information for use
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2488 # with LALR parsing
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2489 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2490
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2491 def add_lalr_lookaheads(self, C):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2492 # Determine all of the nullable nonterminals
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2493 nullable = self.compute_nullable_nonterminals()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2494
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2495 # Find all non-terminal transitions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2496 trans = self.find_nonterminal_transitions(C)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2497
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2498 # Compute read sets
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2499 readsets = self.compute_read_sets(C, trans, nullable)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2500
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2501 # Compute lookback/includes relations
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2502 lookd, included = self.compute_lookback_includes(C, trans, nullable)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2503
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2504 # Compute LALR FOLLOW sets
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2505 followsets = self.compute_follow_sets(trans, readsets, included)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2506
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2507 # Add all of the lookaheads
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2508 self.add_lookaheads(lookd, followsets)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2509
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2510 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2511 # lr_parse_table()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2512 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2513 # This function constructs the parse tables for SLR or LALR
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2514 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2515 def lr_parse_table(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2516 Productions = self.grammar.Productions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2517 Precedence = self.grammar.Precedence
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2518 goto = self.lr_goto # Goto array
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2519 action = self.lr_action # Action array
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2520 log = self.log # Logger for output
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2521
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2522 actionp = {} # Action production array (temporary)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2523
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2524 log.info('Parsing method: %s', self.lr_method)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2525
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2526 # Step 1: Construct C = { I0, I1, ... IN}, collection of LR(0) items
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2527 # This determines the number of states
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2528
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2529 C = self.lr0_items()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2530
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2531 if self.lr_method == 'LALR':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2532 self.add_lalr_lookaheads(C)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2533
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2534 # Build the parser table, state by state
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2535 st = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2536 for I in C:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2537 # Loop over each production in I
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2538 actlist = [] # List of actions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2539 st_action = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2540 st_actionp = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2541 st_goto = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2542 log.info('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2543 log.info('state %d', st)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2544 log.info('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2545 for p in I:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2546 log.info(' (%d) %s', p.number, p)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2547 log.info('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2548
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2549 for p in I:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2550 if p.len == p.lr_index + 1:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2551 if p.name == "S'":
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2552 # Start symbol. Accept!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2553 st_action['$end'] = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2554 st_actionp['$end'] = p
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2555 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2556 # We are at the end of a production. Reduce!
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2557 if self.lr_method == 'LALR':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2558 laheads = p.lookaheads[st]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2559 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2560 laheads = self.grammar.Follow[p.name]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2561 for a in laheads:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2562 actlist.append((a, p, 'reduce using rule %d (%s)' % (p.number, p)))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2563 r = st_action.get(a)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2564 if r is not None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2565 # Whoa. Have a shift/reduce or reduce/reduce conflict
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2566 if r > 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2567 # Need to decide on shift or reduce here
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2568 # By default we favor shifting. Need to add
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2569 # some precedence rules here.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2570 sprec, slevel = Productions[st_actionp[a].number].prec
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2571 rprec, rlevel = Precedence.get(a, ('right', 0))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2572 if (slevel < rlevel) or ((slevel == rlevel) and (rprec == 'left')):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2573 # We really need to reduce here.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2574 st_action[a] = -p.number
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2575 st_actionp[a] = p
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2576 if not slevel and not rlevel:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2577 log.info(' ! shift/reduce conflict for %s resolved as reduce', a)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2578 self.sr_conflicts.append((st, a, 'reduce'))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2579 Productions[p.number].reduced += 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2580 elif (slevel == rlevel) and (rprec == 'nonassoc'):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2581 st_action[a] = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2582 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2583 # Hmmm. Guess we'll keep the shift
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2584 if not rlevel:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2585 log.info(' ! shift/reduce conflict for %s resolved as shift', a)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2586 self.sr_conflicts.append((st, a, 'shift'))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2587 elif r < 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2588 # Reduce/reduce conflict. In this case, we favor the rule
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2589 # that was defined first in the grammar file
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2590 oldp = Productions[-r]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2591 pp = Productions[p.number]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2592 if oldp.line > pp.line:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2593 st_action[a] = -p.number
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2594 st_actionp[a] = p
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2595 chosenp, rejectp = pp, oldp
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2596 Productions[p.number].reduced += 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2597 Productions[oldp.number].reduced -= 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2598 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2599 chosenp, rejectp = oldp, pp
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2600 self.rr_conflicts.append((st, chosenp, rejectp))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2601 log.info(' ! reduce/reduce conflict for %s resolved using rule %d (%s)',
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2602 a, st_actionp[a].number, st_actionp[a])
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2603 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2604 raise LALRError('Unknown conflict in state %d' % st)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2605 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2606 st_action[a] = -p.number
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2607 st_actionp[a] = p
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2608 Productions[p.number].reduced += 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2609 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2610 i = p.lr_index
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2611 a = p.prod[i+1] # Get symbol right after the "."
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2612 if a in self.grammar.Terminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2613 g = self.lr0_goto(I, a)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2614 j = self.lr0_cidhash.get(id(g), -1)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2615 if j >= 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2616 # We are in a shift state
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2617 actlist.append((a, p, 'shift and go to state %d' % j))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2618 r = st_action.get(a)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2619 if r is not None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2620 # Whoa have a shift/reduce or shift/shift conflict
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2621 if r > 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2622 if r != j:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2623 raise LALRError('Shift/shift conflict in state %d' % st)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2624 elif r < 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2625 # Do a precedence check.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2626 # - if precedence of reduce rule is higher, we reduce.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2627 # - if precedence of reduce is same and left assoc, we reduce.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2628 # - otherwise we shift
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2629 rprec, rlevel = Productions[st_actionp[a].number].prec
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2630 sprec, slevel = Precedence.get(a, ('right', 0))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2631 if (slevel > rlevel) or ((slevel == rlevel) and (rprec == 'right')):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2632 # We decide to shift here... highest precedence to shift
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2633 Productions[st_actionp[a].number].reduced -= 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2634 st_action[a] = j
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2635 st_actionp[a] = p
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2636 if not rlevel:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2637 log.info(' ! shift/reduce conflict for %s resolved as shift', a)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2638 self.sr_conflicts.append((st, a, 'shift'))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2639 elif (slevel == rlevel) and (rprec == 'nonassoc'):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2640 st_action[a] = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2641 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2642 # Hmmm. Guess we'll keep the reduce
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2643 if not slevel and not rlevel:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2644 log.info(' ! shift/reduce conflict for %s resolved as reduce', a)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2645 self.sr_conflicts.append((st, a, 'reduce'))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2646
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2647 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2648 raise LALRError('Unknown conflict in state %d' % st)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2649 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2650 st_action[a] = j
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2651 st_actionp[a] = p
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2652
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2653 # Print the actions associated with each terminal
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2654 _actprint = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2655 for a, p, m in actlist:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2656 if a in st_action:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2657 if p is st_actionp[a]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2658 log.info(' %-15s %s', a, m)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2659 _actprint[(a, m)] = 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2660 log.info('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2661 # Print the actions that were not used. (debugging)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2662 not_used = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2663 for a, p, m in actlist:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2664 if a in st_action:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2665 if p is not st_actionp[a]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2666 if not (a, m) in _actprint:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2667 log.debug(' ! %-15s [ %s ]', a, m)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2668 not_used = 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2669 _actprint[(a, m)] = 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2670 if not_used:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2671 log.debug('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2672
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2673 # Construct the goto table for this state
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2674
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2675 nkeys = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2676 for ii in I:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2677 for s in ii.usyms:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2678 if s in self.grammar.Nonterminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2679 nkeys[s] = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2680 for n in nkeys:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2681 g = self.lr0_goto(I, n)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2682 j = self.lr0_cidhash.get(id(g), -1)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2683 if j >= 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2684 st_goto[n] = j
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2685 log.info(' %-30s shift and go to state %d', n, j)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2686
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2687 action[st] = st_action
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2688 actionp[st] = st_actionp
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2689 goto[st] = st_goto
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2690 st += 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2691
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2692 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2693 # write()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2694 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2695 # This function writes the LR parsing tables to a file
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2696 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2697
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2698 def write_table(self, tabmodule, outputdir='', signature=''):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2699 if isinstance(tabmodule, types.ModuleType):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2700 raise IOError("Won't overwrite existing tabmodule")
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2701
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2702 basemodulename = tabmodule.split('.')[-1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2703 filename = os.path.join(outputdir, basemodulename) + '.py'
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2704 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2705 f = open(filename, 'w')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2706
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2707 f.write('''
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2708 # %s
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2709 # This file is automatically generated. Do not edit.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2710 _tabversion = %r
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2711
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2712 _lr_method = %r
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2713
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2714 _lr_signature = %r
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2715 ''' % (os.path.basename(filename), __tabversion__, self.lr_method, signature))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2716
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2717 # Change smaller to 0 to go back to original tables
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2718 smaller = 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2719
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2720 # Factor out names to try and make smaller
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2721 if smaller:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2722 items = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2723
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2724 for s, nd in self.lr_action.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2725 for name, v in nd.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2726 i = items.get(name)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2727 if not i:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2728 i = ([], [])
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2729 items[name] = i
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2730 i[0].append(s)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2731 i[1].append(v)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2732
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2733 f.write('\n_lr_action_items = {')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2734 for k, v in items.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2735 f.write('%r:([' % k)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2736 for i in v[0]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2737 f.write('%r,' % i)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2738 f.write('],[')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2739 for i in v[1]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2740 f.write('%r,' % i)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2741
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2742 f.write(']),')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2743 f.write('}\n')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2744
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2745 f.write('''
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2746 _lr_action = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2747 for _k, _v in _lr_action_items.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2748 for _x,_y in zip(_v[0],_v[1]):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2749 if not _x in _lr_action: _lr_action[_x] = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2750 _lr_action[_x][_k] = _y
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2751 del _lr_action_items
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2752 ''')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2753
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2754 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2755 f.write('\n_lr_action = { ')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2756 for k, v in self.lr_action.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2757 f.write('(%r,%r):%r,' % (k[0], k[1], v))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2758 f.write('}\n')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2759
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2760 if smaller:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2761 # Factor out names to try and make smaller
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2762 items = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2763
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2764 for s, nd in self.lr_goto.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2765 for name, v in nd.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2766 i = items.get(name)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2767 if not i:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2768 i = ([], [])
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2769 items[name] = i
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2770 i[0].append(s)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2771 i[1].append(v)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2772
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2773 f.write('\n_lr_goto_items = {')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2774 for k, v in items.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2775 f.write('%r:([' % k)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2776 for i in v[0]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2777 f.write('%r,' % i)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2778 f.write('],[')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2779 for i in v[1]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2780 f.write('%r,' % i)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2781
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2782 f.write(']),')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2783 f.write('}\n')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2784
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2785 f.write('''
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2786 _lr_goto = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2787 for _k, _v in _lr_goto_items.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2788 for _x, _y in zip(_v[0], _v[1]):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2789 if not _x in _lr_goto: _lr_goto[_x] = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2790 _lr_goto[_x][_k] = _y
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2791 del _lr_goto_items
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2792 ''')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2793 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2794 f.write('\n_lr_goto = { ')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2795 for k, v in self.lr_goto.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2796 f.write('(%r,%r):%r,' % (k[0], k[1], v))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2797 f.write('}\n')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2798
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2799 # Write production table
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2800 f.write('_lr_productions = [\n')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2801 for p in self.lr_productions:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2802 if p.func:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2803 f.write(' (%r,%r,%d,%r,%r,%d),\n' % (p.str, p.name, p.len,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2804 p.func, os.path.basename(p.file), p.line))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2805 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2806 f.write(' (%r,%r,%d,None,None,None),\n' % (str(p), p.name, p.len))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2807 f.write(']\n')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2808 f.close()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2809
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2810 except IOError as e:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2811 raise
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2812
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2813
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2814 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2815 # pickle_table()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2816 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2817 # This function pickles the LR parsing tables to a supplied file object
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2818 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2819
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2820 def pickle_table(self, filename, signature=''):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2821 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2822 import cPickle as pickle
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2823 except ImportError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2824 import pickle
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2825 with open(filename, 'wb') as outf:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2826 pickle.dump(__tabversion__, outf, pickle_protocol)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2827 pickle.dump(self.lr_method, outf, pickle_protocol)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2828 pickle.dump(signature, outf, pickle_protocol)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2829 pickle.dump(self.lr_action, outf, pickle_protocol)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2830 pickle.dump(self.lr_goto, outf, pickle_protocol)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2831
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2832 outp = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2833 for p in self.lr_productions:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2834 if p.func:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2835 outp.append((p.str, p.name, p.len, p.func, os.path.basename(p.file), p.line))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2836 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2837 outp.append((str(p), p.name, p.len, None, None, None))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2838 pickle.dump(outp, outf, pickle_protocol)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2839
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2840 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2841 # === INTROSPECTION ===
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2842 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2843 # The following functions and classes are used to implement the PLY
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2844 # introspection features followed by the yacc() function itself.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2845 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2846
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2847 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2848 # get_caller_module_dict()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2849 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2850 # This function returns a dictionary containing all of the symbols defined within
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2851 # a caller further down the call stack. This is used to get the environment
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2852 # associated with the yacc() call if none was provided.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2853 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2854
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2855 def get_caller_module_dict(levels):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2856 f = sys._getframe(levels)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2857 ldict = f.f_globals.copy()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2858 if f.f_globals != f.f_locals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2859 ldict.update(f.f_locals)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2860 return ldict
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2861
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2862 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2863 # parse_grammar()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2864 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2865 # This takes a raw grammar rule string and parses it into production data
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2866 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2867 def parse_grammar(doc, file, line):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2868 grammar = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2869 # Split the doc string into lines
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2870 pstrings = doc.splitlines()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2871 lastp = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2872 dline = line
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2873 for ps in pstrings:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2874 dline += 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2875 p = ps.split()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2876 if not p:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2877 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2878 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2879 if p[0] == '|':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2880 # This is a continuation of a previous rule
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2881 if not lastp:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2882 raise SyntaxError("%s:%d: Misplaced '|'" % (file, dline))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2883 prodname = lastp
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2884 syms = p[1:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2885 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2886 prodname = p[0]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2887 lastp = prodname
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2888 syms = p[2:]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2889 assign = p[1]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2890 if assign != ':' and assign != '::=':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2891 raise SyntaxError("%s:%d: Syntax error. Expected ':'" % (file, dline))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2892
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2893 grammar.append((file, dline, prodname, syms))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2894 except SyntaxError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2895 raise
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2896 except Exception:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2897 raise SyntaxError('%s:%d: Syntax error in rule %r' % (file, dline, ps.strip()))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2898
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2899 return grammar
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2900
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2901 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2902 # ParserReflect()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2903 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2904 # This class represents information extracted for building a parser including
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2905 # start symbol, error function, tokens, precedence list, action functions,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2906 # etc.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2907 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2908 class ParserReflect(object):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2909 def __init__(self, pdict, log=None):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2910 self.pdict = pdict
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2911 self.start = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2912 self.error_func = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2913 self.tokens = None
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2914 self.modules = set()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2915 self.grammar = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2916 self.error = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2917
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2918 if log is None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2919 self.log = PlyLogger(sys.stderr)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2920 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2921 self.log = log
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2922
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2923 # Get all of the basic information
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2924 def get_all(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2925 self.get_start()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2926 self.get_error_func()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2927 self.get_tokens()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2928 self.get_precedence()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2929 self.get_pfunctions()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2930
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2931 # Validate all of the information
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2932 def validate_all(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2933 self.validate_start()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2934 self.validate_error_func()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2935 self.validate_tokens()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2936 self.validate_precedence()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2937 self.validate_pfunctions()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2938 self.validate_modules()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2939 return self.error
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2940
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2941 # Compute a signature over the grammar
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2942 def signature(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2943 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2944 from hashlib import md5
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2945 except ImportError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2946 from md5 import md5
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2947 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2948 sig = md5()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2949 if self.start:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2950 sig.update(self.start.encode('latin-1'))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2951 if self.prec:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2952 sig.update(''.join([''.join(p) for p in self.prec]).encode('latin-1'))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2953 if self.tokens:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2954 sig.update(' '.join(self.tokens).encode('latin-1'))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2955 for f in self.pfuncs:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2956 if f[3]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2957 sig.update(f[3].encode('latin-1'))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2958 except (TypeError, ValueError):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2959 pass
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2960
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2961 digest = base64.b16encode(sig.digest())
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2962 if sys.version_info[0] >= 3:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2963 digest = digest.decode('latin-1')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2964 return digest
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2965
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2966 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2967 # validate_modules()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2968 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2969 # This method checks to see if there are duplicated p_rulename() functions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2970 # in the parser module file. Without this function, it is really easy for
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2971 # users to make mistakes by cutting and pasting code fragments (and it's a real
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2972 # bugger to try and figure out why the resulting parser doesn't work). Therefore,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2973 # we just do a little regular expression pattern matching of def statements
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2974 # to try and detect duplicates.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2975 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2976
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2977 def validate_modules(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2978 # Match def p_funcname(
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2979 fre = re.compile(r'\s*def\s+(p_[a-zA-Z_0-9]*)\(')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2980
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2981 for module in self.modules:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2982 lines, linen = inspect.getsourcelines(module)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2983
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2984 counthash = {}
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2985 for linen, line in enumerate(lines):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2986 linen += 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2987 m = fre.match(line)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2988 if m:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2989 name = m.group(1)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2990 prev = counthash.get(name)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2991 if not prev:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2992 counthash[name] = linen
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2993 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2994 filename = inspect.getsourcefile(module)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2995 self.log.warning('%s:%d: Function %s redefined. Previously defined on line %d',
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2996 filename, linen, name, prev)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2997
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2998 # Get the start symbol
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
2999 def get_start(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3000 self.start = self.pdict.get('start')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3001
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3002 # Validate the start symbol
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3003 def validate_start(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3004 if self.start is not None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3005 if not isinstance(self.start, string_types):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3006 self.log.error("'start' must be a string")
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3007
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3008 # Look for error handler
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3009 def get_error_func(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3010 self.error_func = self.pdict.get('p_error')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3011
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3012 # Validate the error function
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3013 def validate_error_func(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3014 if self.error_func:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3015 if isinstance(self.error_func, types.FunctionType):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3016 ismethod = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3017 elif isinstance(self.error_func, types.MethodType):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3018 ismethod = 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3019 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3020 self.log.error("'p_error' defined, but is not a function or method")
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3021 self.error = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3022 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3023
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3024 eline = self.error_func.__code__.co_firstlineno
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3025 efile = self.error_func.__code__.co_filename
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3026 module = inspect.getmodule(self.error_func)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3027 self.modules.add(module)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3028
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3029 argcount = self.error_func.__code__.co_argcount - ismethod
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3030 if argcount != 1:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3031 self.log.error('%s:%d: p_error() requires 1 argument', efile, eline)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3032 self.error = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3033
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3034 # Get the tokens map
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3035 def get_tokens(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3036 tokens = self.pdict.get('tokens')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3037 if not tokens:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3038 self.log.error('No token list is defined')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3039 self.error = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3040 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3041
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3042 if not isinstance(tokens, (list, tuple)):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3043 self.log.error('tokens must be a list or tuple')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3044 self.error = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3045 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3046
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3047 if not tokens:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3048 self.log.error('tokens is empty')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3049 self.error = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3050 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3051
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3052 self.tokens = tokens
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3053
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3054 # Validate the tokens
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3055 def validate_tokens(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3056 # Validate the tokens.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3057 if 'error' in self.tokens:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3058 self.log.error("Illegal token name 'error'. Is a reserved word")
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3059 self.error = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3060 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3061
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3062 terminals = set()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3063 for n in self.tokens:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3064 if n in terminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3065 self.log.warning('Token %r multiply defined', n)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3066 terminals.add(n)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3067
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3068 # Get the precedence map (if any)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3069 def get_precedence(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3070 self.prec = self.pdict.get('precedence')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3071
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3072 # Validate and parse the precedence map
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3073 def validate_precedence(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3074 preclist = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3075 if self.prec:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3076 if not isinstance(self.prec, (list, tuple)):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3077 self.log.error('precedence must be a list or tuple')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3078 self.error = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3079 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3080 for level, p in enumerate(self.prec):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3081 if not isinstance(p, (list, tuple)):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3082 self.log.error('Bad precedence table')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3083 self.error = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3084 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3085
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3086 if len(p) < 2:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3087 self.log.error('Malformed precedence entry %s. Must be (assoc, term, ..., term)', p)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3088 self.error = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3089 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3090 assoc = p[0]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3091 if not isinstance(assoc, string_types):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3092 self.log.error('precedence associativity must be a string')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3093 self.error = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3094 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3095 for term in p[1:]:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3096 if not isinstance(term, string_types):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3097 self.log.error('precedence items must be strings')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3098 self.error = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3099 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3100 preclist.append((term, assoc, level+1))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3101 self.preclist = preclist
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3102
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3103 # Get all p_functions from the grammar
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3104 def get_pfunctions(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3105 p_functions = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3106 for name, item in self.pdict.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3107 if not name.startswith('p_') or name == 'p_error':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3108 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3109 if isinstance(item, (types.FunctionType, types.MethodType)):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3110 line = item.__code__.co_firstlineno
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3111 module = inspect.getmodule(item)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3112 p_functions.append((line, module, name, item.__doc__))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3113
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3114 # Sort all of the actions by line number; make sure to stringify
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3115 # modules to make them sortable, since `line` may not uniquely sort all
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3116 # p functions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3117 p_functions.sort(key=lambda p_function: (
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3118 p_function[0],
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3119 str(p_function[1]),
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3120 p_function[2],
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3121 p_function[3]))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3122 self.pfuncs = p_functions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3123
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3124 # Validate all of the p_functions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3125 def validate_pfunctions(self):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3126 grammar = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3127 # Check for non-empty symbols
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3128 if len(self.pfuncs) == 0:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3129 self.log.error('no rules of the form p_rulename are defined')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3130 self.error = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3131 return
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3132
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3133 for line, module, name, doc in self.pfuncs:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3134 file = inspect.getsourcefile(module)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3135 func = self.pdict[name]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3136 if isinstance(func, types.MethodType):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3137 reqargs = 2
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3138 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3139 reqargs = 1
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3140 if func.__code__.co_argcount > reqargs:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3141 self.log.error('%s:%d: Rule %r has too many arguments', file, line, func.__name__)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3142 self.error = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3143 elif func.__code__.co_argcount < reqargs:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3144 self.log.error('%s:%d: Rule %r requires an argument', file, line, func.__name__)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3145 self.error = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3146 elif not func.__doc__:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3147 self.log.warning('%s:%d: No documentation string specified in function %r (ignored)',
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3148 file, line, func.__name__)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3149 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3150 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3151 parsed_g = parse_grammar(doc, file, line)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3152 for g in parsed_g:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3153 grammar.append((name, g))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3154 except SyntaxError as e:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3155 self.log.error(str(e))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3156 self.error = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3157
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3158 # Looks like a valid grammar rule
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3159 # Mark the file in which defined.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3160 self.modules.add(module)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3161
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3162 # Secondary validation step that looks for p_ definitions that are not functions
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3163 # or functions that look like they might be grammar rules.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3164
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3165 for n, v in self.pdict.items():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3166 if n.startswith('p_') and isinstance(v, (types.FunctionType, types.MethodType)):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3167 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3168 if n.startswith('t_'):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3169 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3170 if n.startswith('p_') and n != 'p_error':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3171 self.log.warning('%r not defined as a function', n)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3172 if ((isinstance(v, types.FunctionType) and v.__code__.co_argcount == 1) or
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3173 (isinstance(v, types.MethodType) and v.__func__.__code__.co_argcount == 2)):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3174 if v.__doc__:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3175 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3176 doc = v.__doc__.split(' ')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3177 if doc[1] == ':':
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3178 self.log.warning('%s:%d: Possible grammar rule %r defined without p_ prefix',
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3179 v.__code__.co_filename, v.__code__.co_firstlineno, n)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3180 except IndexError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3181 pass
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3182
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3183 self.grammar = grammar
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3184
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3185 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3186 # yacc(module)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3187 #
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3188 # Build a parser
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3189 # -----------------------------------------------------------------------------
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3190
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3191 def yacc(method='LALR', debug=yaccdebug, module=None, tabmodule=tab_module, start=None,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3192 check_recursion=True, optimize=False, write_tables=True, debugfile=debug_file,
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3193 outputdir=None, debuglog=None, errorlog=None, picklefile=None):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3194
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3195 if tabmodule is None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3196 tabmodule = tab_module
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3197
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3198 # Reference to the parsing method of the last built parser
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3199 global parse
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3200
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3201 # If pickling is enabled, table files are not created
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3202 if picklefile:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3203 write_tables = 0
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3204
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3205 if errorlog is None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3206 errorlog = PlyLogger(sys.stderr)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3207
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3208 # Get the module dictionary used for the parser
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3209 if module:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3210 _items = [(k, getattr(module, k)) for k in dir(module)]
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3211 pdict = dict(_items)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3212 # If no __file__ attribute is available, try to obtain it from the __module__ instead
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3213 if '__file__' not in pdict:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3214 pdict['__file__'] = sys.modules[pdict['__module__']].__file__
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3215 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3216 pdict = get_caller_module_dict(2)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3217
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3218 if outputdir is None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3219 # If no output directory is set, the location of the output files
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3220 # is determined according to the following rules:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3221 # - If tabmodule specifies a package, files go into that package directory
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3222 # - Otherwise, files go in the same directory as the specifying module
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3223 if isinstance(tabmodule, types.ModuleType):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3224 srcfile = tabmodule.__file__
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3225 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3226 if '.' not in tabmodule:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3227 srcfile = pdict['__file__']
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3228 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3229 parts = tabmodule.split('.')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3230 pkgname = '.'.join(parts[:-1])
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3231 exec('import %s' % pkgname)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3232 srcfile = getattr(sys.modules[pkgname], '__file__', '')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3233 outputdir = os.path.dirname(srcfile)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3234
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3235 # Determine if the module is package of a package or not.
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3236 # If so, fix the tabmodule setting so that tables load correctly
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3237 pkg = pdict.get('__package__')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3238 if pkg and isinstance(tabmodule, str):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3239 if '.' not in tabmodule:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3240 tabmodule = pkg + '.' + tabmodule
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3241
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3242
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3243
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3244 # Set start symbol if it's specified directly using an argument
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3245 if start is not None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3246 pdict['start'] = start
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3247
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3248 # Collect parser information from the dictionary
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3249 pinfo = ParserReflect(pdict, log=errorlog)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3250 pinfo.get_all()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3251
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3252 if pinfo.error:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3253 raise YaccError('Unable to build parser')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3254
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3255 # Check signature against table files (if any)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3256 signature = pinfo.signature()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3257
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3258 # Read the tables
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3259 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3260 lr = LRTable()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3261 if picklefile:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3262 read_signature = lr.read_pickle(picklefile)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3263 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3264 read_signature = lr.read_table(tabmodule)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3265 if optimize or (read_signature == signature):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3266 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3267 lr.bind_callables(pinfo.pdict)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3268 parser = LRParser(lr, pinfo.error_func)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3269 parse = parser.parse
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3270 return parser
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3271 except Exception as e:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3272 errorlog.warning('There was a problem loading the table file: %r', e)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3273 except VersionError as e:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3274 errorlog.warning(str(e))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3275 except ImportError:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3276 pass
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3277
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3278 if debuglog is None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3279 if debug:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3280 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3281 debuglog = PlyLogger(open(os.path.join(outputdir, debugfile), 'w'))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3282 except IOError as e:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3283 errorlog.warning("Couldn't open %r. %s" % (debugfile, e))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3284 debuglog = NullLogger()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3285 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3286 debuglog = NullLogger()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3287
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3288 debuglog.info('Created by PLY version %s (http://www.dabeaz.com/ply)', __version__)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3289
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3290 errors = False
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3291
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3292 # Validate the parser information
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3293 if pinfo.validate_all():
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3294 raise YaccError('Unable to build parser')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3295
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3296 if not pinfo.error_func:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3297 errorlog.warning('no p_error() function is defined')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3298
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3299 # Create a grammar object
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3300 grammar = Grammar(pinfo.tokens)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3301
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3302 # Set precedence level for terminals
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3303 for term, assoc, level in pinfo.preclist:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3304 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3305 grammar.set_precedence(term, assoc, level)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3306 except GrammarError as e:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3307 errorlog.warning('%s', e)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3308
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3309 # Add productions to the grammar
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3310 for funcname, gram in pinfo.grammar:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3311 file, line, prodname, syms = gram
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3312 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3313 grammar.add_production(prodname, syms, funcname, file, line)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3314 except GrammarError as e:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3315 errorlog.error('%s', e)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3316 errors = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3317
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3318 # Set the grammar start symbols
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3319 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3320 if start is None:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3321 grammar.set_start(pinfo.start)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3322 else:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3323 grammar.set_start(start)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3324 except GrammarError as e:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3325 errorlog.error(str(e))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3326 errors = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3327
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3328 if errors:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3329 raise YaccError('Unable to build parser')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3330
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3331 # Verify the grammar structure
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3332 undefined_symbols = grammar.undefined_symbols()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3333 for sym, prod in undefined_symbols:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
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)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3335 errors = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3336
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3337 unused_terminals = grammar.unused_terminals()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3338 if unused_terminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3339 debuglog.info('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3340 debuglog.info('Unused terminals:')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3341 debuglog.info('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3342 for term in unused_terminals:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3343 errorlog.warning('Token %r defined, but not used', term)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3344 debuglog.info(' %s', term)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3345
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3346 # Print out all productions to the debug log
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3347 if debug:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3348 debuglog.info('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3349 debuglog.info('Grammar')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3350 debuglog.info('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3351 for n, p in enumerate(grammar.Productions):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3352 debuglog.info('Rule %-5d %s', n, p)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3353
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3354 # Find unused non-terminals
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3355 unused_rules = grammar.unused_rules()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3356 for prod in unused_rules:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3357 errorlog.warning('%s:%d: Rule %r defined, but not used', prod.file, prod.line, prod.name)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3358
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3359 if len(unused_terminals) == 1:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3360 errorlog.warning('There is 1 unused token')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3361 if len(unused_terminals) > 1:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3362 errorlog.warning('There are %d unused tokens', len(unused_terminals))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3363
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3364 if len(unused_rules) == 1:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3365 errorlog.warning('There is 1 unused rule')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3366 if len(unused_rules) > 1:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3367 errorlog.warning('There are %d unused rules', len(unused_rules))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3368
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3369 if debug:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3370 debuglog.info('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3371 debuglog.info('Terminals, with rules where they appear')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3372 debuglog.info('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3373 terms = list(grammar.Terminals)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3374 terms.sort()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3375 for term in terms:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3376 debuglog.info('%-20s : %s', term, ' '.join([str(s) for s in grammar.Terminals[term]]))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3377
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3378 debuglog.info('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3379 debuglog.info('Nonterminals, with rules where they appear')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3380 debuglog.info('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3381 nonterms = list(grammar.Nonterminals)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3382 nonterms.sort()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3383 for nonterm in nonterms:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3384 debuglog.info('%-20s : %s', nonterm, ' '.join([str(s) for s in grammar.Nonterminals[nonterm]]))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3385 debuglog.info('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3386
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3387 if check_recursion:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3388 unreachable = grammar.find_unreachable()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3389 for u in unreachable:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3390 errorlog.warning('Symbol %r is unreachable', u)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3391
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3392 infinite = grammar.infinite_cycles()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3393 for inf in infinite:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3394 errorlog.error('Infinite recursion detected for symbol %r', inf)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3395 errors = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3396
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3397 unused_prec = grammar.unused_precedence()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3398 for term, assoc in unused_prec:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3399 errorlog.error('Precedence rule %r defined for unknown symbol %r', assoc, term)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3400 errors = True
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3401
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3402 if errors:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3403 raise YaccError('Unable to build parser')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3404
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3405 # Run the LRGeneratedTable on the grammar
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3406 if debug:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3407 errorlog.debug('Generating %s tables', method)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3408
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3409 lr = LRGeneratedTable(grammar, method, debuglog)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3410
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3411 if debug:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3412 num_sr = len(lr.sr_conflicts)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3413
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3414 # Report shift/reduce and reduce/reduce conflicts
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3415 if num_sr == 1:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3416 errorlog.warning('1 shift/reduce conflict')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3417 elif num_sr > 1:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3418 errorlog.warning('%d shift/reduce conflicts', num_sr)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3419
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3420 num_rr = len(lr.rr_conflicts)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3421 if num_rr == 1:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3422 errorlog.warning('1 reduce/reduce conflict')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3423 elif num_rr > 1:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3424 errorlog.warning('%d reduce/reduce conflicts', num_rr)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3425
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3426 # Write out conflicts to the output file
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3427 if debug and (lr.sr_conflicts or lr.rr_conflicts):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3428 debuglog.warning('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3429 debuglog.warning('Conflicts:')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3430 debuglog.warning('')
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3431
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3432 for state, tok, resolution in lr.sr_conflicts:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3433 debuglog.warning('shift/reduce conflict for %s in state %d resolved as %s', tok, state, resolution)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3434
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3435 already_reported = set()
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3436 for state, rule, rejected in lr.rr_conflicts:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3437 if (state, id(rule), id(rejected)) in already_reported:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3438 continue
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3439 debuglog.warning('reduce/reduce conflict in state %d resolved using rule (%s)', state, rule)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3440 debuglog.warning('rejected rule (%s) in state %d', rejected, state)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3441 errorlog.warning('reduce/reduce conflict in state %d resolved using rule (%s)', state, rule)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3442 errorlog.warning('rejected rule (%s) in state %d', rejected, state)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3443 already_reported.add((state, id(rule), id(rejected)))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3444
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3445 warned_never = []
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3446 for state, rule, rejected in lr.rr_conflicts:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3447 if not rejected.reduced and (rejected not in warned_never):
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3448 debuglog.warning('Rule (%s) is never reduced', rejected)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3449 errorlog.warning('Rule (%s) is never reduced', rejected)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3450 warned_never.append(rejected)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3451
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3452 # Write the table file if requested
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3453 if write_tables:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3454 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3455 lr.write_table(tabmodule, outputdir, signature)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3456 except IOError as e:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3457 errorlog.warning("Couldn't create %r. %s" % (tabmodule, e))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3458
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3459 # Write a pickled version of the tables
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3460 if picklefile:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3461 try:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3462 lr.pickle_table(picklefile, signature)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3463 except IOError as e:
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3464 errorlog.warning("Couldn't create %r. %s" % (picklefile, e))
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3465
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3466 # Build the parser
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3467 lr.bind_callables(pinfo.pdict)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3468 parser = LRParser(lr, pinfo.error_func)
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3469
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3470 parse = parser.parse
a1845676eaa0 <ais523> ` (cd ply-3.8; python setup.py build)
HackBot
parents:
diff changeset
3471 return parser