# Generated from /workspace/python/tvm/relay/grammar/Relay.g4 by ANTLR 4.7.1
# encoding: utf-8
from antlr4 import *
from io import StringIO
from typing.io import TextIO
import sys

def serializedATN():
    with StringIO() as buf:
        buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3/")
        buf.write("\u0164\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\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16")
        buf.write("\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23")
        buf.write("\4\24\t\24\4\25\t\25\4\26\t\26\3\2\3\2\3\3\3\3\7\3\61")
        buf.write("\n\3\f\3\16\3\64\13\3\3\3\5\3\67\n\3\3\3\5\3:\n\3\3\3")
        buf.write("\3\3\3\4\3\4\3\4\7\4A\n\4\f\4\16\4D\13\4\5\4F\n\4\3\5")
        buf.write("\3\5\3\5\3\5\7\5L\n\5\f\5\16\5O\13\5\3\5\5\5R\n\5\3\6")
        buf.write("\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3")
        buf.write("\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\6\6k\n\6\r\6\16\6l")
        buf.write("\3\6\3\6\3\6\3\6\3\6\3\6\7\6u\n\6\f\6\16\6x\13\6\5\6z")
        buf.write("\n\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3")
        buf.write("\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6")
        buf.write("\5\6\u0096\n\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6")
        buf.write("\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\7")
        buf.write("\6\u00af\n\6\f\6\16\6\u00b2\13\6\3\7\3\7\5\7\u00b6\n\7")
        buf.write("\3\7\3\7\3\7\3\7\3\7\5\7\u00bd\n\7\3\7\3\7\3\b\3\b\3\b")
        buf.write("\5\b\u00c4\n\b\3\b\3\b\3\b\3\b\3\b\5\b\u00cb\n\b\3\b\3")
        buf.write("\b\3\t\3\t\3\t\3\t\7\t\u00d3\n\t\f\t\16\t\u00d6\13\t\3")
        buf.write("\t\5\t\u00d9\n\t\3\n\3\n\3\n\7\n\u00de\n\n\f\n\16\n\u00e1")
        buf.write("\13\n\5\n\u00e3\n\n\3\13\3\13\3\13\5\13\u00e8\n\13\3\f")
        buf.write("\3\f\3\f\7\f\u00ed\n\f\f\f\16\f\u00f0\13\f\3\r\3\r\3\r")
        buf.write("\3\r\3\16\3\16\3\16\3\16\3\16\3\16\7\16\u00fc\n\16\f\16")
        buf.write("\16\16\u00ff\13\16\3\16\3\16\5\16\u0103\n\16\3\17\3\17")
        buf.write("\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\6\17\u0110")
        buf.write("\n\17\r\17\16\17\u0111\3\17\3\17\3\17\3\17\3\17\3\17\3")
        buf.write("\17\3\17\3\17\3\17\3\17\3\17\5\17\u0120\n\17\3\17\3\17")
        buf.write("\3\17\3\17\7\17\u0126\n\17\f\17\16\17\u0129\13\17\5\17")
        buf.write("\u012b\n\17\3\17\3\17\3\17\3\17\3\17\5\17\u0132\n\17\3")
        buf.write("\20\3\20\3\20\3\20\6\20\u0138\n\20\r\20\16\20\u0139\3")
        buf.write("\20\3\20\3\20\3\20\3\20\5\20\u0141\n\20\3\21\3\21\3\21")
        buf.write("\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22")
        buf.write("\5\22\u0151\n\22\3\23\3\23\3\24\3\24\3\24\3\24\3\25\3")
        buf.write("\25\3\25\5\25\u015c\n\25\3\26\3\26\3\26\3\26\5\26\u0162")
        buf.write("\n\26\3\26\2\3\n\27\2\4\6\b\n\f\16\20\22\24\26\30\32\34")
        buf.write("\36 \"$&(*\2\6\3\2\35\36\3\2\37 \3\2!$\3\2%&\2\u018e\2")
        buf.write(",\3\2\2\2\4.\3\2\2\2\6E\3\2\2\2\bQ\3\2\2\2\n\u0095\3\2")
        buf.write("\2\2\f\u00b3\3\2\2\2\16\u00c0\3\2\2\2\20\u00d8\3\2\2\2")
        buf.write("\22\u00e2\3\2\2\2\24\u00e4\3\2\2\2\26\u00e9\3\2\2\2\30")
        buf.write("\u00f1\3\2\2\2\32\u0102\3\2\2\2\34\u0131\3\2\2\2\36\u0140")
        buf.write("\3\2\2\2 \u0142\3\2\2\2\"\u0150\3\2\2\2$\u0152\3\2\2\2")
        buf.write("&\u0154\3\2\2\2(\u015b\3\2\2\2*\u0161\3\2\2\2,-\7(\2\2")
        buf.write("-\3\3\2\2\2.\66\7\30\2\2/\61\5\16\b\2\60/\3\2\2\2\61\64")
        buf.write("\3\2\2\2\62\60\3\2\2\2\62\63\3\2\2\2\63\67\3\2\2\2\64")
        buf.write("\62\3\2\2\2\65\67\5\n\6\2\66\62\3\2\2\2\66\65\3\2\2\2")
        buf.write("\679\3\2\2\28:\7/\2\298\3\2\2\29:\3\2\2\2:;\3\2\2\2;<")
        buf.write("\7\2\2\3<\5\3\2\2\2=B\5\n\6\2>?\7\3\2\2?A\5\n\6\2@>\3")
        buf.write("\2\2\2AD\3\2\2\2B@\3\2\2\2BC\3\2\2\2CF\3\2\2\2DB\3\2\2")
        buf.write("\2E=\3\2\2\2EF\3\2\2\2F\7\3\2\2\2GR\5\6\4\2HI\5\n\6\2")
        buf.write("IJ\7\3\2\2JL\3\2\2\2KH\3\2\2\2LO\3\2\2\2MK\3\2\2\2MN\3")
        buf.write("\2\2\2NP\3\2\2\2OM\3\2\2\2PR\5\26\f\2QG\3\2\2\2QM\3\2")
        buf.write("\2\2R\t\3\2\2\2ST\b\6\1\2TU\7\4\2\2UV\5\n\6\2VW\7\5\2")
        buf.write("\2W\u0096\3\2\2\2XY\7\6\2\2YZ\5\n\6\2Z[\7\7\2\2[\u0096")
        buf.write("\3\2\2\2\\]\7 \2\2]\u0096\5\n\6\25^\u0096\5\f\7\2_`\7")
        buf.write("\4\2\2`\u0096\7\5\2\2ab\7\4\2\2bc\5\n\6\2cd\7\3\2\2de")
        buf.write("\7\5\2\2e\u0096\3\2\2\2fg\7\4\2\2gj\5\n\6\2hi\7\3\2\2")
        buf.write("ik\5\n\6\2jh\3\2\2\2kl\3\2\2\2lj\3\2\2\2lm\3\2\2\2mn\3")
        buf.write("\2\2\2no\7\5\2\2o\u0096\3\2\2\2py\7\t\2\2qv\5\n\6\2rs")
        buf.write("\7\3\2\2su\5\n\6\2tr\3\2\2\2ux\3\2\2\2vt\3\2\2\2vw\3\2")
        buf.write("\2\2wz\3\2\2\2xv\3\2\2\2yq\3\2\2\2yz\3\2\2\2z{\3\2\2\2")
        buf.write("{\u0096\7\n\2\2|}\7\13\2\2}~\7\4\2\2~\177\5\n\6\2\177")
        buf.write("\u0080\7\5\2\2\u0080\u0081\5&\24\2\u0081\u0082\7\f\2\2")
        buf.write("\u0082\u0083\5&\24\2\u0083\u0096\3\2\2\2\u0084\u0085\7")
        buf.write("\r\2\2\u0085\u0086\5\24\13\2\u0086\u0087\7\16\2\2\u0087")
        buf.write("\u0088\5\n\6\2\u0088\u0089\7\17\2\2\u0089\u008a\5\n\6")
        buf.write("\t\u008a\u0096\3\2\2\2\u008b\u008c\7+\2\2\u008c\u008d")
        buf.write("\7\16\2\2\u008d\u008e\5\n\6\2\u008e\u008f\7\17\2\2\u008f")
        buf.write("\u0090\5\n\6\7\u0090\u0096\3\2\2\2\u0091\u0096\5*\26\2")
        buf.write("\u0092\u0096\5(\25\2\u0093\u0096\5 \21\2\u0094\u0096\7")
        buf.write("\34\2\2\u0095S\3\2\2\2\u0095X\3\2\2\2\u0095\\\3\2\2\2")
        buf.write("\u0095^\3\2\2\2\u0095_\3\2\2\2\u0095a\3\2\2\2\u0095f\3")
        buf.write("\2\2\2\u0095p\3\2\2\2\u0095|\3\2\2\2\u0095\u0084\3\2\2")
        buf.write("\2\u0095\u008b\3\2\2\2\u0095\u0091\3\2\2\2\u0095\u0092")
        buf.write("\3\2\2\2\u0095\u0093\3\2\2\2\u0095\u0094\3\2\2\2\u0096")
        buf.write("\u00b0\3\2\2\2\u0097\u0098\f\24\2\2\u0098\u0099\t\2\2")
        buf.write("\2\u0099\u00af\5\n\6\25\u009a\u009b\f\23\2\2\u009b\u009c")
        buf.write("\t\3\2\2\u009c\u00af\5\n\6\24\u009d\u009e\f\22\2\2\u009e")
        buf.write("\u009f\t\4\2\2\u009f\u00af\5\n\6\23\u00a0\u00a1\f\21\2")
        buf.write("\2\u00a1\u00a2\t\5\2\2\u00a2\u00af\5\n\6\22\u00a3\u00a4")
        buf.write("\f\b\2\2\u00a4\u00a5\7\20\2\2\u00a5\u00af\5\n\6\t\u00a6")
        buf.write("\u00a7\f\26\2\2\u00a7\u00a8\7\4\2\2\u00a8\u00a9\5\b\5")
        buf.write("\2\u00a9\u00aa\7\5\2\2\u00aa\u00af\3\2\2\2\u00ab\u00ac")
        buf.write("\f\f\2\2\u00ac\u00ad\7\b\2\2\u00ad\u00af\7.\2\2\u00ae")
        buf.write("\u0097\3\2\2\2\u00ae\u009a\3\2\2\2\u00ae\u009d\3\2\2\2")
        buf.write("\u00ae\u00a0\3\2\2\2\u00ae\u00a3\3\2\2\2\u00ae\u00a6\3")
        buf.write("\2\2\2\u00ae\u00ab\3\2\2\2\u00af\u00b2\3\2\2\2\u00b0\u00ae")
        buf.write("\3\2\2\2\u00b0\u00b1\3\2\2\2\u00b1\13\3\2\2\2\u00b2\u00b0")
        buf.write("\3\2\2\2\u00b3\u00b5\7\21\2\2\u00b4\u00b6\5\32\16\2\u00b5")
        buf.write("\u00b4\3\2\2\2\u00b5\u00b6\3\2\2\2\u00b6\u00b7\3\2\2\2")
        buf.write("\u00b7\u00b8\7\4\2\2\u00b8\u00b9\5\20\t\2\u00b9\u00bc")
        buf.write("\7\5\2\2\u00ba\u00bb\7\22\2\2\u00bb\u00bd\5\34\17\2\u00bc")
        buf.write("\u00ba\3\2\2\2\u00bc\u00bd\3\2\2\2\u00bd\u00be\3\2\2\2")
        buf.write("\u00be\u00bf\5&\24\2\u00bf\r\3\2\2\2\u00c0\u00c1\7\23")
        buf.write("\2\2\u00c1\u00c3\5*\26\2\u00c2\u00c4\5\32\16\2\u00c3\u00c2")
        buf.write("\3\2\2\2\u00c3\u00c4\3\2\2\2\u00c4\u00c5\3\2\2\2\u00c5")
        buf.write("\u00c6\7\4\2\2\u00c6\u00c7\5\20\t\2\u00c7\u00ca\7\5\2")
        buf.write("\2\u00c8\u00c9\7\22\2\2\u00c9\u00cb\5\34\17\2\u00ca\u00c8")
        buf.write("\3\2\2\2\u00ca\u00cb\3\2\2\2\u00cb\u00cc\3\2\2\2\u00cc")
        buf.write("\u00cd\5&\24\2\u00cd\17\3\2\2\2\u00ce\u00d9\5\22\n\2\u00cf")
        buf.write("\u00d0\5\24\13\2\u00d0\u00d1\7\3\2\2\u00d1\u00d3\3\2\2")
        buf.write("\2\u00d2\u00cf\3\2\2\2\u00d3\u00d6\3\2\2\2\u00d4\u00d2")
        buf.write("\3\2\2\2\u00d4\u00d5\3\2\2\2\u00d5\u00d7\3\2\2\2\u00d6")
        buf.write("\u00d4\3\2\2\2\u00d7\u00d9\5\26\f\2\u00d8\u00ce\3\2\2")
        buf.write("\2\u00d8\u00d4\3\2\2\2\u00d9\21\3\2\2\2\u00da\u00df\5")
        buf.write("\24\13\2\u00db\u00dc\7\3\2\2\u00dc\u00de\5\24\13\2\u00dd")
        buf.write("\u00db\3\2\2\2\u00de\u00e1\3\2\2\2\u00df\u00dd\3\2\2\2")
        buf.write("\u00df\u00e0\3\2\2\2\u00e0\u00e3\3\2\2\2\u00e1\u00df\3")
        buf.write("\2\2\2\u00e2\u00da\3\2\2\2\u00e2\u00e3\3\2\2\2\u00e3\23")
        buf.write("\3\2\2\2\u00e4\u00e7\7*\2\2\u00e5\u00e6\7\24\2\2\u00e6")
        buf.write("\u00e8\5\34\17\2\u00e7\u00e5\3\2\2\2\u00e7\u00e8\3\2\2")
        buf.write("\2\u00e8\25\3\2\2\2\u00e9\u00ee\5\30\r\2\u00ea\u00eb\7")
        buf.write("\3\2\2\u00eb\u00ed\5\30\r\2\u00ec\u00ea\3\2\2\2\u00ed")
        buf.write("\u00f0\3\2\2\2\u00ee\u00ec\3\2\2\2\u00ee\u00ef\3\2\2\2")
        buf.write("\u00ef\27\3\2\2\2\u00f0\u00ee\3\2\2\2\u00f1\u00f2\7(\2")
        buf.write("\2\u00f2\u00f3\7\16\2\2\u00f3\u00f4\5\n\6\2\u00f4\31\3")
        buf.write("\2\2\2\u00f5\u00f6\7\t\2\2\u00f6\u0103\7\n\2\2\u00f7\u00f8")
        buf.write("\7\t\2\2\u00f8\u00fd\5*\26\2\u00f9\u00fa\7\3\2\2\u00fa")
        buf.write("\u00fc\5*\26\2\u00fb\u00f9\3\2\2\2\u00fc\u00ff\3\2\2\2")
        buf.write("\u00fd\u00fb\3\2\2\2\u00fd\u00fe\3\2\2\2\u00fe\u0100\3")
        buf.write("\2\2\2\u00ff\u00fd\3\2\2\2\u0100\u0101\7\n\2\2\u0101\u0103")
        buf.write("\3\2\2\2\u0102\u00f5\3\2\2\2\u0102\u00f7\3\2\2\2\u0103")
        buf.write("\33\3\2\2\2\u0104\u0105\7\4\2\2\u0105\u0132\7\5\2\2\u0106")
        buf.write("\u0107\7\4\2\2\u0107\u0108\5\34\17\2\u0108\u0109\7\3\2")
        buf.write("\2\u0109\u010a\7\5\2\2\u010a\u0132\3\2\2\2\u010b\u010c")
        buf.write("\7\4\2\2\u010c\u010f\5\34\17\2\u010d\u010e\7\3\2\2\u010e")
        buf.write("\u0110\5\34\17\2\u010f\u010d\3\2\2\2\u0110\u0111\3\2\2")
        buf.write("\2\u0111\u010f\3\2\2\2\u0111\u0112\3\2\2\2\u0112\u0113")
        buf.write("\3\2\2\2\u0113\u0114\7\5\2\2\u0114\u0132\3\2\2\2\u0115")
        buf.write("\u0132\5$\23\2\u0116\u0117\7\25\2\2\u0117\u0118\7\t\2")
        buf.write("\2\u0118\u0119\5\36\20\2\u0119\u011a\7\3\2\2\u011a\u011b")
        buf.write("\5\34\17\2\u011b\u011c\7\n\2\2\u011c\u0132\3\2\2\2\u011d")
        buf.write("\u011f\7\21\2\2\u011e\u0120\5\32\16\2\u011f\u011e\3\2")
        buf.write("\2\2\u011f\u0120\3\2\2\2\u0120\u0121\3\2\2\2\u0121\u012a")
        buf.write("\7\4\2\2\u0122\u0127\5\34\17\2\u0123\u0124\7\3\2\2\u0124")
        buf.write("\u0126\5\34\17\2\u0125\u0123\3\2\2\2\u0126\u0129\3\2\2")
        buf.write("\2\u0127\u0125\3\2\2\2\u0127\u0128\3\2\2\2\u0128\u012b")
        buf.write("\3\2\2\2\u0129\u0127\3\2\2\2\u012a\u0122\3\2\2\2\u012a")
        buf.write("\u012b\3\2\2\2\u012b\u012c\3\2\2\2\u012c\u012d\7\5\2\2")
        buf.write("\u012d\u012e\7\22\2\2\u012e\u0132\5\34\17\2\u012f\u0132")
        buf.write("\7\26\2\2\u0130\u0132\7.\2\2\u0131\u0104\3\2\2\2\u0131")
        buf.write("\u0106\3\2\2\2\u0131\u010b\3\2\2\2\u0131\u0115\3\2\2\2")
        buf.write("\u0131\u0116\3\2\2\2\u0131\u011d\3\2\2\2\u0131\u012f\3")
        buf.write("\2\2\2\u0131\u0130\3\2\2\2\u0132\35\3\2\2\2\u0133\u0134")
        buf.write("\7\4\2\2\u0134\u0137\5\"\22\2\u0135\u0136\7\3\2\2\u0136")
        buf.write("\u0138\5\"\22\2\u0137\u0135\3\2\2\2\u0138\u0139\3\2\2")
        buf.write("\2\u0139\u0137\3\2\2\2\u0139\u013a\3\2\2\2\u013a\u013b")
        buf.write("\3\2\2\2\u013b\u013c\7\5\2\2\u013c\u0141\3\2\2\2\u013d")
        buf.write("\u013e\7\4\2\2\u013e\u0141\7\5\2\2\u013f\u0141\5\"\22")
        buf.write("\2\u0140\u0133\3\2\2\2\u0140\u013d\3\2\2\2\u0140\u013f")
        buf.write("\3\2\2\2\u0141\37\3\2\2\2\u0142\u0143\7\27\2\2\u0143\u0144")
        buf.write("\7\t\2\2\u0144\u0145\7(\2\2\u0145\u0146\7\n\2\2\u0146")
        buf.write("\u0147\7\t\2\2\u0147\u0148\7.\2\2\u0148\u0149\7\n\2\2")
        buf.write("\u0149!\3\2\2\2\u014a\u0151\5 \21\2\u014b\u014c\7\4\2")
        buf.write("\2\u014c\u014d\5\"\22\2\u014d\u014e\7\5\2\2\u014e\u0151")
        buf.write("\3\2\2\2\u014f\u0151\7.\2\2\u0150\u014a\3\2\2\2\u0150")
        buf.write("\u014b\3\2\2\2\u0150\u014f\3\2\2\2\u0151#\3\2\2\2\u0152")
        buf.write("\u0153\7(\2\2\u0153%\3\2\2\2\u0154\u0155\7\6\2\2\u0155")
        buf.write("\u0156\5\n\6\2\u0156\u0157\7\7\2\2\u0157\'\3\2\2\2\u0158")
        buf.write("\u015c\7-\2\2\u0159\u015c\7.\2\2\u015a\u015c\7\'\2\2\u015b")
        buf.write("\u0158\3\2\2\2\u015b\u0159\3\2\2\2\u015b\u015a\3\2\2\2")
        buf.write("\u015c)\3\2\2\2\u015d\u0162\5\2\2\2\u015e\u0162\7)\2\2")
        buf.write("\u015f\u0162\7*\2\2\u0160\u0162\7+\2\2\u0161\u015d\3\2")
        buf.write("\2\2\u0161\u015e\3\2\2\2\u0161\u015f\3\2\2\2\u0161\u0160")
        buf.write("\3\2\2\2\u0162+\3\2\2\2%\62\669BEMQlvy\u0095\u00ae\u00b0")
        buf.write("\u00b5\u00bc\u00c3\u00ca\u00d4\u00d8\u00df\u00e2\u00e7")
        buf.write("\u00ee\u00fd\u0102\u0111\u011f\u0127\u012a\u0131\u0139")
        buf.write("\u0140\u0150\u015b\u0161")
        return buf.getvalue()


