# Generated from /home/mario/Documents/PYTHON/chessEngines/parser/gen/pgn.g4 by ANTLR 4.9.2
# 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\24")
        buf.write("\u00ac\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
        buf.write("\4\b\t\b\4\t\t\t\3\2\3\2\3\2\3\2\7\2\27\n\2\f\2\16\2\32")
        buf.write("\13\2\3\2\3\2\3\2\3\3\3\3\3\3\3\3\7\3#\n\3\f\3\16\3&\13")
        buf.write("\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\6\4/\n\4\r\4\16\4\60\3")
        buf.write("\4\7\4\64\n\4\f\4\16\4\67\13\4\3\4\3\4\3\4\3\4\3\5\3\5")
        buf.write("\3\5\3\5\3\6\3\6\5\6C\n\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7")
        buf.write("\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3")
        buf.write("\7\3\7\3\7\3\7\3\7\3\7\3\7\5\7`\n\7\3\7\5\7c\n\7\3\7\7")
        buf.write("\7f\n\7\f\7\16\7i\13\7\3\7\3\7\3\7\5\7n\n\7\3\7\3\7\3")
        buf.write("\b\3\b\3\b\3\b\7\bv\n\b\f\b\16\by\13\b\3\b\3\b\3\b\6\b")
        buf.write("~\n\b\r\b\16\b\177\3\b\3\b\3\b\5\b\u0085\n\b\3\b\3\b\3")
        buf.write("\b\6\b\u008a\n\b\r\b\16\b\u008b\3\b\7\b\u008f\n\b\f\b")
        buf.write("\16\b\u0092\13\b\3\b\3\b\3\b\5\b\u0097\n\b\3\b\3\b\3\t")
        buf.write("\3\t\7\t\u009d\n\t\f\t\16\t\u00a0\13\t\3\t\3\t\7\t\u00a4")
        buf.write("\n\t\f\t\16\t\u00a7\13\t\3\t\5\t\u00aa\n\t\3\t\b\65gw")
        buf.write("\u0090\u009e\u00a5\2\n\2\4\6\b\n\f\16\20\2\b\3\2\3\3\3")
        buf.write("\2\5\5\3\2\24\24\3\2\r\16\3\2\n\13\4\2\16\16\22\22\2\u00bb")
        buf.write("\2\22\3\2\2\2\4\36\3\2\2\2\6*\3\2\2\2\b<\3\2\2\2\n@\3")
        buf.write("\2\2\2\fF\3\2\2\2\16q\3\2\2\2\20\u009e\3\2\2\2\22\23\b")
        buf.write("\2\1\2\23\30\7\3\2\2\24\25\n\2\2\2\25\27\b\2\1\2\26\24")
        buf.write("\3\2\2\2\27\32\3\2\2\2\30\26\3\2\2\2\30\31\3\2\2\2\31")
        buf.write("\33\3\2\2\2\32\30\3\2\2\2\33\34\7\3\2\2\34\35\b\2\1\2")
        buf.write("\35\3\3\2\2\2\36\37\b\3\1\2\37$\7\4\2\2 !\n\3\2\2!#\b")
        buf.write("\3\1\2\" \3\2\2\2#&\3\2\2\2$\"\3\2\2\2$%\3\2\2\2%\'\3")
        buf.write("\2\2\2&$\3\2\2\2\'(\7\5\2\2()\b\3\1\2)\5\3\2\2\2*+\b\4")
        buf.write("\1\2+.\7\6\2\2,-\n\4\2\2-/\b\4\1\2.,\3\2\2\2/\60\3\2\2")
        buf.write("\2\60.\3\2\2\2\60\61\3\2\2\2\61\65\3\2\2\2\62\64\7\24")
        buf.write("\2\2\63\62\3\2\2\2\64\67\3\2\2\2\65\66\3\2\2\2\65\63\3")
        buf.write("\2\2\2\668\3\2\2\2\67\65\3\2\2\289\5\2\2\29:\b\4\1\2:")
        buf.write(";\7\7\2\2;\7\3\2\2\2<=\7\r\2\2=>\7\16\2\2>?\b\5\1\2?\t")
        buf.write("\3\2\2\2@B\7\17\2\2AC\t\5\2\2BA\3\2\2\2BC\3\2\2\2CD\3")
        buf.write("\2\2\2DE\b\6\1\2E\13\3\2\2\2F_\b\7\1\2GH\5\b\5\2HI\b\7")
        buf.write("\1\2I`\3\2\2\2JK\7\r\2\2KL\7\b\2\2LM\5\b\5\2MN\b\7\1\2")
        buf.write("N`\3\2\2\2OP\5\n\6\2PQ\7\b\2\2QR\5\b\5\2RS\b\7\1\2S`\3")
        buf.write("\2\2\2TU\5\n\6\2UV\5\b\5\2VW\b\7\1\2W`\3\2\2\2XY\5\b\5")
        buf.write("\2YZ\7\t\2\2Z[\5\n\6\2[\\\b\7\1\2\\`\3\2\2\2]^\t\6\2\2")
        buf.write("^`\b\7\1\2_G\3\2\2\2_J\3\2\2\2_O\3\2\2\2_T\3\2\2\2_X\3")
        buf.write("\2\2\2_]\3\2\2\2`b\3\2\2\2ac\7\20\2\2ba\3\2\2\2bc\3\2")
        buf.write("\2\2cg\3\2\2\2df\7\24\2\2ed\3\2\2\2fi\3\2\2\2gh\3\2\2")
        buf.write("\2ge\3\2\2\2hm\3\2\2\2ig\3\2\2\2jk\5\4\3\2kl\b\7\1\2l")
        buf.write("n\3\2\2\2mj\3\2\2\2mn\3\2\2\2no\3\2\2\2op\b\7\1\2p\r\3")
        buf.write("\2\2\2qr\b\b\1\2rs\t\7\2\2sw\7\f\2\2tv\7\24\2\2ut\3\2")
        buf.write("\2\2vy\3\2\2\2wx\3\2\2\2wu\3\2\2\2x\u0096\3\2\2\2yw\3")
        buf.write("\2\2\2z{\5\f\7\2{\u0084\b\b\1\2|~\7\24\2\2}|\3\2\2\2~")
        buf.write("\177\3\2\2\2\177}\3\2\2\2\177\u0080\3\2\2\2\u0080\u0081")
        buf.write("\3\2\2\2\u0081\u0082\5\f\7\2\u0082\u0083\b\b\1\2\u0083")
        buf.write("\u0085\3\2\2\2\u0084}\3\2\2\2\u0084\u0085\3\2\2\2\u0085")
        buf.write("\u0086\3\2\2\2\u0086\u0087\b\b\1\2\u0087\u0097\3\2\2\2")
        buf.write("\u0088\u008a\7\f\2\2\u0089\u0088\3\2\2\2\u008a\u008b\3")
        buf.write("\2\2\2\u008b\u0089\3\2\2\2\u008b\u008c\3\2\2\2\u008c\u0090")
        buf.write("\3\2\2\2\u008d\u008f\7\24\2\2\u008e\u008d\3\2\2\2\u008f")
        buf.write("\u0092\3\2\2\2\u0090\u0091\3\2\2\2\u0090\u008e\3\2\2\2")
        buf.write("\u0091\u0093\3\2\2\2\u0092\u0090\3\2\2\2\u0093\u0094\5")
        buf.write("\f\7\2\u0094\u0095\b\b\1\2\u0095\u0097\3\2\2\2\u0096z")
        buf.write("\3\2\2\2\u0096\u0089\3\2\2\2\u0097\u0098\3\2\2\2\u0098")
        buf.write("\u0099\b\b\1\2\u0099\17\3\2\2\2\u009a\u009d\5\6\4\2\u009b")
        buf.write("\u009d\7\24\2\2\u009c\u009a\3\2\2\2\u009c\u009b\3\2\2")
        buf.write("\2\u009d\u00a0\3\2\2\2\u009e\u009f\3\2\2\2\u009e\u009c")
        buf.write("\3\2\2\2\u009f\u00a5\3\2\2\2\u00a0\u009e\3\2\2\2\u00a1")
        buf.write("\u00a4\5\16\b\2\u00a2\u00a4\7\24\2\2\u00a3\u00a1\3\2\2")
        buf.write("\2\u00a3\u00a2\3\2\2\2\u00a4\u00a7\3\2\2\2\u00a5\u00a6")
        buf.write("\3\2\2\2\u00a5\u00a3\3\2\2\2\u00a6\u00a9\3\2\2\2\u00a7")
        buf.write("\u00a5\3\2\2\2\u00a8\u00aa\7\21\2\2\u00a9\u00a8\3\2\2")
        buf.write("\2\u00a9\u00aa\3\2\2\2\u00aa\21\3\2\2\2\26\30$\60\65B")
        buf.write("_bgmw\177\u0084\u008b\u0090\u0096\u009c\u009e\u00a3\u00a5")
        buf.write("\u00a9")
        return buf.getvalue()


class pgnParser ( Parser ):

    grammarFileName = "pgn.g4"

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

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

    sharedContextCache = PredictionContextCache()

    literalNames = [ "<INVALID>", "'\"'", "'{'", "'}'", "'['", "']'", "'x'", 
                     "'='", "'O-O'", "'O-O-O'", "'.'" ]

    symbolicNames = [ "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "<INVALID>", "FILE", "RANK", 
                      "PIECE", "GLYPH", "RESULT", "INT", "CHAR", "WS" ]

    RULE_string = 0
    RULE_comment = 1
    RULE_tag = 2
    RULE_square = 3
    RULE_piece = 4
    RULE_halfMove = 5
    RULE_fullMove = 6
    RULE_game = 7

    ruleNames =  [ "string", "comment", "tag", "square", "piece", "halfMove", 
                   "fullMove", "game" ]

    EOF = Token.EOF
    T__0=1
    T__1=2
    T__2=3
    T__3=4
    T__4=5
    T__5=6
    T__6=7
    T__7=8
    T__8=9
    T__9=10
    FILE=11
    RANK=12
    PIECE=13
    GLYPH=14
    RESULT=15
    INT=16
    CHAR=17
    WS=18

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



    tags = {}
    moves = []



    class StringContext(ParserRuleContext):
        __slots__ = 'parser'

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


        def getRuleIndex(self):
            return pgnParser.RULE_string

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

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

        def accept(self, visitor:ParseTreeVisitor):
            if hasattr( visitor, "visitString" ):
                return visitor.visitString(self)
            else:
                return visitor.visitChildren(self)




    def string(self):

        localctx = pgnParser.StringContext(self, self._ctx, self.state)
        self.enterRule(localctx, 0, self.RULE_string)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)

            arr = []

            self.state = 17
            self.match(pgnParser.T__0)
            self.state = 22
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << pgnParser.T__1) | (1 << pgnParser.T__2) | (1 << pgnParser.T__3) | (1 << pgnParser.T__4) | (1 << pgnParser.T__5) | (1 << pgnParser.T__6) | (1 << pgnParser.T__7) | (1 << pgnParser.T__8) | (1 << pgnParser.T__9) | (1 << pgnParser.FILE) | (1 << pgnParser.RANK) | (1 << pgnParser.PIECE) | (1 << pgnParser.GLYPH) | (1 << pgnParser.RESULT) | (1 << pgnParser.INT) | (1 << pgnParser.CHAR) | (1 << pgnParser.WS))) != 0):
                self.state = 18
                localctx.c = self._input.LT(1)
                _la = self._input.LA(1)
                if _la <= 0 or _la==pgnParser.T__0:
                    localctx.c = self._errHandler.recoverInline(self)
                else:
                    self._errHandler.reportMatch(self)
                    self.consume()

                arr.append((None if localctx.c is None else localctx.c.text))

                self.state = 24
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 25
            self.match(pgnParser.T__0)

            localctx.txt = ''.join(arr)

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


    class CommentContext(ParserRuleContext):
        __slots__ = 'parser'

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


        def getRuleIndex(self):
            return pgnParser.RULE_comment

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

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

        def accept(self, visitor:ParseTreeVisitor):
            if hasattr( visitor, "visitComment" ):
                return visitor.visitComment(self)
            else:
                return visitor.visitChildren(self)




    def comment(self):

        localctx = pgnParser.CommentContext(self, self._ctx, self.state)
        self.enterRule(localctx, 2, self.RULE_comment)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)

            arr = []

            self.state = 29
            self.match(pgnParser.T__1)
            self.state = 34
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << pgnParser.T__0) | (1 << pgnParser.T__1) | (1 << pgnParser.T__3) | (1 << pgnParser.T__4) | (1 << pgnParser.T__5) | (1 << pgnParser.T__6) | (1 << pgnParser.T__7) | (1 << pgnParser.T__8) | (1 << pgnParser.T__9) | (1 << pgnParser.FILE) | (1 << pgnParser.RANK) | (1 << pgnParser.PIECE) | (1 << pgnParser.GLYPH) | (1 << pgnParser.RESULT) | (1 << pgnParser.INT) | (1 << pgnParser.CHAR) | (1 << pgnParser.WS))) != 0):
                self.state = 30
                localctx.c = self._input.LT(1)
                _la = self._input.LA(1)
                if _la <= 0 or _la==pgnParser.T__2:
                    localctx.c = self._errHandler.recoverInline(self)
                else:
                    self._errHandler.reportMatch(self)
                    self.consume()

                arr.append((None if localctx.c is None else localctx.c.text))

                self.state = 36
                self._errHandler.sync(self)
                _la = self._input.LA(1)

            self.state = 37
            self.match(pgnParser.T__2)

            localctx.txt = ''.join(arr)

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


    class TagContext(ParserRuleContext):
        __slots__ = 'parser'

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser
            self.a = None # Token
            self.s = None # StringContext

        def string(self):
            return self.getTypedRuleContext(pgnParser.StringContext,0)


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

        def getRuleIndex(self):
            return pgnParser.RULE_tag

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

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

        def accept(self, visitor:ParseTreeVisitor):
            if hasattr( visitor, "visitTag" ):
                return visitor.visitTag(self)
            else:
                return visitor.visitChildren(self)




    def tag(self):

        localctx = pgnParser.TagContext(self, self._ctx, self.state)
        self.enterRule(localctx, 4, self.RULE_tag)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)

            arr = []
            key = ''

            self.state = 41
            self.match(pgnParser.T__3)
            self.state = 44 
            self._errHandler.sync(self)
            _alt = 1
            while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
                if _alt == 1:
                    self.state = 42
                    localctx.a = self._input.LT(1)
                    _la = self._input.LA(1)
                    if _la <= 0 or _la==pgnParser.WS:
                        localctx.a = self._errHandler.recoverInline(self)
                    else:
                        self._errHandler.reportMatch(self)
                        self.consume()

                    arr.append((None if localctx.a is None else localctx.a.text))


                else:
                    raise NoViableAltException(self)
                self.state = 46 
                self._errHandler.sync(self)
                _alt = self._interp.adaptivePredict(self._input,2,self._ctx)

            self.state = 51
            self._errHandler.sync(self)
            _alt = self._interp.adaptivePredict(self._input,3,self._ctx)
            while _alt!=1 and _alt!=ATN.INVALID_ALT_NUMBER:
                if _alt==1+1:
                    self.state = 48
                    self.match(pgnParser.WS) 
                self.state = 53
                self._errHandler.sync(self)
                _alt = self._interp.adaptivePredict(self._input,3,self._ctx)

            self.state = 54
            localctx.s = self.string()

            key = ''.join(arr)
            val = (None if localctx.s is None else self._input.getText(localctx.s.start,localctx.s.stop))[1:-1]
            self.tags[key] = val;

            self.state = 56
            self.match(pgnParser.T__4)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx


    class SquareContext(ParserRuleContext):
        __slots__ = 'parser'

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser
            self.txt = None
            self.f = None # Token
            self.r = None # Token

        def FILE(self):
            return self.getToken(pgnParser.FILE, 0)

        def RANK(self):
            return self.getToken(pgnParser.RANK, 0)

        def getRuleIndex(self):
            return pgnParser.RULE_square

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

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

        def accept(self, visitor:ParseTreeVisitor):
            if hasattr( visitor, "visitSquare" ):
                return visitor.visitSquare(self)
            else:
                return visitor.visitChildren(self)




    def square(self):

        localctx = pgnParser.SquareContext(self, self._ctx, self.state)
        self.enterRule(localctx, 6, self.RULE_square)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 58
            localctx.f = self.match(pgnParser.FILE)
            self.state = 59
            localctx.r = self.match(pgnParser.RANK)

            localctx.txt = (None if localctx.f is None else localctx.f.text) + (None if localctx.r is None else localctx.r.text)

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


    class PieceContext(ParserRuleContext):
        __slots__ = 'parser'

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser
            self.txt = None
            self.p = None # Token
            self.x = None # Token

        def PIECE(self):
            return self.getToken(pgnParser.PIECE, 0)

        def FILE(self):
            return self.getToken(pgnParser.FILE, 0)

        def RANK(self):
            return self.getToken(pgnParser.RANK, 0)

        def getRuleIndex(self):
            return pgnParser.RULE_piece

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

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

        def accept(self, visitor:ParseTreeVisitor):
            if hasattr( visitor, "visitPiece" ):
                return visitor.visitPiece(self)
            else:
                return visitor.visitChildren(self)




    def piece(self):

        localctx = pgnParser.PieceContext(self, self._ctx, self.state)
        self.enterRule(localctx, 8, self.RULE_piece)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 62
            localctx.p = self.match(pgnParser.PIECE)
            self.state = 64
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,4,self._ctx)
            if la_ == 1:
                self.state = 63
                localctx.x = self._input.LT(1)
                _la = self._input.LA(1)
                if not(_la==pgnParser.FILE or _la==pgnParser.RANK):
                    localctx.x = self._errHandler.recoverInline(self)
                else:
                    self._errHandler.reportMatch(self)
                    self.consume()



            localctx.txt = (None if localctx.p is None else localctx.p.text)
            if localctx.x is not None:
                localctx.txt += (None if localctx.x is None else localctx.x.text)

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


    class HalfMoveContext(ParserRuleContext):
        __slots__ = 'parser'

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser
            self.props = None
            self.s = None # SquareContext
            self.f = None # Token
            self.p = None # PieceContext
            self.x = None # Token
            self.g = None # Token
            self.c = None # CommentContext

        def square(self):
            return self.getTypedRuleContext(pgnParser.SquareContext,0)


        def FILE(self):
            return self.getToken(pgnParser.FILE, 0)

        def piece(self):
            return self.getTypedRuleContext(pgnParser.PieceContext,0)


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

        def GLYPH(self):
            return self.getToken(pgnParser.GLYPH, 0)

        def comment(self):
            return self.getTypedRuleContext(pgnParser.CommentContext,0)


        def getRuleIndex(self):
            return pgnParser.RULE_halfMove

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

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

        def accept(self, visitor:ParseTreeVisitor):
            if hasattr( visitor, "visitHalfMove" ):
                return visitor.visitHalfMove(self)
            else:
                return visitor.visitChildren(self)




    def halfMove(self):

        localctx = pgnParser.HalfMoveContext(self, self._ctx, self.state)
        self.enterRule(localctx, 10, self.RULE_halfMove)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)

            localctx.props = {
                'move': None,
                'glyph': None,
                'comment': None
            }

            self.state = 93
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,5,self._ctx)
            if la_ == 1:
                self.state = 69
                localctx.s = self.square()

                localctx.props['move'] = localctx.s.txt

                pass

            elif la_ == 2:
                self.state = 72
                localctx.f = self.match(pgnParser.FILE)
                self.state = 73
                self.match(pgnParser.T__5)
                self.state = 74
                localctx.s = self.square()

                localctx.props['move'] = (None if localctx.f is None else localctx.f.text) + 'x' + localctx.s.txt

                pass

            elif la_ == 3:
                self.state = 77
                localctx.p = self.piece()
                self.state = 78
                self.match(pgnParser.T__5)
                self.state = 79
                localctx.s = self.square()

                localctx.props['move'] = localctx.p.txt + 'x' + localctx.s.txt

                pass

            elif la_ == 4:
                self.state = 82
                localctx.p = self.piece()
                self.state = 83
                localctx.s = self.square()

                localctx.props['move'] = localctx.p.txt + localctx.s.txt

                pass

            elif la_ == 5:
                self.state = 86
                localctx.s = self.square()
                self.state = 87
                self.match(pgnParser.T__6)
                self.state = 88
                localctx.p = self.piece()

                localctx.props['move'] = localctx.s.txt + '=' + localctx.p.txt

                pass

            elif la_ == 6:
                self.state = 91
                localctx.x = self._input.LT(1)
                _la = self._input.LA(1)
                if not(_la==pgnParser.T__7 or _la==pgnParser.T__8):
                    localctx.x = self._errHandler.recoverInline(self)
                else:
                    self._errHandler.reportMatch(self)
                    self.consume()

                localctx.props['move'] = (None if localctx.x is None else localctx.x.text)

                pass


            self.state = 96
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if _la==pgnParser.GLYPH:
                self.state = 95
                localctx.g = self.match(pgnParser.GLYPH)


            self.state = 101
            self._errHandler.sync(self)
            _alt = self._interp.adaptivePredict(self._input,7,self._ctx)
            while _alt!=1 and _alt!=ATN.INVALID_ALT_NUMBER:
                if _alt==1+1:
                    self.state = 98
                    self.match(pgnParser.WS) 
                self.state = 103
                self._errHandler.sync(self)
                _alt = self._interp.adaptivePredict(self._input,7,self._ctx)

            self.state = 107
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if _la==pgnParser.T__1:
                self.state = 104
                localctx.c = self.comment()

                localctx.props['comment'] = localctx.c.txt




            localctx.props['glyph'] = None if (localctx.g is None) else (None if localctx.g is None else localctx.g.text)

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


    class FullMoveContext(ParserRuleContext):
        __slots__ = 'parser'

        def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
            super().__init__(parent, invokingState)
            self.parser = parser
            self.h1 = None # HalfMoveContext
            self.h2 = None # HalfMoveContext
            self.h = None # HalfMoveContext

        def INT(self):
            return self.getToken(pgnParser.INT, 0)

        def RANK(self):
            return self.getToken(pgnParser.RANK, 0)

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

        def halfMove(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(pgnParser.HalfMoveContext)
            else:
                return self.getTypedRuleContext(pgnParser.HalfMoveContext,i)


        def getRuleIndex(self):
            return pgnParser.RULE_fullMove

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

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

        def accept(self, visitor:ParseTreeVisitor):
            if hasattr( visitor, "visitFullMove" ):
                return visitor.visitFullMove(self)
            else:
                return visitor.visitChildren(self)




    def fullMove(self):

        localctx = pgnParser.FullMoveContext(self, self._ctx, self.state)
        self.enterRule(localctx, 12, self.RULE_fullMove)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)

            move = []

            self.state = 112
            _la = self._input.LA(1)
            if not(_la==pgnParser.RANK or _la==pgnParser.INT):
                self._errHandler.recoverInline(self)
            else:
                self._errHandler.reportMatch(self)
                self.consume()
            self.state = 113
            self.match(pgnParser.T__9)
            self.state = 117
            self._errHandler.sync(self)
            _alt = self._interp.adaptivePredict(self._input,9,self._ctx)
            while _alt!=1 and _alt!=ATN.INVALID_ALT_NUMBER:
                if _alt==1+1:
                    self.state = 114
                    self.match(pgnParser.WS) 
                self.state = 119
                self._errHandler.sync(self)
                _alt = self._interp.adaptivePredict(self._input,9,self._ctx)

            self.state = 148
            self._errHandler.sync(self)
            token = self._input.LA(1)
            if token in [pgnParser.T__7, pgnParser.T__8, pgnParser.FILE, pgnParser.PIECE]:
                self.state = 120
                localctx.h1 = self.halfMove()

                move.append(localctx.h1.props)

                self.state = 130
                self._errHandler.sync(self)
                la_ = self._interp.adaptivePredict(self._input,11,self._ctx)
                if la_ == 1:
                    self.state = 123 
                    self._errHandler.sync(self)
                    _la = self._input.LA(1)
                    while True:
                        self.state = 122
                        self.match(pgnParser.WS)
                        self.state = 125 
                        self._errHandler.sync(self)
                        _la = self._input.LA(1)
                        if not (_la==pgnParser.WS):
                            break

                    self.state = 127
                    localctx.h2 = self.halfMove()

                    move.append(localctx.h2.props)




                if len(move) < 2:
                    move.append({
                        'move': None,
                        'glyph': None,
                        'comment': None
                    })

                pass
            elif token in [pgnParser.T__9]:
                self.state = 135 
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                while True:
                    self.state = 134
                    self.match(pgnParser.T__9)
                    self.state = 137 
                    self._errHandler.sync(self)
                    _la = self._input.LA(1)
                    if not (_la==pgnParser.T__9):
                        break

                self.state = 142
                self._errHandler.sync(self)
                _alt = self._interp.adaptivePredict(self._input,13,self._ctx)
                while _alt!=1 and _alt!=ATN.INVALID_ALT_NUMBER:
                    if _alt==1+1:
                        self.state = 139
                        self.match(pgnParser.WS) 
                    self.state = 144
                    self._errHandler.sync(self)
                    _alt = self._interp.adaptivePredict(self._input,13,self._ctx)

                self.state = 145
                localctx.h = self.halfMove()

                move.append({
                    'move': None,
                    'glyph': None,
                    'comment': None
                })
                move.append(localctx.h.props)

                pass
            else:
                raise NoViableAltException(self)


            self.moves.append(move)

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


    class GameContext(ParserRuleContext):
        __slots__ = 'parser'

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

        def tag(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(pgnParser.TagContext)
            else:
                return self.getTypedRuleContext(pgnParser.TagContext,i)


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

        def fullMove(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(pgnParser.FullMoveContext)
            else:
                return self.getTypedRuleContext(pgnParser.FullMoveContext,i)


        def RESULT(self):
            return self.getToken(pgnParser.RESULT, 0)

        def getRuleIndex(self):
            return pgnParser.RULE_game

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

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

        def accept(self, visitor:ParseTreeVisitor):
            if hasattr( visitor, "visitGame" ):
                return visitor.visitGame(self)
            else:
                return visitor.visitChildren(self)




    def game(self):

        localctx = pgnParser.GameContext(self, self._ctx, self.state)
        self.enterRule(localctx, 14, self.RULE_game)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 156
            self._errHandler.sync(self)
            _alt = self._interp.adaptivePredict(self._input,16,self._ctx)
            while _alt!=1 and _alt!=ATN.INVALID_ALT_NUMBER:
                if _alt==1+1:
                    self.state = 154
                    self._errHandler.sync(self)
                    token = self._input.LA(1)
                    if token in [pgnParser.T__3]:
                        self.state = 152
                        self.tag()
                        pass
                    elif token in [pgnParser.WS]:
                        self.state = 153
                        self.match(pgnParser.WS)
                        pass
                    else:
                        raise NoViableAltException(self)
             
                self.state = 158
                self._errHandler.sync(self)
                _alt = self._interp.adaptivePredict(self._input,16,self._ctx)

            self.state = 163
            self._errHandler.sync(self)
            _alt = self._interp.adaptivePredict(self._input,18,self._ctx)
            while _alt!=1 and _alt!=ATN.INVALID_ALT_NUMBER:
                if _alt==1+1:
                    self.state = 161
                    self._errHandler.sync(self)
                    token = self._input.LA(1)
                    if token in [pgnParser.RANK, pgnParser.INT]:
                        self.state = 159
                        self.fullMove()
                        pass
                    elif token in [pgnParser.WS]:
                        self.state = 160
                        self.match(pgnParser.WS)
                        pass
                    else:
                        raise NoViableAltException(self)
             
                self.state = 165
                self._errHandler.sync(self)
                _alt = self._interp.adaptivePredict(self._input,18,self._ctx)

            self.state = 167
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if _la==pgnParser.RESULT:
                self.state = 166
                self.match(pgnParser.RESULT)


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





