public string Generate(List <AphidExpression> nodes, string code) { ParseDirectives(nodes); var lexer = GenerateLexer(nodes, code); ParseRuleStructs(nodes); nodes = new PlusEqualMutator().MutateRecursively(nodes); var rules = GetRules(nodes); _ruleNames = GetRuleNames(nodes).ToArray(); var mutator = new TypeInferenceMutator(_config); foreach (var r in rules) { nodes.Remove(r); } do { rules = rules .Select(x => new BinaryOperatorExpression( x.LeftOperand, x.Operator, new FunctionExpression( x.RightOperand.ToFunction().Args, mutator.MutateRecursively(x.RightOperand.ToFunction().Body)))) .ToArray(); }while (mutator.HasMutated); nodes.AddRange(rules); var declMutator = new DeclarativeStatementMutator(_tokenTypes, _ruleNames); nodes = declMutator.Mutate(nodes); nodes = AddIndexTracking(nodes); var ruleTypeBuilder = new RuleTypeBuilder(_config, _ruleTypes.Select(x => x.Value)); var typeClasses = ruleTypeBuilder.CreateRuleTypeClasses(); var enumBuilder = new EnumBuilder(_config.BaseClass, _ruleTypes.Select(x => x.Key)); var enumDecl = enumBuilder.CreateEnum(); var ns = new CodeNamespace( string.Join(".", _config.Namespace.Concat(new[] { ParserName.Parser }))); ns.Imports.Add(new CodeNamespaceImport( string.Join(".", _config.Namespace.Concat(new[] { ParserName.Lexer })))); ns.Imports.Add(new CodeNamespaceImport("System.Linq")); ns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic")); ns.Types.Add(enumDecl); ns.Types.AddRange(typeClasses); var parserType = new CodeTypeDeclaration(_config.ParserClass) { IsPartial = true }; parserType.Members.Add(GenerateContextField()); parserType.Members.AddRange(nodes.Select(Generate).Where(x => x != null).ToArray()); ns.Types.Add(parserType); var str = CSharpHelper.GenerateCode(ns); return(str + "\r\n\r\n" + lexer); }
public Type BuildType(string typeName) { var nameTable = _sourcePropertyTable.Value; var type2 = new CodeTypeDeclaration(typeName) { CustomAttributes = new CodeAttributeDeclarationCollection( new[] { new CodeAttributeDeclaration(CodeHelper.TypeRef <SerializableAttribute>()) }) }; var fields = nameTable .ToDictionary( x => x.Key, x => new CodeMemberField(x.Value.PropertyType, string.Format("_autoField_{0}", x.Key))); var props = nameTable .Select(x => new CodeMemberProperty { Attributes = MemberAttributes.Public, Type = CodeHelper.TypeRef(x.Value.PropertyType), Name = x.Key, HasGet = true, HasSet = true, CustomAttributes = new CodeAttributeDeclarationCollection( new[] { new CodeAttributeDeclaration(CodeHelper.TypeRef <TAttribute>()) }) }) .ToArray(); foreach (var p in props) { var field = CodeHelper.FieldRef(fields[p.Name].Name); p.GetStatements.Add(CodeHelper.Return(field)); p.SetStatements.Add(CodeHelper.Assign(field, CodeHelper.VarRef("value"))); } type2.Members.AddRange(fields.Select(x => x.Value).ToArray()); type2.Members.AddRange(props); var code = CSharpHelper.GenerateCode(type2); using (var provider = new CSharpCodeProvider()) { var options = new CompilerParameters { GenerateExecutable = false, GenerateInMemory = true, }; var references = nameTable .Select(x => x.Value.PropertyType.Assembly.Location) .Concat(new[] { typeof(SerializableAttribute), typeof(TAttribute) } .Select(x => x.Assembly.Location)) .Distinct() .ToArray(); options.ReferencedAssemblies.AddRange(references); var results = provider.CompileAssemblyFromSource(options, code); return(results.CompiledAssembly.GetType(typeName)); } }