class RelayParser ( Parser ):

    grammarFileName = "Relay.g4"

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

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

    sharedContextCache = PredictionContextCache()

    literalNames = [ "<INVALID>", "','", "'('", "')'", "'{'", "'}'", "'.'", 
                     "'['", "']'", "'if'", "'else'", "'let'", "'='", "';'", 
                     "';;'", "'fn'", "'->'", "'def'", "':'", "'Tensor'", 
                     "'_'", "'meta'", "'v0.0.3'", "<INVALID>", "<INVALID>", 
                     "<INVALID>", "<INVALID>", "'*'", "'/'", "'+'", "'-'", 
                     "'<'", "'>'", "'<='", "'>='", "'=='", "'!='", "<INVALID>", 
                     "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                     "'int64'" ]

    symbolicNames = [ "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", 
                      "<INVALID>", "<INVALID>", "SEMVER", "COMMENT", "WS", 
                      "LINE_COMMENT", "QUOTED_STRING", "MUL", "DIV", "ADD", 
                      "SUB", "LT", "GT", "LE", "GE", "EQ", "NE", "BOOL_LIT", 
                      "CNAME", "GLOBAL_VAR", "LOCAL_VAR", "GRAPH_VAR", "DATATYPE", 
                      "FLOAT", "NAT", "METADATA" ]

    RULE_opIdent = 0
    RULE_prog = 1
    RULE_exprList = 2
    RULE_callList = 3
    RULE_expr = 4
    RULE_func = 5
    RULE_defn = 6
    RULE_argList = 7
    RULE_varList = 8
    RULE_var = 9
    RULE_attrSeq = 10
    RULE_attr = 11
    RULE_typeParamList = 12
    RULE_type_ = 13
    RULE_shapeList = 14
    RULE_meta = 15
    RULE_shape = 16
    RULE_typeIdent = 17
    RULE_body = 18
    RULE_scalar = 19
    RULE_ident = 20

    ruleNames =  [ "opIdent", "prog", "exprList", "callList", "expr", "func", 
                   "defn", "argList", "varList", "var", "attrSeq", "attr", 
                   "typeParamList", "type_", "shapeList", "meta", "shape", 
                   "typeIdent", "body", "scalar", "ident" ]

    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
    T__10=11
    T__11=12
    T__12=13
    T__13=14
    T__14=15
    T__15=16
    T__16=17
    T__17=18
    T__18=19
    T__19=20
    T__20=21
    SEMVER=22
    COMMENT=23
    WS=24
    LINE_COMMENT=25
    QUOTED_STRING=26
    MUL=27
    DIV=28
    ADD=29
    SUB=30
    LT=31
    GT=32
    LE=33
    GE=34
    EQ=35
    NE=36
    BOOL_LIT=37
    CNAME=38
    GLOBAL_VAR=39
    LOCAL_VAR=40
    GRAPH_VAR=41
    DATATYPE=42
    FLOAT=43
    NAT=44
    METADATA=45

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



    class OpIdentContext(ParserRuleContext):

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

        def CNAME(self):
            return self.getToken(RelayParser.CNAME, 0)

        def getRuleIndex(self):
            return RelayParser.RULE_opIdent

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




    def opIdent(self):

        localctx = RelayParser.OpIdentContext(self, self._ctx, self.state)
        self.enterRule(localctx, 0, self.RULE_opIdent)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 42
            self.match(RelayParser.CNAME)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class ProgContext(ParserRuleContext):

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

        def SEMVER(self):
            return self.getToken(RelayParser.SEMVER, 0)

        def EOF(self):
            return self.getToken(RelayParser.EOF, 0)

        def expr(self):
            return self.getTypedRuleContext(RelayParser.ExprContext,0)


        def METADATA(self):
            return self.getToken(RelayParser.METADATA, 0)

        def defn(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.DefnContext)
            else:
                return self.getTypedRuleContext(RelayParser.DefnContext,i)


        def getRuleIndex(self):
            return RelayParser.RULE_prog

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




    def prog(self):

        localctx = RelayParser.ProgContext(self, self._ctx, self.state)
        self.enterRule(localctx, 2, self.RULE_prog)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 44
            self.match(RelayParser.SEMVER)
            self.state = 52
            self._errHandler.sync(self)
            token = self._input.LA(1)
            if token in [RelayParser.EOF, RelayParser.T__16, RelayParser.METADATA]:
                self.state = 48
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                while _la==RelayParser.T__16:
                    self.state = 45
                    self.defn()
                    self.state = 50
                    self._errHandler.sync(self)
                    _la = self._input.LA(1)

                pass
            elif token in [RelayParser.T__1, RelayParser.T__3, RelayParser.T__6, RelayParser.T__8, RelayParser.T__10, RelayParser.T__14, RelayParser.T__20, RelayParser.QUOTED_STRING, RelayParser.SUB, RelayParser.BOOL_LIT, RelayParser.CNAME, RelayParser.GLOBAL_VAR, RelayParser.LOCAL_VAR, RelayParser.GRAPH_VAR, RelayParser.FLOAT, RelayParser.NAT]:
                self.state = 51
                self.expr(0)
                pass
            else:
                raise NoViableAltException(self)

            self.state = 55
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if _la==RelayParser.METADATA:
                self.state = 54
                self.match(RelayParser.METADATA)


            self.state = 57
            self.match(RelayParser.EOF)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class ExprListContext(ParserRuleContext):

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

        def expr(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.ExprContext)
            else:
                return self.getTypedRuleContext(RelayParser.ExprContext,i)


        def getRuleIndex(self):
            return RelayParser.RULE_exprList

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




    def exprList(self):

        localctx = RelayParser.ExprListContext(self, self._ctx, self.state)
        self.enterRule(localctx, 4, self.RULE_exprList)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 67
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << RelayParser.T__1) | (1 << RelayParser.T__3) | (1 << RelayParser.T__6) | (1 << RelayParser.T__8) | (1 << RelayParser.T__10) | (1 << RelayParser.T__14) | (1 << RelayParser.T__20) | (1 << RelayParser.QUOTED_STRING) | (1 << RelayParser.SUB) | (1 << RelayParser.BOOL_LIT) | (1 << RelayParser.CNAME) | (1 << RelayParser.GLOBAL_VAR) | (1 << RelayParser.LOCAL_VAR) | (1 << RelayParser.GRAPH_VAR) | (1 << RelayParser.FLOAT) | (1 << RelayParser.NAT))) != 0):
                self.state = 59
                self.expr(0)
                self.state = 64
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                while _la==RelayParser.T__0:
                    self.state = 60
                    self.match(RelayParser.T__0)
                    self.state = 61
                    self.expr(0)
                    self.state = 66
                    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

    class CallListContext(ParserRuleContext):

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


        def getRuleIndex(self):
            return RelayParser.RULE_callList

     
        def copyFrom(self, ctx:ParserRuleContext):
            super().copyFrom(ctx)



    class CallWithAttrContext(CallListContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.CallListContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def attrSeq(self):
            return self.getTypedRuleContext(RelayParser.AttrSeqContext,0)

        def expr(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.ExprContext)
            else:
                return self.getTypedRuleContext(RelayParser.ExprContext,i)


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


    class CallNoAttrContext(CallListContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.CallListContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def exprList(self):
            return self.getTypedRuleContext(RelayParser.ExprListContext,0)


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



    def callList(self):

        localctx = RelayParser.CallListContext(self, self._ctx, self.state)
        self.enterRule(localctx, 6, self.RULE_callList)
        try:
            self.state = 79
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,6,self._ctx)
            if la_ == 1:
                localctx = RelayParser.CallNoAttrContext(self, localctx)
                self.enterOuterAlt(localctx, 1)
                self.state = 69
                self.exprList()
                pass

            elif la_ == 2:
                localctx = RelayParser.CallWithAttrContext(self, localctx)
                self.enterOuterAlt(localctx, 2)
                self.state = 75
                self._errHandler.sync(self)
                _alt = self._interp.adaptivePredict(self._input,5,self._ctx)
                while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
                    if _alt==1:
                        self.state = 70
                        self.expr(0)
                        self.state = 71
                        self.match(RelayParser.T__0) 
                    self.state = 77
                    self._errHandler.sync(self)
                    _alt = self._interp.adaptivePredict(self._input,5,self._ctx)

                self.state = 78
                self.attrSeq()
                pass


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

    class ExprContext(ParserRuleContext):

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


        def getRuleIndex(self):
            return RelayParser.RULE_expr

     
        def copyFrom(self, ctx:ParserRuleContext):
            super().copyFrom(ctx)


    class FuncExprContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def func(self):
            return self.getTypedRuleContext(RelayParser.FuncContext,0)


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


    class MetaExprContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def meta(self):
            return self.getTypedRuleContext(RelayParser.MetaContext,0)


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


    class TensorContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def expr(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.ExprContext)
            else:
                return self.getTypedRuleContext(RelayParser.ExprContext,i)


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


    class GraphContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def GRAPH_VAR(self):
            return self.getToken(RelayParser.GRAPH_VAR, 0)
        def expr(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.ExprContext)
            else:
                return self.getTypedRuleContext(RelayParser.ExprContext,i)


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


    class IdentExprContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def ident(self):
            return self.getTypedRuleContext(RelayParser.IdentContext,0)


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


    class StringExprContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def QUOTED_STRING(self):
            return self.getToken(RelayParser.QUOTED_STRING, 0)

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


    class CallContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def expr(self):
            return self.getTypedRuleContext(RelayParser.ExprContext,0)

        def callList(self):
            return self.getTypedRuleContext(RelayParser.CallListContext,0)


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


    class NegContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def expr(self):
            return self.getTypedRuleContext(RelayParser.ExprContext,0)


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


    class TupleContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def expr(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.ExprContext)
            else:
                return self.getTypedRuleContext(RelayParser.ExprContext,i)


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


    class ParenContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def expr(self):
            return self.getTypedRuleContext(RelayParser.ExprContext,0)


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


    class ScalarExprContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def scalar(self):
            return self.getTypedRuleContext(RelayParser.ScalarContext,0)


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


    class LetContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def var(self):
            return self.getTypedRuleContext(RelayParser.VarContext,0)

        def expr(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.ExprContext)
            else:
                return self.getTypedRuleContext(RelayParser.ExprContext,i)


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


    class ProjectionContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def expr(self):
            return self.getTypedRuleContext(RelayParser.ExprContext,0)

        def NAT(self):
            return self.getToken(RelayParser.NAT, 0)

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


    class IfElseContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ExprContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def expr(self):
            return self.getTypedRuleContext(RelayParser.ExprContext,0)

        def body(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.BodyContext)
            else:
                return self.getTypedRuleContext(RelayParser.BodyContext,i)


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


    class BinOpContext(ExprContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ExprContext
            super().__init__(parser)
            self.op = None # Token
            self.copyFrom(ctx)

        def expr(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.ExprContext)
            else:
                return self.getTypedRuleContext(RelayParser.ExprContext,i)


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



    def expr(self, _p:int=0):
        _parentctx = self._ctx
        _parentState = self.state
        localctx = RelayParser.ExprContext(self, self._ctx, _parentState)
        _prevctx = localctx
        _startState = 8
        self.enterRecursionRule(localctx, 8, self.RULE_expr, _p)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 147
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,10,self._ctx)
            if la_ == 1:
                localctx = RelayParser.ParenContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx

                self.state = 82
                self.match(RelayParser.T__1)
                self.state = 83
                self.expr(0)
                self.state = 84
                self.match(RelayParser.T__2)
                pass

            elif la_ == 2:
                localctx = RelayParser.ParenContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 86
                self.match(RelayParser.T__3)
                self.state = 87
                self.expr(0)
                self.state = 88
                self.match(RelayParser.T__4)
                pass

            elif la_ == 3:
                localctx = RelayParser.NegContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 90
                self.match(RelayParser.SUB)
                self.state = 91
                self.expr(19)
                pass

            elif la_ == 4:
                localctx = RelayParser.FuncExprContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 92
                self.func()
                pass

            elif la_ == 5:
                localctx = RelayParser.TupleContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 93
                self.match(RelayParser.T__1)
                self.state = 94
                self.match(RelayParser.T__2)
                pass

            elif la_ == 6:
                localctx = RelayParser.TupleContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 95
                self.match(RelayParser.T__1)
                self.state = 96
                self.expr(0)
                self.state = 97
                self.match(RelayParser.T__0)
                self.state = 98
                self.match(RelayParser.T__2)
                pass

            elif la_ == 7:
                localctx = RelayParser.TupleContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 100
                self.match(RelayParser.T__1)
                self.state = 101
                self.expr(0)
                self.state = 104 
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                while True:
                    self.state = 102
                    self.match(RelayParser.T__0)
                    self.state = 103
                    self.expr(0)
                    self.state = 106 
                    self._errHandler.sync(self)
                    _la = self._input.LA(1)
                    if not (_la==RelayParser.T__0):
                        break

                self.state = 108
                self.match(RelayParser.T__2)
                pass

            elif la_ == 8:
                localctx = RelayParser.TensorContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 110
                self.match(RelayParser.T__6)
                self.state = 119
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << RelayParser.T__1) | (1 << RelayParser.T__3) | (1 << RelayParser.T__6) | (1 << RelayParser.T__8) | (1 << RelayParser.T__10) | (1 << RelayParser.T__14) | (1 << RelayParser.T__20) | (1 << RelayParser.QUOTED_STRING) | (1 << RelayParser.SUB) | (1 << RelayParser.BOOL_LIT) | (1 << RelayParser.CNAME) | (1 << RelayParser.GLOBAL_VAR) | (1 << RelayParser.LOCAL_VAR) | (1 << RelayParser.GRAPH_VAR) | (1 << RelayParser.FLOAT) | (1 << RelayParser.NAT))) != 0):
                    self.state = 111
                    self.expr(0)
                    self.state = 116
                    self._errHandler.sync(self)
                    _la = self._input.LA(1)
                    while _la==RelayParser.T__0:
                        self.state = 112
                        self.match(RelayParser.T__0)
                        self.state = 113
                        self.expr(0)
                        self.state = 118
                        self._errHandler.sync(self)
                        _la = self._input.LA(1)



                self.state = 121
                self.match(RelayParser.T__7)
                pass

            elif la_ == 9:
                localctx = RelayParser.IfElseContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 122
                self.match(RelayParser.T__8)
                self.state = 123
                self.match(RelayParser.T__1)
                self.state = 124
                self.expr(0)
                self.state = 125
                self.match(RelayParser.T__2)
                self.state = 126
                self.body()
                self.state = 127
                self.match(RelayParser.T__9)
                self.state = 128
                self.body()
                pass

            elif la_ == 10:
                localctx = RelayParser.LetContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 130
                self.match(RelayParser.T__10)
                self.state = 131
                self.var()
                self.state = 132
                self.match(RelayParser.T__11)
                self.state = 133
                self.expr(0)
                self.state = 134
                self.match(RelayParser.T__12)
                self.state = 135
                self.expr(7)
                pass

            elif la_ == 11:
                localctx = RelayParser.GraphContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 137
                self.match(RelayParser.GRAPH_VAR)
                self.state = 138
                self.match(RelayParser.T__11)
                self.state = 139
                self.expr(0)
                self.state = 140
                self.match(RelayParser.T__12)
                self.state = 141
                self.expr(5)
                pass

            elif la_ == 12:
                localctx = RelayParser.IdentExprContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 143
                self.ident()
                pass

            elif la_ == 13:
                localctx = RelayParser.ScalarExprContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 144
                self.scalar()
                pass

            elif la_ == 14:
                localctx = RelayParser.MetaExprContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 145
                self.meta()
                pass

            elif la_ == 15:
                localctx = RelayParser.StringExprContext(self, localctx)
                self._ctx = localctx
                _prevctx = localctx
                self.state = 146
                self.match(RelayParser.QUOTED_STRING)
                pass


            self._ctx.stop = self._input.LT(-1)
            self.state = 174
            self._errHandler.sync(self)
            _alt = self._interp.adaptivePredict(self._input,12,self._ctx)
            while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
                if _alt==1:
                    if self._parseListeners is not None:
                        self.triggerExitRuleEvent()
                    _prevctx = localctx
                    self.state = 172
                    self._errHandler.sync(self)
                    la_ = self._interp.adaptivePredict(self._input,11,self._ctx)
                    if la_ == 1:
                        localctx = RelayParser.BinOpContext(self, RelayParser.ExprContext(self, _parentctx, _parentState))
                        self.pushNewRecursionContext(localctx, _startState, self.RULE_expr)
                        self.state = 149
                        if not self.precpred(self._ctx, 18):
                            from antlr4.error.Errors import FailedPredicateException
                            raise FailedPredicateException(self, "self.precpred(self._ctx, 18)")
                        self.state = 150
                        localctx.op = self._input.LT(1)
                        _la = self._input.LA(1)
                        if not(_la==RelayParser.MUL or _la==RelayParser.DIV):
                            localctx.op = self._errHandler.recoverInline(self)
                        else:
                            self._errHandler.reportMatch(self)
                            self.consume()
                        self.state = 151
                        self.expr(19)
                        pass

                    elif la_ == 2:
                        localctx = RelayParser.BinOpContext(self, RelayParser.ExprContext(self, _parentctx, _parentState))
                        self.pushNewRecursionContext(localctx, _startState, self.RULE_expr)
                        self.state = 152
                        if not self.precpred(self._ctx, 17):
                            from antlr4.error.Errors import FailedPredicateException
                            raise FailedPredicateException(self, "self.precpred(self._ctx, 17)")
                        self.state = 153
                        localctx.op = self._input.LT(1)
                        _la = self._input.LA(1)
                        if not(_la==RelayParser.ADD or _la==RelayParser.SUB):
                            localctx.op = self._errHandler.recoverInline(self)
                        else:
                            self._errHandler.reportMatch(self)
                            self.consume()
                        self.state = 154
                        self.expr(18)
                        pass

                    elif la_ == 3:
                        localctx = RelayParser.BinOpContext(self, RelayParser.ExprContext(self, _parentctx, _parentState))
                        self.pushNewRecursionContext(localctx, _startState, self.RULE_expr)
                        self.state = 155
                        if not self.precpred(self._ctx, 16):
                            from antlr4.error.Errors import FailedPredicateException
                            raise FailedPredicateException(self, "self.precpred(self._ctx, 16)")
                        self.state = 156
                        localctx.op = self._input.LT(1)
                        _la = self._input.LA(1)
                        if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << RelayParser.LT) | (1 << RelayParser.GT) | (1 << RelayParser.LE) | (1 << RelayParser.GE))) != 0)):
                            localctx.op = self._errHandler.recoverInline(self)
                        else:
                            self._errHandler.reportMatch(self)
                            self.consume()
                        self.state = 157
                        self.expr(17)
                        pass

                    elif la_ == 4:
                        localctx = RelayParser.BinOpContext(self, RelayParser.ExprContext(self, _parentctx, _parentState))
                        self.pushNewRecursionContext(localctx, _startState, self.RULE_expr)
                        self.state = 158
                        if not self.precpred(self._ctx, 15):
                            from antlr4.error.Errors import FailedPredicateException
                            raise FailedPredicateException(self, "self.precpred(self._ctx, 15)")
                        self.state = 159
                        localctx.op = self._input.LT(1)
                        _la = self._input.LA(1)
                        if not(_la==RelayParser.EQ or _la==RelayParser.NE):
                            localctx.op = self._errHandler.recoverInline(self)
                        else:
                            self._errHandler.reportMatch(self)
                            self.consume()
                        self.state = 160
                        self.expr(16)
                        pass

                    elif la_ == 5:
                        localctx = RelayParser.LetContext(self, RelayParser.ExprContext(self, _parentctx, _parentState))
                        self.pushNewRecursionContext(localctx, _startState, self.RULE_expr)
                        self.state = 161
                        if not self.precpred(self._ctx, 6):
                            from antlr4.error.Errors import FailedPredicateException
                            raise FailedPredicateException(self, "self.precpred(self._ctx, 6)")
                        self.state = 162
                        self.match(RelayParser.T__13)
                        self.state = 163
                        self.expr(7)
                        pass

                    elif la_ == 6:
                        localctx = RelayParser.CallContext(self, RelayParser.ExprContext(self, _parentctx, _parentState))
                        self.pushNewRecursionContext(localctx, _startState, self.RULE_expr)
                        self.state = 164
                        if not self.precpred(self._ctx, 20):
                            from antlr4.error.Errors import FailedPredicateException
                            raise FailedPredicateException(self, "self.precpred(self._ctx, 20)")
                        self.state = 165
                        self.match(RelayParser.T__1)
                        self.state = 166
                        self.callList()
                        self.state = 167
                        self.match(RelayParser.T__2)
                        pass

                    elif la_ == 7:
                        localctx = RelayParser.ProjectionContext(self, RelayParser.ExprContext(self, _parentctx, _parentState))
                        self.pushNewRecursionContext(localctx, _startState, self.RULE_expr)
                        self.state = 169
                        if not self.precpred(self._ctx, 10):
                            from antlr4.error.Errors import FailedPredicateException
                            raise FailedPredicateException(self, "self.precpred(self._ctx, 10)")
                        self.state = 170
                        self.match(RelayParser.T__5)
                        self.state = 171
                        self.match(RelayParser.NAT)
                        pass

             
                self.state = 176
                self._errHandler.sync(self)
                _alt = self._interp.adaptivePredict(self._input,12,self._ctx)

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

    class FuncContext(ParserRuleContext):

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

        def argList(self):
            return self.getTypedRuleContext(RelayParser.ArgListContext,0)


        def body(self):
            return self.getTypedRuleContext(RelayParser.BodyContext,0)


        def typeParamList(self):
            return self.getTypedRuleContext(RelayParser.TypeParamListContext,0)


        def type_(self):
            return self.getTypedRuleContext(RelayParser.Type_Context,0)


        def getRuleIndex(self):
            return RelayParser.RULE_func

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




    def func(self):

        localctx = RelayParser.FuncContext(self, self._ctx, self.state)
        self.enterRule(localctx, 10, self.RULE_func)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 177
            self.match(RelayParser.T__14)
            self.state = 179
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if _la==RelayParser.T__6:
                self.state = 178
                self.typeParamList()


            self.state = 181
            self.match(RelayParser.T__1)
            self.state = 182
            self.argList()
            self.state = 183
            self.match(RelayParser.T__2)
            self.state = 186
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if _la==RelayParser.T__15:
                self.state = 184
                self.match(RelayParser.T__15)
                self.state = 185
                self.type_()


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

    class DefnContext(ParserRuleContext):

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

        def ident(self):
            return self.getTypedRuleContext(RelayParser.IdentContext,0)


        def argList(self):
            return self.getTypedRuleContext(RelayParser.ArgListContext,0)


        def body(self):
            return self.getTypedRuleContext(RelayParser.BodyContext,0)


        def typeParamList(self):
            return self.getTypedRuleContext(RelayParser.TypeParamListContext,0)


        def type_(self):
            return self.getTypedRuleContext(RelayParser.Type_Context,0)


        def getRuleIndex(self):
            return RelayParser.RULE_defn

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




    def defn(self):

        localctx = RelayParser.DefnContext(self, self._ctx, self.state)
        self.enterRule(localctx, 12, self.RULE_defn)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 190
            self.match(RelayParser.T__16)
            self.state = 191
            self.ident()
            self.state = 193
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if _la==RelayParser.T__6:
                self.state = 192
                self.typeParamList()


            self.state = 195
            self.match(RelayParser.T__1)
            self.state = 196
            self.argList()
            self.state = 197
            self.match(RelayParser.T__2)
            self.state = 200
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if _la==RelayParser.T__15:
                self.state = 198
                self.match(RelayParser.T__15)
                self.state = 199
                self.type_()


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

    class ArgListContext(ParserRuleContext):

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


        def getRuleIndex(self):
            return RelayParser.RULE_argList

     
        def copyFrom(self, ctx:ParserRuleContext):
            super().copyFrom(ctx)



    class ArgNoAttrContext(ArgListContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ArgListContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def varList(self):
            return self.getTypedRuleContext(RelayParser.VarListContext,0)


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


    class ArgWithAttrContext(ArgListContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ArgListContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def attrSeq(self):
            return self.getTypedRuleContext(RelayParser.AttrSeqContext,0)

        def var(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.VarContext)
            else:
                return self.getTypedRuleContext(RelayParser.VarContext,i)


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



    def argList(self):

        localctx = RelayParser.ArgListContext(self, self._ctx, self.state)
        self.enterRule(localctx, 14, self.RULE_argList)
        self._la = 0 # Token type
        try:
            self.state = 214
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,18,self._ctx)
            if la_ == 1:
                localctx = RelayParser.ArgNoAttrContext(self, localctx)
                self.enterOuterAlt(localctx, 1)
                self.state = 204
                self.varList()
                pass

            elif la_ == 2:
                localctx = RelayParser.ArgWithAttrContext(self, localctx)
                self.enterOuterAlt(localctx, 2)
                self.state = 210
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                while _la==RelayParser.LOCAL_VAR:
                    self.state = 205
                    self.var()
                    self.state = 206
                    self.match(RelayParser.T__0)
                    self.state = 212
                    self._errHandler.sync(self)
                    _la = self._input.LA(1)

                self.state = 213
                self.attrSeq()
                pass


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

    class VarListContext(ParserRuleContext):

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

        def var(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.VarContext)
            else:
                return self.getTypedRuleContext(RelayParser.VarContext,i)


        def getRuleIndex(self):
            return RelayParser.RULE_varList

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




    def varList(self):

        localctx = RelayParser.VarListContext(self, self._ctx, self.state)
        self.enterRule(localctx, 16, self.RULE_varList)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 224
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if _la==RelayParser.LOCAL_VAR:
                self.state = 216
                self.var()
                self.state = 221
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                while _la==RelayParser.T__0:
                    self.state = 217
                    self.match(RelayParser.T__0)
                    self.state = 218
                    self.var()
                    self.state = 223
                    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

    class VarContext(ParserRuleContext):

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

        def LOCAL_VAR(self):
            return self.getToken(RelayParser.LOCAL_VAR, 0)

        def type_(self):
            return self.getTypedRuleContext(RelayParser.Type_Context,0)


        def getRuleIndex(self):
            return RelayParser.RULE_var

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




    def var(self):

        localctx = RelayParser.VarContext(self, self._ctx, self.state)
        self.enterRule(localctx, 18, self.RULE_var)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 226
            self.match(RelayParser.LOCAL_VAR)
            self.state = 229
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            if _la==RelayParser.T__17:
                self.state = 227
                self.match(RelayParser.T__17)
                self.state = 228
                self.type_()


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

    class AttrSeqContext(ParserRuleContext):

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

        def attr(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.AttrContext)
            else:
                return self.getTypedRuleContext(RelayParser.AttrContext,i)


        def getRuleIndex(self):
            return RelayParser.RULE_attrSeq

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




    def attrSeq(self):

        localctx = RelayParser.AttrSeqContext(self, self._ctx, self.state)
        self.enterRule(localctx, 20, self.RULE_attrSeq)
        self._la = 0 # Token type
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 231
            self.attr()
            self.state = 236
            self._errHandler.sync(self)
            _la = self._input.LA(1)
            while _la==RelayParser.T__0:
                self.state = 232
                self.match(RelayParser.T__0)
                self.state = 233
                self.attr()
                self.state = 238
                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

    class AttrContext(ParserRuleContext):

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

        def CNAME(self):
            return self.getToken(RelayParser.CNAME, 0)

        def expr(self):
            return self.getTypedRuleContext(RelayParser.ExprContext,0)


        def getRuleIndex(self):
            return RelayParser.RULE_attr

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




    def attr(self):

        localctx = RelayParser.AttrContext(self, self._ctx, self.state)
        self.enterRule(localctx, 22, self.RULE_attr)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 239
            self.match(RelayParser.CNAME)
            self.state = 240
            self.match(RelayParser.T__11)
            self.state = 241
            self.expr(0)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class TypeParamListContext(ParserRuleContext):

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

        def ident(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.IdentContext)
            else:
                return self.getTypedRuleContext(RelayParser.IdentContext,i)


        def getRuleIndex(self):
            return RelayParser.RULE_typeParamList

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




    def typeParamList(self):

        localctx = RelayParser.TypeParamListContext(self, self._ctx, self.state)
        self.enterRule(localctx, 24, self.RULE_typeParamList)
        self._la = 0 # Token type
        try:
            self.state = 256
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,24,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 243
                self.match(RelayParser.T__6)
                self.state = 244
                self.match(RelayParser.T__7)
                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 245
                self.match(RelayParser.T__6)
                self.state = 246
                self.ident()
                self.state = 251
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                while _la==RelayParser.T__0:
                    self.state = 247
                    self.match(RelayParser.T__0)
                    self.state = 248
                    self.ident()
                    self.state = 253
                    self._errHandler.sync(self)
                    _la = self._input.LA(1)

                self.state = 254
                self.match(RelayParser.T__7)
                pass


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

    class Type_Context(ParserRuleContext):

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


        def getRuleIndex(self):
            return RelayParser.RULE_type_

     
        def copyFrom(self, ctx:ParserRuleContext):
            super().copyFrom(ctx)



    class IntTypeContext(Type_Context):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.Type_Context
            super().__init__(parser)
            self.copyFrom(ctx)

        def NAT(self):
            return self.getToken(RelayParser.NAT, 0)

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


    class TupleTypeContext(Type_Context):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.Type_Context
            super().__init__(parser)
            self.copyFrom(ctx)

        def type_(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.Type_Context)
            else:
                return self.getTypedRuleContext(RelayParser.Type_Context,i)


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


    class TypeIdentTypeContext(Type_Context):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.Type_Context
            super().__init__(parser)
            self.copyFrom(ctx)

        def typeIdent(self):
            return self.getTypedRuleContext(RelayParser.TypeIdentContext,0)


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


    class IncompleteTypeContext(Type_Context):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.Type_Context
            super().__init__(parser)
            self.copyFrom(ctx)


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


    class TensorTypeContext(Type_Context):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.Type_Context
            super().__init__(parser)
            self.copyFrom(ctx)

        def shapeList(self):
            return self.getTypedRuleContext(RelayParser.ShapeListContext,0)

        def type_(self):
            return self.getTypedRuleContext(RelayParser.Type_Context,0)


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


    class FuncTypeContext(Type_Context):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.Type_Context
            super().__init__(parser)
            self.copyFrom(ctx)

        def type_(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.Type_Context)
            else:
                return self.getTypedRuleContext(RelayParser.Type_Context,i)

        def typeParamList(self):
            return self.getTypedRuleContext(RelayParser.TypeParamListContext,0)


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



    def type_(self):

        localctx = RelayParser.Type_Context(self, self._ctx, self.state)
        self.enterRule(localctx, 26, self.RULE_type_)
        self._la = 0 # Token type
        try:
            self.state = 303
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,29,self._ctx)
            if la_ == 1:
                localctx = RelayParser.TupleTypeContext(self, localctx)
                self.enterOuterAlt(localctx, 1)
                self.state = 258
                self.match(RelayParser.T__1)
                self.state = 259
                self.match(RelayParser.T__2)
                pass

            elif la_ == 2:
                localctx = RelayParser.TupleTypeContext(self, localctx)
                self.enterOuterAlt(localctx, 2)
                self.state = 260
                self.match(RelayParser.T__1)
                self.state = 261
                self.type_()
                self.state = 262
                self.match(RelayParser.T__0)
                self.state = 263
                self.match(RelayParser.T__2)
                pass

            elif la_ == 3:
                localctx = RelayParser.TupleTypeContext(self, localctx)
                self.enterOuterAlt(localctx, 3)
                self.state = 265
                self.match(RelayParser.T__1)
                self.state = 266
                self.type_()
                self.state = 269 
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                while True:
                    self.state = 267
                    self.match(RelayParser.T__0)
                    self.state = 268
                    self.type_()
                    self.state = 271 
                    self._errHandler.sync(self)
                    _la = self._input.LA(1)
                    if not (_la==RelayParser.T__0):
                        break

                self.state = 273
                self.match(RelayParser.T__2)
                pass

            elif la_ == 4:
                localctx = RelayParser.TypeIdentTypeContext(self, localctx)
                self.enterOuterAlt(localctx, 4)
                self.state = 275
                self.typeIdent()
                pass

            elif la_ == 5:
                localctx = RelayParser.TensorTypeContext(self, localctx)
                self.enterOuterAlt(localctx, 5)
                self.state = 276
                self.match(RelayParser.T__18)
                self.state = 277
                self.match(RelayParser.T__6)
                self.state = 278
                self.shapeList()
                self.state = 279
                self.match(RelayParser.T__0)
                self.state = 280
                self.type_()
                self.state = 281
                self.match(RelayParser.T__7)
                pass

            elif la_ == 6:
                localctx = RelayParser.FuncTypeContext(self, localctx)
                self.enterOuterAlt(localctx, 6)
                self.state = 283
                self.match(RelayParser.T__14)
                self.state = 285
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                if _la==RelayParser.T__6:
                    self.state = 284
                    self.typeParamList()


                self.state = 287
                self.match(RelayParser.T__1)
                self.state = 296
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << RelayParser.T__1) | (1 << RelayParser.T__14) | (1 << RelayParser.T__18) | (1 << RelayParser.T__19) | (1 << RelayParser.CNAME) | (1 << RelayParser.NAT))) != 0):
                    self.state = 288
                    self.type_()
                    self.state = 293
                    self._errHandler.sync(self)
                    _la = self._input.LA(1)
                    while _la==RelayParser.T__0:
                        self.state = 289
                        self.match(RelayParser.T__0)
                        self.state = 290
                        self.type_()
                        self.state = 295
                        self._errHandler.sync(self)
                        _la = self._input.LA(1)



                self.state = 298
                self.match(RelayParser.T__2)
                self.state = 299
                self.match(RelayParser.T__15)
                self.state = 300
                self.type_()
                pass

            elif la_ == 7:
                localctx = RelayParser.IncompleteTypeContext(self, localctx)
                self.enterOuterAlt(localctx, 7)
                self.state = 301
                self.match(RelayParser.T__19)
                pass

            elif la_ == 8:
                localctx = RelayParser.IntTypeContext(self, localctx)
                self.enterOuterAlt(localctx, 8)
                self.state = 302
                self.match(RelayParser.NAT)
                pass


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

    class ShapeListContext(ParserRuleContext):

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

        def shape(self, i:int=None):
            if i is None:
                return self.getTypedRuleContexts(RelayParser.ShapeContext)
            else:
                return self.getTypedRuleContext(RelayParser.ShapeContext,i)


        def getRuleIndex(self):
            return RelayParser.RULE_shapeList

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




    def shapeList(self):

        localctx = RelayParser.ShapeListContext(self, self._ctx, self.state)
        self.enterRule(localctx, 28, self.RULE_shapeList)
        self._la = 0 # Token type
        try:
            self.state = 318
            self._errHandler.sync(self)
            la_ = self._interp.adaptivePredict(self._input,31,self._ctx)
            if la_ == 1:
                self.enterOuterAlt(localctx, 1)
                self.state = 305
                self.match(RelayParser.T__1)
                self.state = 306
                self.shape()
                self.state = 309 
                self._errHandler.sync(self)
                _la = self._input.LA(1)
                while True:
                    self.state = 307
                    self.match(RelayParser.T__0)
                    self.state = 308
                    self.shape()
                    self.state = 311 
                    self._errHandler.sync(self)
                    _la = self._input.LA(1)
                    if not (_la==RelayParser.T__0):
                        break

                self.state = 313
                self.match(RelayParser.T__2)
                pass

            elif la_ == 2:
                self.enterOuterAlt(localctx, 2)
                self.state = 315
                self.match(RelayParser.T__1)
                self.state = 316
                self.match(RelayParser.T__2)
                pass

            elif la_ == 3:
                self.enterOuterAlt(localctx, 3)
                self.state = 317
                self.shape()
                pass


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

    class MetaContext(ParserRuleContext):

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

        def CNAME(self):
            return self.getToken(RelayParser.CNAME, 0)

        def NAT(self):
            return self.getToken(RelayParser.NAT, 0)

        def getRuleIndex(self):
            return RelayParser.RULE_meta

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




    def meta(self):

        localctx = RelayParser.MetaContext(self, self._ctx, self.state)
        self.enterRule(localctx, 30, self.RULE_meta)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 320
            self.match(RelayParser.T__20)
            self.state = 321
            self.match(RelayParser.T__6)
            self.state = 322
            self.match(RelayParser.CNAME)
            self.state = 323
            self.match(RelayParser.T__7)
            self.state = 324
            self.match(RelayParser.T__6)
            self.state = 325
            self.match(RelayParser.NAT)
            self.state = 326
            self.match(RelayParser.T__7)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class ShapeContext(ParserRuleContext):

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


        def getRuleIndex(self):
            return RelayParser.RULE_shape

     
        def copyFrom(self, ctx:ParserRuleContext):
            super().copyFrom(ctx)



    class ParensShapeContext(ShapeContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ShapeContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def shape(self):
            return self.getTypedRuleContext(RelayParser.ShapeContext,0)


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


    class MetaShapeContext(ShapeContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ShapeContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def meta(self):
            return self.getTypedRuleContext(RelayParser.MetaContext,0)


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


    class IntShapeContext(ShapeContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ShapeContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def NAT(self):
            return self.getToken(RelayParser.NAT, 0)

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



    def shape(self):

        localctx = RelayParser.ShapeContext(self, self._ctx, self.state)
        self.enterRule(localctx, 32, self.RULE_shape)
        try:
            self.state = 334
            self._errHandler.sync(self)
            token = self._input.LA(1)
            if token in [RelayParser.T__20]:
                localctx = RelayParser.MetaShapeContext(self, localctx)
                self.enterOuterAlt(localctx, 1)
                self.state = 328
                self.meta()
                pass
            elif token in [RelayParser.T__1]:
                localctx = RelayParser.ParensShapeContext(self, localctx)
                self.enterOuterAlt(localctx, 2)
                self.state = 329
                self.match(RelayParser.T__1)
                self.state = 330
                self.shape()
                self.state = 331
                self.match(RelayParser.T__2)
                pass
            elif token in [RelayParser.NAT]:
                localctx = RelayParser.IntShapeContext(self, localctx)
                self.enterOuterAlt(localctx, 3)
                self.state = 333
                self.match(RelayParser.NAT)
                pass
            else:
                raise NoViableAltException(self)

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

    class TypeIdentContext(ParserRuleContext):

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

        def CNAME(self):
            return self.getToken(RelayParser.CNAME, 0)

        def getRuleIndex(self):
            return RelayParser.RULE_typeIdent

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




    def typeIdent(self):

        localctx = RelayParser.TypeIdentContext(self, self._ctx, self.state)
        self.enterRule(localctx, 34, self.RULE_typeIdent)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 336
            self.match(RelayParser.CNAME)
        except RecognitionException as re:
            localctx.exception = re
            self._errHandler.reportError(self, re)
            self._errHandler.recover(self, re)
        finally:
            self.exitRule()
        return localctx

    class BodyContext(ParserRuleContext):

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

        def expr(self):
            return self.getTypedRuleContext(RelayParser.ExprContext,0)


        def getRuleIndex(self):
            return RelayParser.RULE_body

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




    def body(self):

        localctx = RelayParser.BodyContext(self, self._ctx, self.state)
        self.enterRule(localctx, 36, self.RULE_body)
        try:
            self.enterOuterAlt(localctx, 1)
            self.state = 338
            self.match(RelayParser.T__3)
            self.state = 339
            self.expr(0)
            self.state = 340
            self.match(RelayParser.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 ScalarContext(ParserRuleContext):

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


        def getRuleIndex(self):
            return RelayParser.RULE_scalar

     
        def copyFrom(self, ctx:ParserRuleContext):
            super().copyFrom(ctx)



    class ScalarFloatContext(ScalarContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ScalarContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def FLOAT(self):
            return self.getToken(RelayParser.FLOAT, 0)

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


    class ScalarBoolContext(ScalarContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ScalarContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def BOOL_LIT(self):
            return self.getToken(RelayParser.BOOL_LIT, 0)

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


    class ScalarIntContext(ScalarContext):

        def __init__(self, parser, ctx:ParserRuleContext): # actually a RelayParser.ScalarContext
            super().__init__(parser)
            self.copyFrom(ctx)

        def NAT(self):
            return self.getToken(RelayParser.NAT, 0)

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



    def scalar(self):

        localctx = RelayParser.ScalarContext(self, self._ctx, self.state)
        self.enterRule(localctx, 38, self.RULE_scalar)
        try:
            self.state = 345
            self._errHandler.sync(self)
            token = self._input.LA(1)
            if token in [RelayParser.FLOAT]:
                localctx = RelayParser.ScalarFloatContext(self, localctx)
                self.enterOuterAlt(localctx, 1)
                self.state = 342
                self.match(RelayParser.FLOAT)
                pass
            elif token in [RelayParser.NAT]:
                localctx = RelayParser.ScalarIntContext(self, localctx)
                self.enterOuterAlt(localctx, 2)
                self.state = 343
                self.match(RelayParser.NAT)
                pass
            elif token in [RelayParser.BOOL_LIT]:
                localctx = RelayParser.ScalarBoolContext(self, localctx)
                self.enterOuterAlt(localctx, 3)
                self.state = 344
                self.match(RelayParser.BOOL_LIT)
                pass
            else:
                raise NoViableAltException(self)

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

    class IdentContext(ParserRuleContext):

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

        def opIdent(self):
            return self.getTypedRuleContext(RelayParser.OpIdentContext,0)


        def GLOBAL_VAR(self):
            return self.getToken(RelayParser.GLOBAL_VAR, 0)

        def LOCAL_VAR(self):
            return self.getToken(RelayParser.LOCAL_VAR, 0)

        def GRAPH_VAR(self):
            return self.getToken(RelayParser.GRAPH_VAR, 0)

        def getRuleIndex(self):
            return RelayParser.RULE_ident

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




    def ident(self):

        localctx = RelayParser.IdentContext(self, self._ctx, self.state)
        self.enterRule(localctx, 40, self.RULE_ident)
        try:
            self.state = 351
            self._errHandler.sync(self)
            token = self._input.LA(1)
            if token in [RelayParser.CNAME]:
                self.enterOuterAlt(localctx, 1)
                self.state = 347
                self.opIdent()
                pass
            elif token in [RelayParser.GLOBAL_VAR]:
                self.enterOuterAlt(localctx, 2)
                self.state = 348
                self.match(RelayParser.GLOBAL_VAR)
                pass
            elif token in [RelayParser.LOCAL_VAR]:
                self.enterOuterAlt(localctx, 3)
                self.state = 349
                self.match(RelayParser.LOCAL_VAR)
                pass
            elif token in [RelayParser.GRAPH_VAR]:
                self.enterOuterAlt(localctx, 4)
                self.state = 350
                self.match(RelayParser.GRAPH_VAR)
                pass
            else:
                raise NoViableAltException(self)

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



    def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int):
        if self._predicates == None:
            self._predicates = dict()
        self._predicates[4] = self.expr_sempred
        pred = self._predicates.get(ruleIndex, None)
        if pred is None:
            raise Exception("No predicate with index:" + str(ruleIndex))
        else:
            return pred(localctx, predIndex)

    def expr_sempred(self, localctx:ExprContext, predIndex:int):
            if predIndex == 0:
                return self.precpred(self._ctx, 18)
         

            if predIndex == 1:
                return self.precpred(self._ctx, 17)
         

            if predIndex == 2:
                return self.precpred(self._ctx, 16)
         

            if predIndex == 3:
                return self.precpred(self._ctx, 15)
         

            if predIndex == 4:
                return self.precpred(self._ctx, 6)
         

            if predIndex == 5:
                return self.precpred(self._ctx, 20)
         

            if predIndex == 6:
                return self.precpred(self._ctx, 10)
         




