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); }
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); }
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); }
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); }
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); }
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); }
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); }