| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | 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 |
| |
|