Go to the documentation of this file.00001 """ANTLR3 runtime package"""
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 from constants import EOF
00034 from exceptions import NoViableAltException, BacktrackingFailed
00035
00036
00037 class DFA(object):
00038 """@brief A DFA implemented as a set of transition tables.
00039
00040 Any state that has a semantic predicate edge is special; those states
00041 are generated with if-then-else structures in a specialStateTransition()
00042 which is generated by cyclicDFA template.
00043
00044 """
00045
00046 def __init__(
00047 self,
00048 recognizer, decisionNumber,
00049 eot, eof, min, max, accept, special, transition
00050 ):
00051
00052 self.recognizer = recognizer
00053
00054 self.decisionNumber = decisionNumber
00055 self.eot = eot
00056 self.eof = eof
00057 self.min = min
00058 self.max = max
00059 self.accept = accept
00060 self.special = special
00061 self.transition = transition
00062
00063
00064 def predict(self, input):
00065 """
00066 From the input stream, predict what alternative will succeed
00067 using this DFA (representing the covering regular approximation
00068 to the underlying CFL). Return an alternative number 1..n. Throw
00069 an exception upon error.
00070 """
00071 mark = input.mark()
00072 s = 0
00073 try:
00074 for _ in xrange(50000):
00075
00076
00077 specialState = self.special[s]
00078 if specialState >= 0:
00079
00080 s = self.specialStateTransition(specialState, input)
00081 if s == -1:
00082 self.noViableAlt(s, input)
00083 return 0
00084 input.consume()
00085 continue
00086
00087 if self.accept[s] >= 1:
00088
00089 return self.accept[s]
00090
00091
00092 c = input.LA(1)
00093
00094
00095
00096
00097 if c >= self.min[s] and c <= self.max[s]:
00098
00099 snext = self.transition[s][c-self.min[s]]
00100
00101
00102 if snext < 0:
00103
00104
00105
00106
00107
00108 if self.eot[s] >= 0:
00109
00110
00111 s = self.eot[s]
00112 input.consume()
00113
00114
00115
00116
00117
00118 continue
00119
00120
00121 self.noViableAlt(s, input)
00122 return 0
00123
00124 s = snext
00125 input.consume()
00126 continue
00127
00128 if self.eot[s] >= 0:
00129
00130
00131 s = self.eot[s]
00132 input.consume()
00133 continue
00134
00135
00136 if c == EOF and self.eof[s] >= 0:
00137
00138
00139 return self.accept[self.eof[s]]
00140
00141
00142 self.noViableAlt(s, input)
00143 return 0
00144
00145 else:
00146 raise RuntimeError("DFA bang!")
00147
00148 finally:
00149 input.rewind(mark)
00150
00151
00152 def noViableAlt(self, s, input):
00153 if self.recognizer._state.backtracking > 0:
00154 raise BacktrackingFailed
00155
00156 nvae = NoViableAltException(
00157 self.getDescription(),
00158 self.decisionNumber,
00159 s,
00160 input
00161 )
00162
00163 self.error(nvae)
00164 raise nvae
00165
00166
00167 def error(self, nvae):
00168 """A hook for debugging interface"""
00169 pass
00170
00171
00172 def specialStateTransition(self, s, input):
00173 return -1
00174
00175
00176 def getDescription(self):
00177 return "n/a"
00178
00179
00180
00181
00182
00183
00184 def unpack(cls, string):
00185 """@brief Unpack the runlength encoded table data.
00186
00187 Terence implemented packed table initializers, because Java has a
00188 size restriction on .class files and the lookup tables can grow
00189 pretty large. The generated JavaLexer.java of the Java.g example
00190 would be about 15MB with uncompressed array initializers.
00191
00192 Python does not have any size restrictions, but the compilation of
00193 such large source files seems to be pretty memory hungry. The memory
00194 consumption of the python process grew to >1.5GB when importing a
00195 15MB lexer, eating all my swap space and I was to impacient to see,
00196 if it could finish at all. With packed initializers that are unpacked
00197 at import time of the lexer module, everything works like a charm.
00198
00199 """
00200
00201 ret = []
00202 for i in range(len(string) / 2):
00203 (n, v) = ord(string[i*2]), ord(string[i*2+1])
00204
00205
00206 if v == 0xFFFF:
00207 v = -1
00208
00209 ret += [v] * n
00210
00211 return ret
00212
00213 unpack = classmethod(unpack)