Пример #1
0
        public bool GenerateAllCodes(string idl, string template, string dir)
        {
            if (!File.Exists(idl))
            {
                Console.WriteLine("IDL文件{0}不存在!", idl);
                return(false);
            }
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }


            string idlfile    = Path.GetFileName(idl);
            string rawname    = idlfile.Substring(0, idlfile.IndexOf('.'));
            string aa_bb_name = NameMangling(rawname, NameManglingType.aa_bb);
            string AaBbName   = NameMangling(rawname, NameManglingType.AaBb);

            string tplfile  = Path.GetFileName(template).Replace("Template", AaBbName).Replace("template", aa_bb_name);
            string codefile = Path.Combine(dir, tplfile);

            if (File.Exists(codefile) &&
                !m_file_time_checker.IsModified(idl) &&
                !m_file_time_checker.IsModified(template))
            {
                return(true);
            }

            IDLMeta meta = ParseIDL(idl);

            if (meta == null)
            {
                return(false);
            }
            meta.lang           = GetLanguageByTemplateExt(Path.GetExtension(template));
            meta.code_file_name = tplfile.Substring(0, tplfile.IndexOf('.'));
            if (!GenerateCode(meta, template, codefile))
            {
                Console.WriteLine("生成IDL文件{0}的代码失败!", idl);
                return(false);
            }
            Console.WriteLine("生成代码文件:{0}成功", codefile);

            m_file_time_checker.SetFileTime(idl);
            m_file_time_checker.SetFileTime(template);
            return(true);
        }
Пример #2
0
        public static IDLEnum FindUsingEnum(IDLMeta meta, string enum_name)
        {
            if (meta.meta_enum.TryGetValue(enum_name, out IDLEnum enumtype))
            {
                return(enumtype);
            }

            foreach (var u in meta.meta_using)
            {
                var c = CodeGenHelper.FindMetaEnum(u.using_name, enum_name);
                if (c != null)
                {
                    return(c);
                }
            }
            return(null);
        }
Пример #3
0
        public IDLMeta ParseIDL(string idl)
        {
            IDLMeta meta      = null;
            string  meta_name = Path.GetFileNameWithoutExtension(idl).Split('.')[0];

            if (!all_xml_meta.TryGetValue(meta_name, out meta))
            {
                try
                {
                    meta = IDLParser.Parse(idl);
                }
                catch (Exception e)
                {
                    Console.WriteLine("解析IDL文件{0}失败,{1}", idl, e);
                    return(null);
                }
                all_xml_meta.Add(meta_name, meta);
            }
            return(meta);
        }
Пример #4
0
        public static IDLClass FindUsingClass(IDLMeta meta, string class_name)
        {
            if (class_name == null)
            {
                return(null);
            }
            if (meta.meta_class.TryGetValue(class_name, out IDLClass classtype))
            {
                return(classtype);
            }

            foreach (var u in meta.meta_using)
            {
                var c = CodeGenHelper.FindMetaClass(u.using_name, class_name);
                if (c != null)
                {
                    return(c);
                }
            }
            return(null);
        }
Пример #5
0
        public bool GenerateCode(IDLMeta meta, string template, string codefile)
        {
            string[] lines = File.ReadAllLines(template);
            //解析规则
            var rules = TemplateRuleParser.Parse(lines.ToList());
            //展开规则
            List <string> code = new List <string>();
            TemplateData  data = new TemplateData();

            data.SetGlobalVariant("Meta", meta);
            //meta变量注入
            foreach (var kv in meta.meta_variant)
            {
                data.SetGlobalVariant(kv.Key, kv.Value);
            }
            foreach (var rule in rules)
            {
                var code_line = rule.Apply(data);
                code.AddRange(code_line);
            }
            //删除旧文件
            if (File.Exists(codefile))
            {
                File.SetAttributes(codefile, FileAttributes.Normal);
                File.Delete(codefile);
            }
            //写入文件
            using (FileStream fs = new FileStream(codefile, FileMode.Create, FileAccess.Write))
            {
                using (StreamWriter sw = new StreamWriter(fs))
                {
                    foreach (var line in code)
                    {
                        sw.WriteLine(line);
                    }
                }
            }
            return(true);
        }
