omlish 0.0.0.dev56__py3-none-any.whl → 0.0.0.dev58__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. omlish/__about__.py +2 -2
  2. omlish/antlr/__init__.py +0 -0
  3. omlish/antlr/_runtime/BufferedTokenStream.py +305 -0
  4. omlish/antlr/_runtime/CommonTokenFactory.py +64 -0
  5. omlish/antlr/_runtime/CommonTokenStream.py +90 -0
  6. omlish/antlr/_runtime/FileStream.py +30 -0
  7. omlish/antlr/_runtime/InputStream.py +90 -0
  8. omlish/antlr/_runtime/IntervalSet.py +183 -0
  9. omlish/antlr/_runtime/LL1Analyzer.py +176 -0
  10. omlish/antlr/_runtime/Lexer.py +332 -0
  11. omlish/antlr/_runtime/ListTokenSource.py +147 -0
  12. omlish/antlr/_runtime/Parser.py +583 -0
  13. omlish/antlr/_runtime/ParserInterpreter.py +173 -0
  14. omlish/antlr/_runtime/ParserRuleContext.py +189 -0
  15. omlish/antlr/_runtime/PredictionContext.py +632 -0
  16. omlish/antlr/_runtime/Recognizer.py +150 -0
  17. omlish/antlr/_runtime/RuleContext.py +230 -0
  18. omlish/antlr/_runtime/StdinStream.py +14 -0
  19. omlish/antlr/_runtime/Token.py +158 -0
  20. omlish/antlr/_runtime/TokenStreamRewriter.py +258 -0
  21. omlish/antlr/_runtime/Utils.py +36 -0
  22. omlish/antlr/_runtime/__init__.py +24 -0
  23. omlish/antlr/_runtime/_pygrun.py +174 -0
  24. omlish/antlr/_runtime/atn/ATN.py +135 -0
  25. omlish/antlr/_runtime/atn/ATNConfig.py +162 -0
  26. omlish/antlr/_runtime/atn/ATNConfigSet.py +215 -0
  27. omlish/antlr/_runtime/atn/ATNDeserializationOptions.py +27 -0
  28. omlish/antlr/_runtime/atn/ATNDeserializer.py +449 -0
  29. omlish/antlr/_runtime/atn/ATNSimulator.py +50 -0
  30. omlish/antlr/_runtime/atn/ATNState.py +267 -0
  31. omlish/antlr/_runtime/atn/ATNType.py +20 -0
  32. omlish/antlr/_runtime/atn/LexerATNSimulator.py +573 -0
  33. omlish/antlr/_runtime/atn/LexerAction.py +301 -0
  34. omlish/antlr/_runtime/atn/LexerActionExecutor.py +146 -0
  35. omlish/antlr/_runtime/atn/ParserATNSimulator.py +1664 -0
  36. omlish/antlr/_runtime/atn/PredictionMode.py +502 -0
  37. omlish/antlr/_runtime/atn/SemanticContext.py +333 -0
  38. omlish/antlr/_runtime/atn/Transition.py +271 -0
  39. omlish/antlr/_runtime/atn/__init__.py +4 -0
  40. omlish/antlr/_runtime/dfa/DFA.py +136 -0
  41. omlish/antlr/_runtime/dfa/DFASerializer.py +76 -0
  42. omlish/antlr/_runtime/dfa/DFAState.py +129 -0
  43. omlish/antlr/_runtime/dfa/__init__.py +4 -0
  44. omlish/antlr/_runtime/error/DiagnosticErrorListener.py +110 -0
  45. omlish/antlr/_runtime/error/ErrorListener.py +75 -0
  46. omlish/antlr/_runtime/error/ErrorStrategy.py +712 -0
  47. omlish/antlr/_runtime/error/Errors.py +176 -0
  48. omlish/antlr/_runtime/error/__init__.py +4 -0
  49. omlish/antlr/_runtime/tree/Chunk.py +33 -0
  50. omlish/antlr/_runtime/tree/ParseTreeMatch.py +121 -0
  51. omlish/antlr/_runtime/tree/ParseTreePattern.py +75 -0
  52. omlish/antlr/_runtime/tree/ParseTreePatternMatcher.py +377 -0
  53. omlish/antlr/_runtime/tree/RuleTagToken.py +53 -0
  54. omlish/antlr/_runtime/tree/TokenTagToken.py +50 -0
  55. omlish/antlr/_runtime/tree/Tree.py +194 -0
  56. omlish/antlr/_runtime/tree/Trees.py +114 -0
  57. omlish/antlr/_runtime/tree/__init__.py +2 -0
  58. omlish/antlr/_runtime/xpath/XPath.py +272 -0
  59. omlish/antlr/_runtime/xpath/XPathLexer.py +98 -0
  60. omlish/antlr/_runtime/xpath/__init__.py +4 -0
  61. omlish/formats/json/cli.py +76 -7
  62. omlish/formats/props.py +6 -2
  63. {omlish-0.0.0.dev56.dist-info → omlish-0.0.0.dev58.dist-info}/METADATA +1 -1
  64. {omlish-0.0.0.dev56.dist-info → omlish-0.0.0.dev58.dist-info}/RECORD +68 -9
  65. {omlish-0.0.0.dev56.dist-info → omlish-0.0.0.dev58.dist-info}/LICENSE +0 -0
  66. {omlish-0.0.0.dev56.dist-info → omlish-0.0.0.dev58.dist-info}/WHEEL +0 -0
  67. {omlish-0.0.0.dev56.dist-info → omlish-0.0.0.dev58.dist-info}/entry_points.txt +0 -0
  68. {omlish-0.0.0.dev56.dist-info → omlish-0.0.0.dev58.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,583 @@
1
+ # type: ignore
2
+ # ruff: noqa
3
+ # flake8: noqa
4
+ #
5
+ # Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
6
+ # Use of this file is governed by the BSD 3-clause license that
7
+ # can be found in the LICENSE.txt file in the project root.
8
+ import sys
9
+ if sys.version_info[1] > 5:
10
+ from typing import TextIO
11
+ else:
12
+ from typing.io import TextIO
13
+ from .BufferedTokenStream import TokenStream
14
+ from .CommonTokenFactory import TokenFactory
15
+ from .error.ErrorStrategy import DefaultErrorStrategy
16
+ from .InputStream import InputStream
17
+ from .Recognizer import Recognizer
18
+ from .RuleContext import RuleContext
19
+ from .ParserRuleContext import ParserRuleContext
20
+ from .Token import Token
21
+ from .Lexer import Lexer
22
+ from .atn.ATNDeserializer import ATNDeserializer
23
+ from .atn.ATNDeserializationOptions import ATNDeserializationOptions
24
+ from .error.Errors import UnsupportedOperationException, RecognitionException
25
+ from .tree.ParseTreePatternMatcher import ParseTreePatternMatcher
26
+ from .tree.Tree import ParseTreeListener, TerminalNode, ErrorNode
27
+
28
+ class TraceListener(ParseTreeListener):
29
+ __slots__ = '_parser'
30
+
31
+ def __init__(self, parser):
32
+ self._parser = parser
33
+
34
+ def enterEveryRule(self, ctx):
35
+ print("enter " + self._parser.ruleNames[ctx.getRuleIndex()] + ", LT(1)=" + self._parser._input.LT(1).text, file=self._parser._output)
36
+
37
+ def visitTerminal(self, node):
38
+
39
+ print("consume " + str(node.symbol) + " rule " + self._parser.ruleNames[self._parser._ctx.getRuleIndex()], file=self._parser._output)
40
+
41
+ def visitErrorNode(self, node):
42
+ pass
43
+
44
+
45
+ def exitEveryRule(self, ctx):
46
+ print("exit " + self._parser.ruleNames[ctx.getRuleIndex()] + ", LT(1)=" + self._parser._input.LT(1).text, file=self._parser._output)
47
+
48
+
49
+ # self is all the parsing support code essentially; most of it is error recovery stuff.#
50
+ class Parser (Recognizer):
51
+ __slots__ = (
52
+ '_input', '_output', '_errHandler', '_precedenceStack', '_ctx',
53
+ 'buildParseTrees', '_tracer', '_parseListeners', '_syntaxErrors'
54
+
55
+ )
56
+ # self field maps from the serialized ATN string to the deserialized {@link ATN} with
57
+ # bypass alternatives.
58
+ #
59
+ # @see ATNDeserializationOptions#isGenerateRuleBypassTransitions()
60
+ #
61
+ bypassAltsAtnCache = dict()
62
+
63
+ def __init__(self, input:TokenStream, output:TextIO = sys.stdout):
64
+ super().__init__()
65
+ # The input stream.
66
+ self._input = None
67
+ self._output = output
68
+ # The error handling strategy for the parser. The default value is a new
69
+ # instance of {@link DefaultErrorStrategy}.
70
+ self._errHandler = DefaultErrorStrategy()
71
+ self._precedenceStack = list()
72
+ self._precedenceStack.append(0)
73
+ # The {@link ParserRuleContext} object for the currently executing rule.
74
+ # self is always non-null during the parsing process.
75
+ self._ctx = None
76
+ # Specifies whether or not the parser should construct a parse tree during
77
+ # the parsing process. The default value is {@code true}.
78
+ self.buildParseTrees = True
79
+ # When {@link #setTrace}{@code (true)} is called, a reference to the
80
+ # {@link TraceListener} is stored here so it can be easily removed in a
81
+ # later call to {@link #setTrace}{@code (false)}. The listener itself is
82
+ # implemented as a parser listener so self field is not directly used by
83
+ # other parser methods.
84
+ self._tracer = None
85
+ # The list of {@link ParseTreeListener} listeners registered to receive
86
+ # events during the parse.
87
+ self._parseListeners = None
88
+ # The number of syntax errors reported during parsing. self value is
89
+ # incremented each time {@link #notifyErrorListeners} is called.
90
+ self._syntaxErrors = 0
91
+ self.setInputStream(input)
92
+
93
+ # reset the parser's state#
94
+ def reset(self):
95
+ if self._input is not None:
96
+ self._input.seek(0)
97
+ self._errHandler.reset(self)
98
+ self._ctx = None
99
+ self._syntaxErrors = 0
100
+ self.setTrace(False)
101
+ self._precedenceStack = list()
102
+ self._precedenceStack.append(0)
103
+ if self._interp is not None:
104
+ self._interp.reset()
105
+
106
+ # Match current input symbol against {@code ttype}. If the symbol type
107
+ # matches, {@link ANTLRErrorStrategy#reportMatch} and {@link #consume} are
108
+ # called to complete the match process.
109
+ #
110
+ # <p>If the symbol type does not match,
111
+ # {@link ANTLRErrorStrategy#recoverInline} is called on the current error
112
+ # strategy to attempt recovery. If {@link #getBuildParseTree} is
113
+ # {@code true} and the token index of the symbol returned by
114
+ # {@link ANTLRErrorStrategy#recoverInline} is -1, the symbol is added to
115
+ # the parse tree by calling {@link ParserRuleContext#addErrorNode}.</p>
116
+ #
117
+ # @param ttype the token type to match
118
+ # @return the matched symbol
119
+ # @throws RecognitionException if the current input symbol did not match
120
+ # {@code ttype} and the error strategy could not recover from the
121
+ # mismatched symbol
122
+
123
+ def match(self, ttype:int):
124
+ t = self.getCurrentToken()
125
+ if t.type==ttype:
126
+ self._errHandler.reportMatch(self)
127
+ self.consume()
128
+ else:
129
+ t = self._errHandler.recoverInline(self)
130
+ if self.buildParseTrees and t.tokenIndex==-1:
131
+ # we must have conjured up a new token during single token insertion
132
+ # if it's not the current symbol
133
+ self._ctx.addErrorNode(t)
134
+ return t
135
+
136
+ # Match current input symbol as a wildcard. If the symbol type matches
137
+ # (i.e. has a value greater than 0), {@link ANTLRErrorStrategy#reportMatch}
138
+ # and {@link #consume} are called to complete the match process.
139
+ #
140
+ # <p>If the symbol type does not match,
141
+ # {@link ANTLRErrorStrategy#recoverInline} is called on the current error
142
+ # strategy to attempt recovery. If {@link #getBuildParseTree} is
143
+ # {@code true} and the token index of the symbol returned by
144
+ # {@link ANTLRErrorStrategy#recoverInline} is -1, the symbol is added to
145
+ # the parse tree by calling {@link ParserRuleContext#addErrorNode}.</p>
146
+ #
147
+ # @return the matched symbol
148
+ # @throws RecognitionException if the current input symbol did not match
149
+ # a wildcard and the error strategy could not recover from the mismatched
150
+ # symbol
151
+
152
+ def matchWildcard(self):
153
+ t = self.getCurrentToken()
154
+ if t.type > 0:
155
+ self._errHandler.reportMatch(self)
156
+ self.consume()
157
+ else:
158
+ t = self._errHandler.recoverInline(self)
159
+ if self.buildParseTrees and t.tokenIndex == -1:
160
+ # we must have conjured up a new token during single token insertion
161
+ # if it's not the current symbol
162
+ self._ctx.addErrorNode(t)
163
+
164
+ return t
165
+
166
+ def getParseListeners(self):
167
+ return list() if self._parseListeners is None else self._parseListeners
168
+
169
+ # Registers {@code listener} to receive events during the parsing process.
170
+ #
171
+ # <p>To support output-preserving grammar transformations (including but not
172
+ # limited to left-recursion removal, automated left-factoring, and
173
+ # optimized code generation), calls to listener methods during the parse
174
+ # may differ substantially from calls made by
175
+ # {@link ParseTreeWalker#DEFAULT} used after the parse is complete. In
176
+ # particular, rule entry and exit events may occur in a different order
177
+ # during the parse than after the parser. In addition, calls to certain
178
+ # rule entry methods may be omitted.</p>
179
+ #
180
+ # <p>With the following specific exceptions, calls to listener events are
181
+ # <em>deterministic</em>, i.e. for identical input the calls to listener
182
+ # methods will be the same.</p>
183
+ #
184
+ # <ul>
185
+ # <li>Alterations to the grammar used to generate code may change the
186
+ # behavior of the listener calls.</li>
187
+ # <li>Alterations to the command line options passed to ANTLR 4 when
188
+ # generating the parser may change the behavior of the listener calls.</li>
189
+ # <li>Changing the version of the ANTLR Tool used to generate the parser
190
+ # may change the behavior of the listener calls.</li>
191
+ # </ul>
192
+ #
193
+ # @param listener the listener to add
194
+ #
195
+ # @throws NullPointerException if {@code} listener is {@code null}
196
+ #
197
+ def addParseListener(self, listener:ParseTreeListener):
198
+ if listener is None:
199
+ raise ReferenceError("listener")
200
+ if self._parseListeners is None:
201
+ self._parseListeners = []
202
+ self._parseListeners.append(listener)
203
+
204
+ #
205
+ # Remove {@code listener} from the list of parse listeners.
206
+ #
207
+ # <p>If {@code listener} is {@code null} or has not been added as a parse
208
+ # listener, self method does nothing.</p>
209
+ # @param listener the listener to remove
210
+ #
211
+ def removeParseListener(self, listener:ParseTreeListener):
212
+ if self._parseListeners is not None:
213
+ self._parseListeners.remove(listener)
214
+ if len(self._parseListeners)==0:
215
+ self._parseListeners = None
216
+
217
+ # Remove all parse listeners.
218
+ def removeParseListeners(self):
219
+ self._parseListeners = None
220
+
221
+ # Notify any parse listeners of an enter rule event.
222
+ def triggerEnterRuleEvent(self):
223
+ if self._parseListeners is not None:
224
+ for listener in self._parseListeners:
225
+ listener.enterEveryRule(self._ctx)
226
+ self._ctx.enterRule(listener)
227
+
228
+ #
229
+ # Notify any parse listeners of an exit rule event.
230
+ #
231
+ # @see #addParseListener
232
+ #
233
+ def triggerExitRuleEvent(self):
234
+ if self._parseListeners is not None:
235
+ # reverse order walk of listeners
236
+ for listener in reversed(self._parseListeners):
237
+ self._ctx.exitRule(listener)
238
+ listener.exitEveryRule(self._ctx)
239
+
240
+
241
+ # Gets the number of syntax errors reported during parsing. This value is
242
+ # incremented each time {@link #notifyErrorListeners} is called.
243
+ #
244
+ # @see #notifyErrorListeners
245
+ #
246
+ def getNumberOfSyntaxErrors(self):
247
+ return self._syntaxErrors
248
+
249
+ def getTokenFactory(self):
250
+ return self._input.tokenSource._factory
251
+
252
+ # Tell our token source and error strategy about a new way to create tokens.#
253
+ def setTokenFactory(self, factory:TokenFactory):
254
+ self._input.tokenSource._factory = factory
255
+
256
+ # The ATN with bypass alternatives is expensive to create so we create it
257
+ # lazily.
258
+ #
259
+ # @throws UnsupportedOperationException if the current parser does not
260
+ # implement the {@link #getSerializedATN()} method.
261
+ #
262
+ def getATNWithBypassAlts(self):
263
+ serializedAtn = self.getSerializedATN()
264
+ if serializedAtn is None:
265
+ raise UnsupportedOperationException("The current parser does not support an ATN with bypass alternatives.")
266
+ result = self.bypassAltsAtnCache.get(serializedAtn, None)
267
+ if result is None:
268
+ deserializationOptions = ATNDeserializationOptions()
269
+ deserializationOptions.generateRuleBypassTransitions = True
270
+ result = ATNDeserializer(deserializationOptions).deserialize(serializedAtn)
271
+ self.bypassAltsAtnCache[serializedAtn] = result
272
+ return result
273
+
274
+ # The preferred method of getting a tree pattern. For example, here's a
275
+ # sample use:
276
+ #
277
+ # <pre>
278
+ # ParseTree t = parser.expr();
279
+ # ParseTreePattern p = parser.compileParseTreePattern("&lt;ID&gt;+0", MyParser.RULE_expr);
280
+ # ParseTreeMatch m = p.match(t);
281
+ # String id = m.get("ID");
282
+ # </pre>
283
+ #
284
+ def compileParseTreePattern(self, pattern:str, patternRuleIndex:int, lexer:Lexer = None):
285
+ if lexer is None:
286
+ if self.getTokenStream() is not None:
287
+ tokenSource = self.getTokenStream().tokenSource
288
+ if isinstance( tokenSource, Lexer ):
289
+ lexer = tokenSource
290
+ if lexer is None:
291
+ raise UnsupportedOperationException("Parser can't discover a lexer to use")
292
+
293
+ m = ParseTreePatternMatcher(lexer, self)
294
+ return m.compile(pattern, patternRuleIndex)
295
+
296
+
297
+ def getInputStream(self):
298
+ return self.getTokenStream()
299
+
300
+ def setInputStream(self, input:InputStream):
301
+ self.setTokenStream(input)
302
+
303
+ def getTokenStream(self):
304
+ return self._input
305
+
306
+ # Set the token stream and reset the parser.#
307
+ def setTokenStream(self, input:TokenStream):
308
+ self._input = None
309
+ self.reset()
310
+ self._input = input
311
+
312
+ # Match needs to return the current input symbol, which gets put
313
+ # into the label for the associated token ref; e.g., x=ID.
314
+ #
315
+ def getCurrentToken(self):
316
+ return self._input.LT(1)
317
+
318
+ def notifyErrorListeners(self, msg:str, offendingToken:Token = None, e:RecognitionException = None):
319
+ if offendingToken is None:
320
+ offendingToken = self.getCurrentToken()
321
+ self._syntaxErrors += 1
322
+ line = offendingToken.line
323
+ column = offendingToken.column
324
+ listener = self.getErrorListenerDispatch()
325
+ listener.syntaxError(self, offendingToken, line, column, msg, e)
326
+
327
+ #
328
+ # Consume and return the {@linkplain #getCurrentToken current symbol}.
329
+ #
330
+ # <p>E.g., given the following input with {@code A} being the current
331
+ # lookahead symbol, self function moves the cursor to {@code B} and returns
332
+ # {@code A}.</p>
333
+ #
334
+ # <pre>
335
+ # A B
336
+ # ^
337
+ # </pre>
338
+ #
339
+ # If the parser is not in error recovery mode, the consumed symbol is added
340
+ # to the parse tree using {@link ParserRuleContext#addChild(Token)}, and
341
+ # {@link ParseTreeListener#visitTerminal} is called on any parse listeners.
342
+ # If the parser <em>is</em> in error recovery mode, the consumed symbol is
343
+ # added to the parse tree using
344
+ # {@link ParserRuleContext#addErrorNode(Token)}, and
345
+ # {@link ParseTreeListener#visitErrorNode} is called on any parse
346
+ # listeners.
347
+ #
348
+ def consume(self):
349
+ o = self.getCurrentToken()
350
+ if o.type != Token.EOF:
351
+ self.getInputStream().consume()
352
+ hasListener = self._parseListeners is not None and len(self._parseListeners)>0
353
+ if self.buildParseTrees or hasListener:
354
+ if self._errHandler.inErrorRecoveryMode(self):
355
+ node = self._ctx.addErrorNode(o)
356
+ else:
357
+ node = self._ctx.addTokenNode(o)
358
+ if hasListener:
359
+ for listener in self._parseListeners:
360
+ if isinstance(node, ErrorNode):
361
+ listener.visitErrorNode(node)
362
+ elif isinstance(node, TerminalNode):
363
+ listener.visitTerminal(node)
364
+ return o
365
+
366
+ def addContextToParseTree(self):
367
+ # add current context to parent if we have a parent
368
+ if self._ctx.parentCtx is not None:
369
+ self._ctx.parentCtx.addChild(self._ctx)
370
+
371
+ # Always called by generated parsers upon entry to a rule. Access field
372
+ # {@link #_ctx} get the current context.
373
+ #
374
+ def enterRule(self, localctx:ParserRuleContext , state:int , ruleIndex:int):
375
+ self.state = state
376
+ self._ctx = localctx
377
+ self._ctx.start = self._input.LT(1)
378
+ if self.buildParseTrees:
379
+ self.addContextToParseTree()
380
+ if self._parseListeners is not None:
381
+ self.triggerEnterRuleEvent()
382
+
383
+ def exitRule(self):
384
+ self._ctx.stop = self._input.LT(-1)
385
+ # trigger event on _ctx, before it reverts to parent
386
+ if self._parseListeners is not None:
387
+ self.triggerExitRuleEvent()
388
+ self.state = self._ctx.invokingState
389
+ self._ctx = self._ctx.parentCtx
390
+
391
+ def enterOuterAlt(self, localctx:ParserRuleContext, altNum:int):
392
+ localctx.setAltNumber(altNum)
393
+ # if we have new localctx, make sure we replace existing ctx
394
+ # that is previous child of parse tree
395
+ if self.buildParseTrees and self._ctx != localctx:
396
+ if self._ctx.parentCtx is not None:
397
+ self._ctx.parentCtx.removeLastChild()
398
+ self._ctx.parentCtx.addChild(localctx)
399
+ self._ctx = localctx
400
+
401
+ # Get the precedence level for the top-most precedence rule.
402
+ #
403
+ # @return The precedence level for the top-most precedence rule, or -1 if
404
+ # the parser context is not nested within a precedence rule.
405
+ #
406
+ def getPrecedence(self):
407
+ if len(self._precedenceStack)==0:
408
+ return -1
409
+ else:
410
+ return self._precedenceStack[-1]
411
+
412
+ def enterRecursionRule(self, localctx:ParserRuleContext, state:int, ruleIndex:int, precedence:int):
413
+ self.state = state
414
+ self._precedenceStack.append(precedence)
415
+ self._ctx = localctx
416
+ self._ctx.start = self._input.LT(1)
417
+ if self._parseListeners is not None:
418
+ self.triggerEnterRuleEvent() # simulates rule entry for left-recursive rules
419
+
420
+ #
421
+ # Like {@link #enterRule} but for recursive rules.
422
+ #
423
+ def pushNewRecursionContext(self, localctx:ParserRuleContext, state:int, ruleIndex:int):
424
+ previous = self._ctx
425
+ previous.parentCtx = localctx
426
+ previous.invokingState = state
427
+ previous.stop = self._input.LT(-1)
428
+
429
+ self._ctx = localctx
430
+ self._ctx.start = previous.start
431
+ if self.buildParseTrees:
432
+ self._ctx.addChild(previous)
433
+
434
+ if self._parseListeners is not None:
435
+ self.triggerEnterRuleEvent() # simulates rule entry for left-recursive rules
436
+
437
+ def unrollRecursionContexts(self, parentCtx:ParserRuleContext):
438
+ self._precedenceStack.pop()
439
+ self._ctx.stop = self._input.LT(-1)
440
+ retCtx = self._ctx # save current ctx (return value)
441
+ # unroll so _ctx is as it was before call to recursive method
442
+ if self._parseListeners is not None:
443
+ while self._ctx is not parentCtx:
444
+ self.triggerExitRuleEvent()
445
+ self._ctx = self._ctx.parentCtx
446
+ else:
447
+ self._ctx = parentCtx
448
+
449
+ # hook into tree
450
+ retCtx.parentCtx = parentCtx
451
+
452
+ if self.buildParseTrees and parentCtx is not None:
453
+ # add return ctx into invoking rule's tree
454
+ parentCtx.addChild(retCtx)
455
+
456
+ def getInvokingContext(self, ruleIndex:int):
457
+ ctx = self._ctx
458
+ while ctx is not None:
459
+ if ctx.getRuleIndex() == ruleIndex:
460
+ return ctx
461
+ ctx = ctx.parentCtx
462
+ return None
463
+
464
+
465
+ def precpred(self, localctx:RuleContext , precedence:int):
466
+ return precedence >= self._precedenceStack[-1]
467
+
468
+ def inContext(self, context:str):
469
+ # TODO: useful in parser?
470
+ return False
471
+
472
+ #
473
+ # Checks whether or not {@code symbol} can follow the current state in the
474
+ # ATN. The behavior of self method is equivalent to the following, but is
475
+ # implemented such that the complete context-sensitive follow set does not
476
+ # need to be explicitly constructed.
477
+ #
478
+ # <pre>
479
+ # return getExpectedTokens().contains(symbol);
480
+ # </pre>
481
+ #
482
+ # @param symbol the symbol type to check
483
+ # @return {@code true} if {@code symbol} can follow the current state in
484
+ # the ATN, otherwise {@code false}.
485
+ #
486
+ def isExpectedToken(self, symbol:int):
487
+ atn = self._interp.atn
488
+ ctx = self._ctx
489
+ s = atn.states[self.state]
490
+ following = atn.nextTokens(s)
491
+ if symbol in following:
492
+ return True
493
+ if not Token.EPSILON in following:
494
+ return False
495
+
496
+ while ctx is not None and ctx.invokingState>=0 and Token.EPSILON in following:
497
+ invokingState = atn.states[ctx.invokingState]
498
+ rt = invokingState.transitions[0]
499
+ following = atn.nextTokens(rt.followState)
500
+ if symbol in following:
501
+ return True
502
+ ctx = ctx.parentCtx
503
+
504
+ if Token.EPSILON in following and symbol == Token.EOF:
505
+ return True
506
+ else:
507
+ return False
508
+
509
+ # Computes the set of input symbols which could follow the current parser
510
+ # state and context, as given by {@link #getState} and {@link #getContext},
511
+ # respectively.
512
+ #
513
+ # @see ATN#getExpectedTokens(int, RuleContext)
514
+ #
515
+ def getExpectedTokens(self):
516
+ return self._interp.atn.getExpectedTokens(self.state, self._ctx)
517
+
518
+ def getExpectedTokensWithinCurrentRule(self):
519
+ atn = self._interp.atn
520
+ s = atn.states[self.state]
521
+ return atn.nextTokens(s)
522
+
523
+ # Get a rule's index (i.e., {@code RULE_ruleName} field) or -1 if not found.#
524
+ def getRuleIndex(self, ruleName:str):
525
+ ruleIndex = self.getRuleIndexMap().get(ruleName, None)
526
+ if ruleIndex is not None:
527
+ return ruleIndex
528
+ else:
529
+ return -1
530
+
531
+ # Return List&lt;String&gt; of the rule names in your parser instance
532
+ # leading up to a call to the current rule. You could override if
533
+ # you want more details such as the file/line info of where
534
+ # in the ATN a rule is invoked.
535
+ #
536
+ # this is very useful for error messages.
537
+ #
538
+ def getRuleInvocationStack(self, p:RuleContext=None):
539
+ if p is None:
540
+ p = self._ctx
541
+ stack = list()
542
+ while p is not None:
543
+ # compute what follows who invoked us
544
+ ruleIndex = p.getRuleIndex()
545
+ if ruleIndex<0:
546
+ stack.append("n/a")
547
+ else:
548
+ stack.append(self.ruleNames[ruleIndex])
549
+ p = p.parentCtx
550
+ return stack
551
+
552
+ # For debugging and other purposes.#
553
+ def getDFAStrings(self):
554
+ return [ str(dfa) for dfa in self._interp.decisionToDFA]
555
+
556
+ # For debugging and other purposes.#
557
+ def dumpDFA(self):
558
+ seenOne = False
559
+ for i in range(0, len(self._interp.decisionToDFA)):
560
+ dfa = self._interp.decisionToDFA[i]
561
+ if len(dfa.states)>0:
562
+ if seenOne:
563
+ print(file=self._output)
564
+ print("Decision " + str(dfa.decision) + ":", file=self._output)
565
+ print(dfa.toString(self.literalNames, self.symbolicNames), end='', file=self._output)
566
+ seenOne = True
567
+
568
+
569
+ def getSourceName(self):
570
+ return self._input.sourceName
571
+
572
+ # During a parse is sometimes useful to listen in on the rule entry and exit
573
+ # events as well as token matches. self is for quick and dirty debugging.
574
+ #
575
+ def setTrace(self, trace:bool):
576
+ if not trace:
577
+ self.removeParseListener(self._tracer)
578
+ self._tracer = None
579
+ else:
580
+ if self._tracer is not None:
581
+ self.removeParseListener(self._tracer)
582
+ self._tracer = TraceListener(self)
583
+ self.addParseListener(self._tracer)