| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| from antlr4.dfa.DFA import DFA |
| from antlr4.BufferedTokenStream import TokenStream |
| from antlr4.Lexer import Lexer |
| from antlr4.Parser import Parser |
| from antlr4.ParserRuleContext import InterpreterRuleContext, ParserRuleContext |
| from antlr4.Token import Token |
| from antlr4.atn.ATN import ATN |
| from antlr4.atn.ATNState import StarLoopEntryState, ATNState, LoopEndState |
| from antlr4.atn.ParserATNSimulator import ParserATNSimulator |
| from antlr4.PredictionContext import PredictionContextCache |
| from antlr4.atn.Transition import Transition |
| from antlr4.error.Errors import RecognitionException, UnsupportedOperationException, FailedPredicateException |
|
|
|
|
| class ParserInterpreter(Parser): |
| __slots__ = ( |
| 'grammarFileName', 'atn', 'tokenNames', 'ruleNames', 'decisionToDFA', |
| 'sharedContextCache', '_parentContextStack', |
| 'pushRecursionContextStates' |
| ) |
|
|
| def __init__(self, grammarFileName:str, tokenNames:list, ruleNames:list, atn:ATN, input:TokenStream): |
| super().__init__(input) |
| self.grammarFileName = grammarFileName |
| self.atn = atn |
| self.tokenNames = tokenNames |
| self.ruleNames = ruleNames |
| self.decisionToDFA = [ DFA(state) for state in atn.decisionToState ] |
| self.sharedContextCache = PredictionContextCache() |
| self._parentContextStack = list() |
| |
| self.pushRecursionContextStates = set() |
| for state in atn.states: |
| if not isinstance(state, StarLoopEntryState): |
| continue |
| if state.isPrecedenceDecision: |
| self.pushRecursionContextStates.add(state.stateNumber) |
| |
| self._interp = ParserATNSimulator(self, atn, self.decisionToDFA, self.sharedContextCache) |
|
|
| |
| def parse(self, startRuleIndex:int): |
| startRuleStartState = self.atn.ruleToStartState[startRuleIndex] |
| rootContext = InterpreterRuleContext(None, ATNState.INVALID_STATE_NUMBER, startRuleIndex) |
| if startRuleStartState.isPrecedenceRule: |
| self.enterRecursionRule(rootContext, startRuleStartState.stateNumber, startRuleIndex, 0) |
| else: |
| self.enterRule(rootContext, startRuleStartState.stateNumber, startRuleIndex) |
| while True: |
| p = self.getATNState() |
| if p.stateType==ATNState.RULE_STOP : |
| |
| if len(self._ctx)==0: |
| if startRuleStartState.isPrecedenceRule: |
| result = self._ctx |
| parentContext = self._parentContextStack.pop() |
| self.unrollRecursionContexts(parentContext.a) |
| return result |
| else: |
| self.exitRule() |
| return rootContext |
| self.visitRuleStopState(p) |
|
|
| else: |
| try: |
| self.visitState(p) |
| except RecognitionException as e: |
| self.state = self.atn.ruleToStopState[p.ruleIndex].stateNumber |
| self._ctx.exception = e |
| self._errHandler.reportError(self, e) |
| self._errHandler.recover(self, e) |
|
|
| def enterRecursionRule(self, localctx:ParserRuleContext, state:int, ruleIndex:int, precedence:int): |
| self._parentContextStack.append((self._ctx, localctx.invokingState)) |
| super().enterRecursionRule(localctx, state, ruleIndex, precedence) |
|
|
| def getATNState(self): |
| return self.atn.states[self.state] |
|
|
| def visitState(self, p:ATNState): |
| edge = 0 |
| if len(p.transitions) > 1: |
| self._errHandler.sync(self) |
| edge = self._interp.adaptivePredict(self._input, p.decision, self._ctx) |
| else: |
| edge = 1 |
|
|
| transition = p.transitions[edge - 1] |
| tt = transition.serializationType |
| if tt==Transition.EPSILON: |
|
|
| if self.pushRecursionContextStates[p.stateNumber] and not isinstance(transition.target, LoopEndState): |
| t = self._parentContextStack[-1] |
| ctx = InterpreterRuleContext(t[0], t[1], self._ctx.ruleIndex) |
| self.pushNewRecursionContext(ctx, self.atn.ruleToStartState[p.ruleIndex].stateNumber, self._ctx.ruleIndex) |
|
|
| elif tt==Transition.ATOM: |
|
|
| self.match(transition.label) |
|
|
| elif tt in [ Transition.RANGE, Transition.SET, Transition.NOT_SET]: |
|
|
| if not transition.matches(self._input.LA(1), Token.MIN_USER_TOKEN_TYPE, Lexer.MAX_CHAR_VALUE): |
| self._errHandler.recoverInline(self) |
| self.matchWildcard() |
|
|
| elif tt==Transition.WILDCARD: |
|
|
| self.matchWildcard() |
|
|
| elif tt==Transition.RULE: |
|
|
| ruleStartState = transition.target |
| ruleIndex = ruleStartState.ruleIndex |
| ctx = InterpreterRuleContext(self._ctx, p.stateNumber, ruleIndex) |
| if ruleStartState.isPrecedenceRule: |
| self.enterRecursionRule(ctx, ruleStartState.stateNumber, ruleIndex, transition.precedence) |
| else: |
| self.enterRule(ctx, transition.target.stateNumber, ruleIndex) |
|
|
| elif tt==Transition.PREDICATE: |
|
|
| if not self.sempred(self._ctx, transition.ruleIndex, transition.predIndex): |
| raise FailedPredicateException(self) |
|
|
| elif tt==Transition.ACTION: |
|
|
| self.action(self._ctx, transition.ruleIndex, transition.actionIndex) |
|
|
| elif tt==Transition.PRECEDENCE: |
|
|
| if not self.precpred(self._ctx, transition.precedence): |
| msg = "precpred(_ctx, " + str(transition.precedence) + ")" |
| raise FailedPredicateException(self, msg) |
|
|
| else: |
| raise UnsupportedOperationException("Unrecognized ATN transition type.") |
|
|
| self.state = transition.target.stateNumber |
|
|
| def visitRuleStopState(self, p:ATNState): |
| ruleStartState = self.atn.ruleToStartState[p.ruleIndex] |
| if ruleStartState.isPrecedenceRule: |
| parentContext = self._parentContextStack.pop() |
| self.unrollRecursionContexts(parentContext.a) |
| self.state = parentContext[1] |
| else: |
| self.exitRule() |
|
|
| ruleTransition = self.atn.states[self.state].transitions[0] |
| self.state = ruleTransition.followState.stateNumber |
|
|