# Generated from Glycan.g4 by ANTLR 4.9
# encoding: utf-8
from antlr4 import *
from io import StringIO
import sys
if sys.version_info[1] > 5:
	from typing import TextIO
else:
	from typing.io import TextIO


def serializedATN():
    with StringIO() as buf:
        buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\r")
        buf.write("Q\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\3\2\3\2\3\2\3\2\3\2")
        buf.write("\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3")
        buf.write("\2\3\2\3\2\3\2\5\2!\n\2\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3")
        buf.write("\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\5\3\65\n\3")
        buf.write("\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\5\4B\n\4")
        buf.write("\3\5\7\5E\n\5\f\5\16\5H\13\5\3\5\3\5\7\5L\n\5\f\5\16\5")
        buf.write("O\13\5\3\5\2\2\6\2\4\6\b\2\2\2W\2 \3\2\2\2\4\64\3\2\2")
        buf.write("\2\6A\3\2\2\2\bF\3\2\2\2\n\13\7\3\2\2\13\f\5\4\3\2\f\r")
        buf.write("\5\6\4\2\r\16\7\4\2\2\16\17\7\13\2\2\17\20\7\5\2\2\20")
        buf.write("!\3\2\2\2\21\22\7\3\2\2\22\23\5\4\3\2\23\24\5\6\4\2\24")
        buf.write("\25\7\5\2\2\25!\3\2\2\2\26\27\7\3\2\2\27\30\5\6\4\2\30")
        buf.write("\31\7\4\2\2\31\32\7\13\2\2\32\33\7\5\2\2\33!\3\2\2\2\34")
        buf.write("\35\7\3\2\2\35\36\5\6\4\2\36\37\7\5\2\2\37!\3\2\2\2 \n")
        buf.write("\3\2\2\2 \21\3\2\2\2 \26\3\2\2\2 \34\3\2\2\2!\3\3\2\2")
        buf.write("\2\"#\5\6\4\2#$\7\n\2\2$\65\3\2\2\2%&\5\6\4\2&\'\7\n\2")
        buf.write("\2\'(\5\4\3\2(\65\3\2\2\2)*\7\6\2\2*+\5\4\3\2+,\7\7\2")
        buf.write("\2,\65\3\2\2\2-.\5\6\4\2./\7\n\2\2/\60\7\6\2\2\60\61\5")
        buf.write("\4\3\2\61\62\7\7\2\2\62\63\5\4\3\2\63\65\3\2\2\2\64\"")
        buf.write("\3\2\2\2\64%\3\2\2\2\64)\3\2\2\2\64-\3\2\2\2\65\5\3\2")
        buf.write("\2\2\66\67\5\b\5\2\678\7\f\2\289\7\13\2\29B\3\2\2\2:;")
        buf.write("\5\b\5\2;<\7\13\2\2<B\3\2\2\2=>\5\b\5\2>?\7\f\2\2?B\3")
        buf.write("\2\2\2@B\5\b\5\2A\66\3\2\2\2A:\3\2\2\2A=\3\2\2\2A@\3\2")
        buf.write("\2\2B\7\3\2\2\2CE\7\t\2\2DC\3\2\2\2EH\3\2\2\2FD\3\2\2")
        buf.write("\2FG\3\2\2\2GI\3\2\2\2HF\3\2\2\2IM\7\b\2\2JL\7\t\2\2K")
        buf.write("J\3\2\2\2LO\3\2\2\2MK\3\2\2\2MN\3\2\2\2N\t\3\2\2\2OM\3")
        buf.write("\2\2\2\7 \64AFM")
        return buf.getvalue()


