예제 #1
0
        static CodeTypeDeclaration _CreateTokenizerClass(LexDocument lex, IList <string> symbolTable, string name, IProgress <FAProgress> progress)
        {
            var lexer = lex.ToLexer(progress);
            var ii    = 0;
            var syms  = new List <string>(symbolTable);
            var bes   = new string[syms.Count];

            for (ii = 0; ii < bes.Length; ii++)
            {
                bes[ii] = lex.GetAttribute(syms[ii], "blockEnd", null) as string;
            }
            lexer = lexer.ToDfa(progress);
            //lexer.TrimDuplicates(progress);
            var dfaTable = lexer.ToArray(syms);
            var result   = new CodeTypeDeclaration();
            var tt       = new List <string>();

            for (int ic = lex.Rules.Count, i = 0; i < ic; ++i)
            {
                var t = lex.Rules[i].Left;
                if (!tt.Contains(t))
                {
                    tt.Add(t);
                }
            }
            tt.Add("#EOS");
            tt.Add("#ERROR");
            for (int ic = syms.Count, i = 0; i < ic; ++i)
            {
                if (!tt.Contains(syms[i]))
                {
                    syms[i] = null;
                }
            }
            result.Name = name;
            result.BaseTypes.Add(typeof(TableTokenizer));
            result.Attributes = MemberAttributes.FamilyOrAssembly;
            CodeMemberField f;

            foreach (var t in tt)
            {
                if (null != t)
                {
                    f                = new CodeMemberField();
                    f.Attributes     = MemberAttributes.Const | MemberAttributes.Public;
                    f.Name           = t.Replace("#", "_").Replace("'", "_").Replace("<", "_").Replace(">", "_");
                    f.Type           = new CodeTypeReference(typeof(int));
                    f.InitExpression = CodeDomUtility.Serialize(syms.IndexOf(t));
                    result.Members.Add(f);
                }
            }

            f            = new CodeMemberField();
            f.Name       = "_Symbols";
            f.Type       = new CodeTypeReference(typeof(string[]));
            f.Attributes = MemberAttributes.Static;
            var arr = new string[syms.Count];

            syms.CopyTo(arr, 0);
            f.InitExpression = CodeDomUtility.Serialize(arr);
            result.Members.Add(f);

            f                = new CodeMemberField();
            f.Name           = "_BlockEnds";
            f.Type           = new CodeTypeReference(typeof(string[]));
            f.Attributes     = MemberAttributes.Static;
            f.InitExpression = CodeDomUtility.Serialize(bes);
            result.Members.Add(f);

            f                = new CodeMemberField();
            f.Name           = "_DfaTable";
            f.Type           = new CodeTypeReference(typeof(CharDfaEntry[]));
            f.Attributes     = MemberAttributes.Static;
            f.InitExpression = CodeDomUtility.Serialize(dfaTable);
            result.Members.Add(f);

            var ctor = new CodeConstructor();

            ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(IEnumerable <char>), "input"));
            ctor.BaseConstructorArgs.AddRange(new CodeExpression[] {
                new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(result.Name), "_DfaTable"),
                new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(result.Name), "_Symbols"),
                new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(result.Name), "_BlockEnds"),
                new CodeArgumentReferenceExpression("input")
            });
            ctor.Attributes = MemberAttributes.Public;
            result.Members.Add(ctor);
            return(result);
        }
예제 #2
0
        static IList <CfgMessage> _CreateParserClass(CfgDocument cfg, string name, IProgress <CfgLL1Progress> progress, out CodeTypeDeclaration parserClass)
        {
            var result = new List <CfgMessage>();
            var sm     = new Dictionary <string, int>();
            var ii     = 0;
            var syms   = new List <string>();

            cfg.FillSymbols(syms);


            foreach (var sym in syms)
            {
                sm.Add(sym, ii);
                ++ii;
            }
            CfgLL1ParseTable pt;

            result.AddRange(cfg.TryToLL1ParseTable(progress, out pt));
            var hasErrors = false;

            foreach (var msg in result)
            {
                if (CfgErrorLevel.Error == msg.ErrorLevel)
                {
                    hasErrors = true;
                    break;
                }
            }
            if (!hasErrors)
            {
                var ipt       = pt.ToArray(syms);
                var nodeFlags = new int[syms.Count];
                for (var i = 0; i < nodeFlags.Length; ++i)
                {
                    var o = cfg.GetAttribute(syms[i], "hidden", false);
                    if (o is bool && (bool)o)
                    {
                        nodeFlags[i] |= 2;
                    }
                    o = cfg.GetAttribute(syms[i], "collapsed", false);
                    if (o is bool && (bool)o)
                    {
                        nodeFlags[i] |= 1;
                    }
                }
                var substitutions = new int[syms.Count];
                for (var i = 0; i < substitutions.Length; i++)
                {
                    var s = cfg.GetAttribute(syms[i], "substitute", null) as string;
                    if (!string.IsNullOrEmpty(s) && cfg.IsSymbol(s) && s != syms[i])
                    {
                        substitutions[i] = cfg.GetIdOfSymbol(s);
                    }
                    else
                    {
                        substitutions[i] = -1;
                    }
                }
                var attrSets = new KeyValuePair <string, object> [syms.Count][];
                for (ii = 0; ii < attrSets.Length; ii++)
                {
                    CfgAttributeList attrs;
                    if (cfg.AttributeSets.TryGetValue(syms[ii], out attrs))
                    {
                        attrSets[ii] = new KeyValuePair <string, object> [attrs.Count];
                        var j = 0;
                        foreach (var attr in attrs)
                        {
                            attrSets[ii][j] = new KeyValuePair <string, object>(attr.Name, attr.Value);
                            ++j;
                        }
                    }
                    else
                    {
                        attrSets[ii] = null;
                    }
                }


                parserClass            = new CodeTypeDeclaration();
                parserClass.Name       = name;
                parserClass.Attributes = MemberAttributes.FamilyOrAssembly;
                parserClass.BaseTypes.Add(typeof(LL1TableParser));
                CodeMemberField f;
                foreach (var s in syms)
                {
                    if (null != s)
                    {
                        f                = new CodeMemberField();
                        f.Attributes     = MemberAttributes.Const | MemberAttributes.Public;
                        f.Name           = s.Replace("#", "_").Replace("'", "_").Replace("<", "_").Replace(">", "_");
                        f.Type           = new CodeTypeReference(typeof(int));
                        f.InitExpression = CodeDomUtility.Serialize(cfg.GetIdOfSymbol(s));
                        parserClass.Members.Add(f);
                    }
                }
                f                = new CodeMemberField();
                f.Attributes     = MemberAttributes.Static;
                f.Name           = "_Symbols";
                f.Type           = new CodeTypeReference(typeof(string[]));
                f.InitExpression = CodeDomUtility.Serialize(syms.ToArray());
                parserClass.Members.Add(f);

                f                = new CodeMemberField();
                f.Attributes     = MemberAttributes.Static;
                f.Name           = "_ParseTable";
                f.Type           = new CodeTypeReference(typeof(int[][][]));
                f.InitExpression = CodeDomUtility.Serialize(ipt);
                parserClass.Members.Add(f);

                f                = new CodeMemberField();
                f.Attributes     = MemberAttributes.Static;
                f.Name           = "_InitCfg";
                f.Type           = new CodeTypeReference(typeof(int[]));
                f.InitExpression = CodeDomUtility.Serialize(new int[] { cfg.GetIdOfSymbol(cfg.StartSymbol), cfg.FillNonTerminals().Count });
                parserClass.Members.Add(f);

                f                = new CodeMemberField();
                f.Attributes     = MemberAttributes.Static;
                f.Name           = "_NodeFlags";
                f.Type           = new CodeTypeReference(typeof(int[]));
                f.InitExpression = CodeDomUtility.Serialize(nodeFlags);
                parserClass.Members.Add(f);

                f                = new CodeMemberField();
                f.Attributes     = MemberAttributes.Static;
                f.Name           = "_Substitutions";
                f.Type           = new CodeTypeReference(typeof(int[]));
                f.InitExpression = CodeDomUtility.Serialize(substitutions);
                parserClass.Members.Add(f);

                f                = new CodeMemberField();
                f.Attributes     = MemberAttributes.Static;
                f.Name           = "_AttributeSets";
                f.Type           = new CodeTypeReference(attrSets.GetType());
                f.InitExpression = CodeDomUtility.Serialize(attrSets);
                parserClass.Members.Add(f);

                var ctor = new CodeConstructor();
                ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(IEnumerable <Token>), "tokenizer"));
                ctor.BaseConstructorArgs.AddRange(new CodeExpression[] {
                    new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(parserClass.Name), "_ParseTable"),
                    new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(parserClass.Name), "_InitCfg"),
                    new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(parserClass.Name), "_Symbols"),
                    new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(parserClass.Name), "_NodeFlags"),
                    new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(parserClass.Name), "_Substitutions"),
                    new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(parserClass.Name), "_AttributeSets"),
                    new CodeArgumentReferenceExpression("tokenizer")
                });
                ctor.Attributes = MemberAttributes.Public;
                parserClass.Members.Add(ctor);
                ctor = new CodeConstructor();
                ctor.ChainedConstructorArgs.AddRange(new CodeExpression[] { new CodePrimitiveExpression(null) });
                ctor.Attributes = MemberAttributes.Public;
                parserClass.Members.Add(ctor);
            }
            else
            {
                parserClass = null;
            }
            return(result);
        }