Пример #6
0
        public static bool ParseFieldType(IDLMeta meta, string typename, IDLType fieldtype, bool undefinedasclass = false)
        {
            fieldtype.type_name = typename;
            switch (typename)
            {
            case "int": { fieldtype.type = eIDLType.INT; return(true); }

            case "float": { fieldtype.type = eIDLType.FLOAT; return(true); }

            case "string": { fieldtype.type = eIDLType.STRING; return(true); }

            case "bool": { fieldtype.type = eIDLType.BOOL; return(true); }

            default:
                break;
            }
            Match m = Regex.Match(typename, @"List<(\w+)>");

            if (m.Success)
            {
                fieldtype.type       = eIDLType.LIST;
                fieldtype.inner_type = new IDLType[1] {
                    new IDLType()
                };
                string inner_name = m.Groups[1].Value;
                if (!ParseFieldType(meta, inner_name, fieldtype.inner_type[0], undefinedasclass))
                {
                    return(false);
                }
                return(true);
            }

            m = Regex.Match(typename, @"Dict<(\w+),(\w+)>");
            if (m.Success)
            {
                fieldtype.type       = eIDLType.DICT;
                fieldtype.inner_type = new IDLType[2] {
                    new IDLType(), new IDLType()
                };
                string key_name = m.Groups[1].Value;
                if (!ParseFieldType(meta, key_name, fieldtype.inner_type[0]))
                {
                    return(false);
                }
                string value_name = m.Groups[2].Value;
                if (!ParseFieldType(meta, value_name, fieldtype.inner_type[1], undefinedasclass))
                {
                    return(false);
                }
                return(true);
            }

            if (FindUsingClass(meta, typename) != null)
            {
                fieldtype.type = eIDLType.CLASS;
                return(true);
            }

            if (FindUsingEnum(meta, typename) != null)
            {
                fieldtype.type = eIDLType.ENUM;
                return(true);
            }

            if (undefinedasclass)
            {
                fieldtype.type = eIDLType.CLASS;
                return(true);
            }
            Console.WriteLine("解析类型名称错误,未能识别{0}", typename);
            return(false);
        }
