static void ParseGrammarToSpaceObjectMap(List <string> grammartospaceobjects)
        {
            /*
             * {
             *  REAL1_EXPR ={ Euclidean.Angle,Vector.Scalar}
             *  REAL3_EXPR ={ Euclidean.Rotation,Euclidean.Orientation,Vector.Vector,Affine.Point}
             *  MATRIX_EXPR ={ Vector.Scaling,Vector.Shear,Vector.BasisChange, Affine.FrameChange, Euclidean.Rotation}
             *  REAL4_EXPR ={ Euclidean.Rotation,Euclidean.Orientation,Affine.HomogenousPoint}
             * }*/
            Func <string, bool> begin = (ln) => ln.Trim() == "{";
            Func <string, bool> end   = (ln) => ln.Trim() == "}";

            int
                prematch = 1,
                matched  = 2;//,
            //exSpace = 3,
            // instance = 4;

            int current = prematch;

            try
            {
                foreach (var lin in grammartospaceobjects)
                {
                    var line = lin.Length > 0 && lin[0] == '\t' ? lin.Substring(1) : lin;


                    if (isComment(line))
                    {
                        continue;
                    }
                    else if (current == prematch && begin(line))
                    {
                        current = matched;
                    }
                    else if (current == matched && !string.IsNullOrEmpty(line) && !end(line))
                    {
                        var pattern = Regex.Escape("{") + "(.*)" + Regex.Escape("}") + @"(?:,(\w*))*";

                        var stripped = Regex.Replace(line, @"\s+", "");

                        var prodName = Grammar.TrimProductionType(stripped.Split('=')[0]);

                        var prod = Instance.Grammar.Productions.Single(prod_ => prod_.Name == prodName ||
                                                                       (prod_.ProductionType == Grammar.ProductionType.Single || prod_.ProductionType == Grammar.ProductionType.CaptureSingle) && prod_.Name.Contains(prodName));

                        var match = Regex.Match(stripped.Split('=')[1], pattern).Groups[1].Value;

                        foreach (var objType in match.Split(','))
                        {
                            var spaceCat = objType.Split('.')[0];
                            var objName  = objType.Split('.')[1];

                            var matchedSpaces = Instance.Spaces.Where(sp_ => sp_.Category.Category == spaceCat).ToList();

                            foreach (var sp in matchedSpaces)
                            {
                                var obj = sp.Category.Objects.Single(obj_ => obj_.Name == objName);


                                var spaceObjDict = Space.RetrieveInheritedObjects(sp, obj, Instance.Spaces);
                                Instance.GrammarRuleToSpaceObjectMap[prod] = Instance.GrammarRuleToSpaceObjectMap.ContainsKey(prod) ? Instance.GrammarRuleToSpaceObjectMap[prod]: new List <MonoHack>();
                                spaceObjDict.Keys.ToList().ForEach(key => Instance.GrammarRuleToSpaceObjectMap[prod].Add(new MonoHack()
                                {
                                    Item1 = key, Item2 = spaceObjDict[key]
                                }));
                            }
                        }
                    }
                    else if (current == matched && end(line))
                    {
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            //var initial = Instance.Spaces.Where(s_ => s_.Inherits == default(Space.SpaceCategory)).ToList();

            // Space.PropagateInheritance(initial, Instance.Spaces);
        }
        static void ParseGrammar(List <string> grammar)
        {
            var curProd = new Grammar.Production(); curProd = null;
            var curCase = new Grammar.Case(); curCase = null;

            try
            {
                foreach (var line in grammar)
                {
                    var fixedline = line.Length > 0 && line[0] == '\t' ? line.Substring(1) : line;


                    if (isComment(fixedline))
                    {
                        continue;
                    }
                    else if (string.IsNullOrEmpty(fixedline) && curProd != null)
                    {
                        curProd = null;
                    }
                    else if (string.IsNullOrEmpty(fixedline) && curProd == null)
                    {
                        continue;
                    }
                    else if (curCase == null && curProd != null)
                    {
                        var captionmatch = Regex.Match(fixedline, @"([^~]*)((?:~)((\w|\s)*))?");


                        var toks = captionmatch.Groups[1].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).ToList().Select(tok_ => tok_.Trim()).ToList();

                        bool isLast = !toks.Contains("|");

                        var coordsandinterp = toks.Where(tok_ => tok_.Contains("<") && tok_.Contains(">")).ToList();

                        var commandwrapper = toks.Where(tok_ => tok_[0] == '@' && tok_[tok_.Length - 1] == '@').Select(tok_ => tok_.Substring(1, tok_.Length - 2)).ToList();

                        var cmd = commandwrapper.Count == 0 ? default(Grammar.Command) : new Grammar.Command()
                        {
                            Production = commandwrapper[0].Split(',')[0], Case = commandwrapper[0].Split(',')[1], NameSuffix = commandwrapper[0].Split(',')[2]
                        };



                        toks = toks
                               .Where(tok_ => tok_ != "|" && !(tok_.Contains("<") && tok_.Contains(">")))
                               .Where(tok_ => !(tok_[0] == '@' && tok_[tok_.Length - 1] == '@'))
                               .ToList();

                        /*
                         * +EXPR :=
                         +REAL1_EXPR |
                         +REAL3_EXPR |
                         +REAL4_EXPR |
                         +MATRIX_EXPR
                         * */

                        bool isFuncDeclare = toks[0][0] == 'f';
                        if (isFuncDeclare)
                        {
                            toks[0] = toks[0].Substring(1);
                        }
                        bool isTransDeclare = toks[0][0] == 't';
                        if (isTransDeclare)
                        {
                            toks[0] = toks[0].Substring(1);
                        }
                        bool isVarDeclare = toks[0][0] == 'v';
                        if (isVarDeclare)
                        {
                            toks[0] = toks[0].Substring(1);
                        }

                        var linkSpace = (toks.Count > 1 && toks[1][1] == 's');
                        if (linkSpace)
                        {
                            toks[1] = toks[1][0] + toks[1].Substring(2);
                        }
                        var ct = Grammar.TokenToCaseTypeMap(toks);


                        curCase = new Grammar.Case()
                        {
                            CaseType = ct,
                            Name     = //ct ==
                                       // Grammar.CaseType.Value ? curProd.Name + (valueCount) :
                                       //? "IDENT" :
                                       ct == Grammar.CaseType.Pure || ct == Grammar.CaseType.Pure ? curProd.Name + "_" + string.Join("_", toks.Select(t_ => Grammar.TrimProductionType(t_))) :
                                       string.Join("_", toks.Select(t_ => Grammar.TrimProductionType(t_))),
                            ProductionRefs =
                                ct == Grammar.CaseType.Hidden ||
                                ct == Grammar.CaseType.Op ||
                                ct == Grammar.CaseType.ArrayOp ? toks.Skip(1).ToList() : ct == Grammar.CaseType.Inherits ||
                                ct == Grammar.CaseType.Array ||
                                ct == Grammar.CaseType.Pure ||
                                // ct == Grammar.CaseType.Value ||
                                ct == Grammar.CaseType.Passthrough ? toks
                                    : new List <string>(),
                            Productions          = new List <Grammar.Production>(), //fix this.... these need to "resolve" incrementally
                            Description          = captionmatch.Groups.Count > 2 ? captionmatch.Groups[3].Value : ""
                            , CoordsToString     = (p) => { return("\"Not implemented\";"); },
                            InterpTranslation    = (p, s, sp) => { return("\"Not implemented\";"); },
                            Production           = curProd,
                            Command              = cmd,
                            IsTranslationDeclare = isTransDeclare,
                            IsFuncDeclare        = isFuncDeclare,
                            IsVarDeclare         = isVarDeclare,
                            LinkSpace            = linkSpace,
                            // ValueType = valueType,
                            // ValueCount = valueCount,
                            // ValueDefault = valueDefault
                        };

                        if (coordsandinterp.Count == 2)
                        {
                            curCase.ParseCoordsToString(coordsandinterp[0]);
                            curCase.ParseInterpTranslation(coordsandinterp[1]);
                        }
                        else if (cmd is Grammar.Command || curProd.Command is Grammar.Command)
                        {
                            curCase.ParseCoordsToString(true);
                            curCase.ParseInterpTranslation(true);
                        }
                        curProd.Cases.Add(curCase);

                        curCase = null;

                        if (isLast)
                        {
                            curProd = null;
                        }
                    }
                    else if (curProd == null)
                    {
                        var toks           = fixedline.Split(' ').Where(tok_ => tok_.Length > 1);
                        var commandwrapper = toks.Where(tok_ => tok_[0] == '@' && tok_[tok_.Length - 1] == '@').Select(tok_ => tok_.Substring(1, tok_.Length - 2)).ToList();

                        var cmd = commandwrapper.Count == 0 ? default(Grammar.Command) : new Grammar.Command()
                        {
                            Production = commandwrapper[0].Split(',')[0], Case = commandwrapper[0].Split(',')[1], NameSuffix = commandwrapper[0].Split(',')[2]
                        };

                        if (cmd is Grammar.Command)
                        {
                            fixedline = fixedline.Replace('@' + commandwrapper[0] + '@', "");
                        }

                        //var last = fixedline.IndexOf(" :=");

                        bool isDeclare = (fixedline[1] == '#');
                        if (isDeclare)
                        {
                            fixedline = fixedline[0] + fixedline.Substring(2);
                        }

                        bool isFuncDeclare = fixedline[1] == 'f';
                        if (isFuncDeclare)
                        {
                            fixedline = fixedline[0] + fixedline.Substring(2);
                        }
                        bool isTransDeclare = fixedline[1] == 't';
                        if (isTransDeclare)
                        {
                            fixedline = fixedline[0] + fixedline.Substring(2);
                        }
                        bool isVarDeclare = fixedline[1] == 'v';
                        if (isVarDeclare)
                        {
                            fixedline = fixedline[0] + fixedline.Substring(2);
                        }
                        //Console.WriteLine(fixedline);

                        var toksvcheck = fixedline.Replace(" :=", "").Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).ToList();

                        var valueType             = "";
                        var valueCount            = 0;
                        var valueDefault          = "";
                        Grammar.ValueContainer vc = default(Grammar.ValueContainer);
                        if (toksvcheck.Count > 1)
                        {
                            var vstr = toksvcheck[1].Substring(toksvcheck[1].IndexOf("(") + 1, toksvcheck[1].Length - toksvcheck[1].IndexOf("(") - 2).Split(',');
                            valueType  = vstr[0];
                            valueCount = int.Parse(vstr[1]);
                            if (vstr.Length > 2)
                            {
                                valueDefault = vstr[2];
                            }

                            vc = new Grammar.ValueContainer()
                            {
                                ValueCount = valueCount, ValueDefault = valueDefault, ValueType = valueType
                            };
                        }

                        curProd = new Grammar.Production()
                        {
                            ProductionType = Grammar.TokenToProductionTypeMap[fixedline[0]],

                            Name                 = Grammar.TrimProductionType(toksvcheck[0]).Trim(),
                            HasPassthrough       = false,
                            Passthrough          = default(Grammar.Production),
                            Command              = cmd,
                            IsTranslationDeclare = isTransDeclare,
                            IsFuncDeclare        = isFuncDeclare,
                            IsVarDeclare         = isVarDeclare,
                            Cases                = new List <Grammar.Case>(),
                            ValueContainer       = vc
                        };

                        Instance.Grammar.Productions.Add(curProd);
                    }
                }
                var t = default(List <Grammar.Production>);
                foreach (var prod in Instance.Grammar.Productions)
                {
                    if (prod.ProductionType == Grammar.ProductionType.Single || prod.ProductionType == Grammar.ProductionType.CaptureSingle)
                    {
                        prod.Name = prod.Name + "_" + prod.Cases[0].Name;
                    }

                    foreach (var pcase in prod.Cases)
                    {
                        //if (pcase.CaseType == Grammar.CaseType.Value)
                        //    continue;

                        foreach (var pref in pcase.ProductionRefs)
                        {
                            t = Instance.Grammar.Productions.Where(p_ => p_.Name == Grammar.TrimProductionType(pref)).ToList();
                            //Console.WriteLine(pcase.Name + " " + pref);
                            pcase.Productions.Add(Instance.Grammar.Productions.Single(p_ => p_.Name == Grammar.TrimProductionType(pref)));
                        }

                        if (pcase.CaseType == Grammar.CaseType.Passthrough)
                        {
                            prod.HasPassthrough = true;
                            pcase.Productions[0].Passthrough = prod;
                        }
                        if (pcase.CaseType == Grammar.CaseType.Inherits)
                        {
                            prod.HasInherits = true;

                            pcase.Productions[0].Inherits = prod;
                            //pcase.CaseType = Grammar.CaseType.Pure;
                        }
                    }
                }
            }
            catch (Exception ex) {
                Console.WriteLine(ex.StackTrace);
            }
        }