class GlycanParser ( Parser ):

    grammarFileName = "Glycan.g4"

    atn = ATNDeserializer().deserialize(serializedATN())

    decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]

    sharedContextCache = PredictionContextCache()

    literalNames = [ "<INVALID>", "'{'", "' '", "'}'", "'['", "']'" ]

    symbolicNames = [ "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "SAC", "MOD", "CON", "TYPE", 
                      "RING", "NUM" ]

    RULE_start = 0
    RULE_branch = 1
    RULE_glycan = 2
    RULE_deriv = 3

    ruleNames =  [ "start", "branch", "glycan", "deriv" ]

    EOF = Token.EOF
    T__0=1
    T__1=2
    T__2=3
    T__3=4
    T__4=5
    SAC=6
    MOD=7
    CON=8
    TYPE=9
    RING=10
    NUM=11

    def __init__(self, input:TokenStream, output:TextIO = sys.stdout):
        super().__init__(input, output)
        self.checkVersion("4.9")
        self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache)
        self._predicates = None




    class StartContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def branch(self):
            return self.getTypedRuleContext(GlycanParser.BranchContext,0)


        def glycan(self):
            return self.getTypedRuleContext(GlycanParser.GlycanContext,0)


        def TYPE(self):
            return self.getToken(GlycanParser.TYPE, 0)

        def getRuleIndex(self):
            return GlycanParser.RULE_start

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterStart" ):
                listener.enterStart(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitStart" ):
                listener.exitStart(self)




    def start(self):

        localctx = GlycanParser.StartContext(self, self._ctx, self.state)
        self.enterRule(localctx, 0, self.RULE_start)
        try:
            self.state = 30
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,0,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 8
                self.match(GlycanParser.T__0)
                self.state = 9
                self.branch()
                self.state = 10
                self.glycan()
                self.state = 11
                self.match(GlycanParser.T__1)
                self.state = 12
                self.match(GlycanParser.TYPE)
                self.state = 13
                self.match(GlycanParser.T__2)
                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 15
                self.match(GlycanParser.T__0)
                self.state = 16
                self.branch()
                self.state = 17
                self.glycan()
                self.state = 18
                self.match(GlycanParser.T__2)
                pass

            elif la_ == 3:
                self.enterOuterAlt(localctx, 3)
                self.state = 20
                self.match(GlycanParser.T__0)
                self.state = 21
                self.glycan()
                self.state = 22
                self.match(GlycanParser.T__1)
                self.state = 23
                self.match(GlycanParser.TYPE)
                self.state = 24
                self.match(GlycanParser.T__2)
                pass

            elif la_ == 4:
                self.enterOuterAlt(localctx, 4)
                self.state = 26
                self.match(GlycanParser.T__0)
                self.state = 27
                self.glycan()
                self.state = 28
                self.match(GlycanParser.T__2)
                pass


        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class BranchContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def glycan(self):
            return self.getTypedRuleContext(GlycanParser.GlycanContext,0)


        def CON(self):
            return self.getToken(GlycanParser.CON, 0)

        def branch(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(GlycanParser.BranchContext)
            else:
                return self.getTypedRuleContext(GlycanParser.BranchContext,i)


        def getRuleIndex(self):
            return GlycanParser.RULE_branch

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterBranch" ):
                listener.enterBranch(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitBranch" ):
                listener.exitBranch(self)




    def branch(self):

        localctx = GlycanParser.BranchContext(self, self._ctx, self.state)
        self.enterRule(localctx, 2, self.RULE_branch)
        try:
            self.state = 50
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,1,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 32
                self.glycan()
                self.state = 33
                self.match(GlycanParser.CON)
                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 35
                self.glycan()
                self.state = 36
                self.match(GlycanParser.CON)
                self.state = 37
                self.branch()
                pass

            elif la_ == 3:
                self.enterOuterAlt(localctx, 3)
                self.state = 39
                self.match(GlycanParser.T__3)
                self.state = 40
                self.branch()
                self.state = 41
                self.match(GlycanParser.T__4)
                pass

            elif la_ == 4:
                self.enterOuterAlt(localctx, 4)
                self.state = 43
                self.glycan()
                self.state = 44
                self.match(GlycanParser.CON)
                self.state = 45
                self.match(GlycanParser.T__3)
                self.state = 46
                self.branch()
                self.state = 47
                self.match(GlycanParser.T__4)
                self.state = 48
                self.branch()
                pass


        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class GlycanContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def deriv(self):
            return self.getTypedRuleContext(GlycanParser.DerivContext,0)


        def RING(self):
            return self.getToken(GlycanParser.RING, 0)

        def TYPE(self):
            return self.getToken(GlycanParser.TYPE, 0)

        def getRuleIndex(self):
            return GlycanParser.RULE_glycan

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterGlycan" ):
                listener.enterGlycan(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitGlycan" ):
                listener.exitGlycan(self)




    def glycan(self):

        localctx = GlycanParser.GlycanContext(self, self._ctx, self.state)
        self.enterRule(localctx, 4, self.RULE_glycan)
        try:
            self.state = 63
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,2,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 52
                self.deriv()
                self.state = 53
                self.match(GlycanParser.RING)
                self.state = 54
                self.match(GlycanParser.TYPE)
                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 56
                self.deriv()
                self.state = 57
                self.match(GlycanParser.TYPE)
                pass

            elif la_ == 3:
                self.enterOuterAlt(localctx, 3)
                self.state = 59
                self.deriv()
                self.state = 60
                self.match(GlycanParser.RING)
                pass

            elif la_ == 4:
                self.enterOuterAlt(localctx, 4)
                self.state = 62
                self.deriv()
                pass


        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class DerivContext(ParserRuleContext):

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser

        def SAC(self):
            return self.getToken(GlycanParser.SAC, 0)

        def MOD(self, i:int=None):
            if i is None:
                return self.getTokens(GlycanParser.MOD)
            else:
                return self.getToken(GlycanParser.MOD, i)

        def getRuleIndex(self):
            return GlycanParser.RULE_deriv

        def enterRule(self, listener:ParseTreeListener):
            if hasattr( listener, "enterDeriv" ):
                listener.enterDeriv(self)

        def exitRule(self, listener:ParseTreeListener):
            if hasattr( listener, "exitDeriv" ):
                listener.exitDeriv(self)




    def deriv(self):

        localctx = GlycanParser.DerivContext(self, self._ctx, self.state)
        self.enterRule(localctx, 6, self.RULE_deriv)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 68
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while _la==GlycanParser.MOD:
                self.state = 65
                self.match(GlycanParser.MOD)
                self.state = 70
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 71
            self.match(GlycanParser.SAC)
            self.state = 75
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while _la==GlycanParser.MOD:
                self.state = 72
                self.match(GlycanParser.MOD)
                self.state = 77
                self._errHandler.sync(self)
                _la = self._input.LA(1)

        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx





