public static LalFile Parse(string file) { var fileContent = File.ReadAllText(file); var lalFile = new LalFile(); ParseFileOptions(lalFile, ref fileContent); ParseTypeName(lalFile, ref fileContent); ParseFields(lalFile, ref fileContent); return lalFile; }
static void ParseFileOptions(LalFile lalFile, ref string fileContent) { var fileOptionsMatch = Regex.Match(fileContent, "//.*FileOptions.*:(.*)\\s"); // We need exactly 2 results. if (fileOptionsMatch.Groups.Count == 2) { lalFile.FileOptions = (FileFlags)Enum.Parse(typeof(FileFlags), fileOptionsMatch.Groups[1].Value.Trim(' ')); fileContent = fileContent.Replace(fileOptionsMatch.Groups[0].Value, ""); } //else //MessageBox.Show("Error while parsing FileOptions."); }
static void ParseTypeName(LalFile lalFile, ref string fileContent) { // Matches the Name between 'type' and the next '{'. var typeMatch = Regex.Match(fileContent, "type(.+?)\\s\\{"); // We need exactly 2 results. if (typeMatch.Groups.Count == 2) { lalFile.TypeName = Regex.Replace(typeMatch.Groups[1].Value.Trim(' '), @"\s+", ""); fileContent = fileContent.Replace(typeMatch.Groups[0].Value, ""); } else Console.WriteLine("Error while parsing type name."); }
static void ParseFields(LalFile lalFile, ref string fileContent) { // Remove any white space/tab/new line char. fileContent = Regex.Replace(fileContent, @"\s+", ""); var typeSplit = fileContent.Split(new[] { "List", "};" }, StringSplitOptions.RemoveEmptyEntries); foreach (var t in typeSplit) { if (t.StartsWith("->")) { var m = Regex.Match(t, "->(.+?),(.+?)\\{([^}]*)"); var lalField = new LalField(); lalField.Name = m.Groups[1].Value; var count = 0; if (int.TryParse(m.Groups[2].Value, out count)) lalField.Count = count; else lalField.CountField = m.Groups[2].Value; lalField.Type = typeof(LalList); lalField.Value = new LalList(); var fields = Regex.Matches(m.Groups[3].Value, "(.+?)->(.+?);"); //for (var i = 0; i < lalField.Count; i++) { foreach (Match m2 in fields) { if (m2.Groups[2].Value.Contains(",")) { var countInfo = m2.Groups[2].Value.Split(new[] { ',' }); if (int.TryParse(countInfo[1], out count)) { ((LalList)lalField.Value).Fields.Add(countInfo[0], new LalField { Name = countInfo[0], Count = count, Type = LalTypeMapper.ReadValue[m2.Groups[1].Value].MakeArrayType() }); } else { var lalField2 = new LalField(); lalField2.Name = countInfo[0]; lalField2.CountField = countInfo[1]; lalField2.Type = LalTypeMapper.ReadValue[m2.Groups[1].Value]; if (m2.Groups[1].Value != "string" && m2.Groups[1].Value != "Bit") lalField2.Type = typeof(List<>).MakeGenericType(lalField2.Type); else lalField2.Type = lalField2.Type.MakeArrayType(); ((LalList)lalField.Value).Fields.Add(countInfo[0], lalField2); } } else { ((LalList)lalField.Value).Fields.Add(m2.Groups[2].Value, new LalField { Name = m2.Groups[2].Value, Type = LalTypeMapper.ReadValue[m2.Groups[1].Value] }); } } } lalFile.Fields.Add(lalField.Name, lalField); } else { var count = 0; var fields = Regex.Matches(t, "(.+?)->(.+?);"); foreach (Match m2 in fields) { var lalField = new LalField(); if (m2.Groups[2].Value.Contains(",")) { var countInfo = m2.Groups[2].Value.Split(new[] { ',' }); if (int.TryParse(countInfo[1], out count)) { lalField.Name = countInfo[0]; lalField.Count = count; lalField.Type = LalTypeMapper.ReadValue[m2.Groups[1].Value].MakeArrayType(); } else { lalField.Name = countInfo[0]; lalField.CountField = countInfo[1]; lalField.Type = LalTypeMapper.ReadValue[m2.Groups[1].Value]; if (m2.Groups[1].Value != "string" && m2.Groups[1].Value != "Bit") lalField.Type = typeof(List<>).MakeGenericType(lalField.Type); else lalField.Type = lalField.Type.MakeArrayType(); } } else { lalField.Name = m2.Groups[2].Value; lalField.Type = LalTypeMapper.ReadValue[m2.Groups[1].Value]; } lalFile.Fields.Add(lalField.Name, lalField); } } } }
public static Tuple<Type, Dictionary<Tuple<string, string>, Array>, Dictionary<Tuple<string, string>, string>, FileFlags> CreateType(LalFile lalFile) { var typeName = lalFile.TypeName; var fields = new Dictionary<string, Type>(); var additionalArrayInfo = new Dictionary<Tuple<string, string>, Array>(); var additionalListInfo = new Dictionary<Tuple<string, string>, string>(); //additionalFieldInfo.Add(fieldName, Activator.CreateInstance(fieldType, new object[] { length }) as Array); var assemblyName = new AssemblyName(); assemblyName.Name = typeName; var assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); var module = assemblyBuilder.DefineDynamicModule(typeName); var typeBuilder = module.DefineType(typeName, TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit, typeof(object)); foreach (var f in lalFile.Fields) { if (f.Value.Type == typeof(LalList)) { var listType = module.DefineType(f.Key, TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit, typeof(object)); foreach (var listFields in ((LalList)f.Value.Value).Fields) { if (listFields.Value.Type.IsArray || listFields.Value.Type.IsGenericType) { if (!string.IsNullOrEmpty(listFields.Value.CountField)) additionalListInfo.Add(Tuple.Create(f.Key, listFields.Key), listFields.Value.CountField); else if (listFields.Value.Count != -1) additionalArrayInfo.Add(Tuple.Create(f.Key, listFields.Key), Activator.CreateInstance(listFields.Value.Type, new object[] { listFields.Value.Count }) as Array); } listType.DefineField(listFields.Key, listFields.Value.Type, FieldAttributes.Public); } var lType = listType.CreateType(); if (!string.IsNullOrEmpty(f.Value.CountField)) { additionalListInfo.Add(Tuple.Create(typeName, f.Key), f.Value.CountField); lType = typeof(List<>).MakeGenericType(lType); } else if (f.Value.Count != -1) { lType = lType.MakeArrayType(); additionalArrayInfo.Add(Tuple.Create(typeName, f.Key), Activator.CreateInstance(lType, new object[] { f.Value.Count }) as Array); } typeBuilder.DefineField(f.Key, lType, FieldAttributes.Public); } else { if (f.Value.Type.IsArray) { if (!string.IsNullOrEmpty(f.Value.CountField)) additionalListInfo.Add(Tuple.Create(lalFile.TypeName, f.Key), f.Value.CountField); else if (f.Value.Count != -1) additionalArrayInfo.Add(Tuple.Create(lalFile.TypeName, f.Key), Activator.CreateInstance(f.Value.Type, new object[] { f.Value.Count }) as Array); } typeBuilder.DefineField(f.Key, f.Value.Type, FieldAttributes.Public); } } return Tuple.Create(typeBuilder.CreateType(), additionalArrayInfo, additionalListInfo, lalFile.FileOptions); }