Пример #7
0
        public static IDLMeta Parse(string idl)
        {
            IDLMeta  meta    = new IDLMeta();
            IDLClass m_class = null;
            IDLEnum  m_enum  = null;

            string[] lines    = File.ReadAllLines(idl);
            string   metaname = new string(Path.GetFileNameWithoutExtension(idl).TakeWhile(c => c != '.').ToArray());

            meta.meta_file_path = Path.Combine(Path.GetDirectoryName(idl), metaname).Replace('\\', '/');
            meta.meta_name      = CodeGenHelper.NameMangling(metaname, NameManglingType.AaBb);
            string     comment      = null;
            IDLAttr    attr         = null;
            ParseState m_parseState = ParseState.End;

            for (int i = 0; i < lines.Count(); i++)
            {
                //注释
                string cc = parseComment(ref lines[i]);
                if (!string.IsNullOrEmpty(cc))
                {
                    comment = cc;
                }
                //空行
                if (Regex.IsMatch(lines[i], @"^\s*$"))
                {
                    continue;
                }
                //特性
                if (Regex.IsMatch(lines[i], @"^\s*\[.*\]\s*$"))
                {
                    attr = IDLAttr.ParseAttr(lines[i]);
                    continue;
                }
                //变量
                Match match = Regex.Match(lines[i], @"^\s*set\s+(\w+)\s*=\s*(\w+)\s*;\s*$");
                if (match.Success)
                {
                    string key = match.Groups[1].Value;
                    string val = match.Groups[2].Value;
                    meta.meta_variant.Add(key, val);
                    continue;
                }
                //引用
                match = Regex.Match(lines[i], @"^\s*using\s+(\w+)\s*;\s*$");
                if (match.Success)
                {
                    IDLUsing u = new IDLUsing();
                    u.comment    = comment;
                    u.using_name = match.Groups[1].Value;
                    u.Meta       = meta;
                    meta.meta_using.Add(u);
                    comment = null;
                    continue;
                }

                //结束
                if (Regex.IsMatch(lines[i], @"^\s*};?\s*$"))
                {
                    if (m_parseState == ParseState.End)
                    {
                        throw new Exception($"idl文件错误:第{i + 1}行,{lines[i]}");
                    }
                    if (m_parseState == ParseState.BeginClass)
                    {
                        meta.meta_class.Add(m_class.class_name, m_class);
                        m_class = null;
                    }
                    else if (m_parseState == ParseState.BeginEnum)
                    {
                        meta.meta_enum.Add(m_enum.enum_name, m_enum);
                        m_enum = null;
                    }
                    m_parseState = ParseState.End;

                    continue;
                }
                //开始
                if (Regex.IsMatch(lines[i], @"^\s*{\s*$"))
                {
                    if (m_parseState != ParseState.BeginClass && m_parseState != ParseState.BeginEnum)
                    {
                        throw new Exception($"idl文件错误:第{i + 1}行,{lines[i]}");
                    }
                    continue;
                }
                //枚举开始
                match = Regex.Match(lines[i], @"^\s*enum\s*(\w+)\s*{?\s*$");
                if (match.Success)
                {
                    if (m_parseState != ParseState.End)
                    {
                        throw new Exception($"idl文件错误:第{i + 1}行,{lines[i]}");
                    }
                    m_parseState     = ParseState.BeginEnum;
                    m_enum           = new IDLEnum();
                    m_enum.comment   = comment;
                    m_enum.enum_name = match.Groups[1].Value;
                    m_enum.Meta      = meta;
                    attr             = null;//用完清空
                    comment          = null;
                    continue;
                }

                //结构体开始
                match = Regex.Match(lines[i], @"^\s*(struct|class)\s*(\w+)\s*{?\s*$");
                if (match.Success)
                {
                    if (m_parseState != ParseState.End)
                    {
                        throw new Exception($"idl文件错误:第{i + 1}行,{lines[i]}");
                    }
                    m_parseState       = ParseState.BeginClass;
                    m_class            = new IDLClass();
                    m_class.comment    = comment;
                    m_class.class_name = match.Groups[2].Value;
                    m_class.Meta       = meta;
                    if (attr != null)
                    {
                        m_class.attrs.Add(attr);
                    }
                    if (attr != null && attr.attr_name == "root")
                    {
                        meta.root_class_name = m_class.class_name;
                    }
                    attr    = null;//用完清空
                    comment = null;
                    continue;
                }


                //结构体
                if (m_parseState == ParseState.BeginClass)
                {
                    parseGenericType(ref lines[i]);
                    string def = parseDefaultValue(ref lines[i]);
                    Match  m   = Regex.Match(lines[i], @"\s*(\S+)\s+(\w+)\s*;\s*$");
                    if (m.Success == false)
                    {
                        throw new Exception($"idl文件错误:第{i + 1}行,{lines[i]}");
                    }

                    IDLClassField field = new IDLClassField();
                    field.comment       = comment;
                    field.type_name     = m.Groups[1].Value;
                    field.field_name    = m.Groups[2].Value;
                    field.default_value = def;
                    if (attr != null)
                    {
                        field.attrs.Add(attr);
                    }
                    field.Class = m_class;
                    if (!ParseFieldType(meta, field.type_name, field.field_type, true))
                    {
                        throw new Exception($"idl文件错误:第{i + 1}行,{lines[i]}");
                    }
                    m_class.fieldList.Add(field);
                    attr    = null;//用完清空
                    comment = null;
                    continue;
                }

                //枚举
                if (m_parseState == ParseState.BeginEnum)
                {
                    Match m = Regex.Match(lines[i], @"\s*(\w+)\s*=\s*(\w+)\s*,\s*$");
                    if (m.Success == false)
                    {
                        throw new Exception($"idl文件错误:第{i + 1}行,{lines[i]}");
                    }

                    IDLEnumField item = new IDLEnumField();
                    item.comment    = comment;
                    item.item_name  = m.Groups[1].Value;
                    item.item_value = m.Groups[2].Value;
                    item.Enum       = m_enum;
                    m_enum.enum_fields.Add(item.item_name, item);
                    attr    = null;//用完清空
                    comment = null;
                    continue;
                }

                throw new Exception($"idl文件错误:第{i + 1}行,{lines[i]}");
            }
            return(meta);
        }