private static ErrorType CopyIntermediateCodeInsertingSequencesCode(String actionsFilename, Dictionary<String, Type> actionTypes, Dictionary<String, Type> proceduresTypes, LGSPSequenceGenerator seqGen, SourceBuilder source, out bool actionPointFound, out String actionsNamespace) { actionPointFound = false; actionsNamespace = null; using(StreamReader sr = new StreamReader(actionsFilename)) { String line; while(!actionPointFound && (line = sr.ReadLine()) != null) { if(actionsNamespace == null && line.StartsWith("namespace ")) { actionsNamespace = line.Substring("namespace ".Length); source.Append(line); source.Append("\n"); } else if(line.Length > 0 && line[0] == '#' && line.Contains("// GrGen imperative statement section") && seqGen != null) { int lastSpace = line.LastIndexOf(' '); String ruleName = line.Substring(lastSpace + 1); Type ruleType = actionTypes[ruleName]; FieldInfo[] ruleFields = ruleType.GetFields(); for(int i = 0; i < ruleFields.Length; ++i) { if(ruleFields[i].Name.StartsWith("XGRSInfo_") && ruleFields[i].FieldType == typeof(EmbeddedSequenceInfo)) { EmbeddedSequenceInfo xgrsInfo = (EmbeddedSequenceInfo)ruleFields[i].GetValue(null); if(!seqGen.GenerateXGRSCode(ruleFields[i].Name.Substring("XGRSInfo_".Length), xgrsInfo.Package, xgrsInfo.XGRS, xgrsInfo.Parameters, xgrsInfo.ParameterTypes, xgrsInfo.OutParameters, xgrsInfo.OutParameterTypes, source, xgrsInfo.LineNr)) { return ErrorType.GrGenNetError; } } } while((line = sr.ReadLine()) != null) { if(line.StartsWith("#")) break; } } else if(line.Length > 0 && line[0] == '#' && line.Contains("// GrGen procedure exec section") && seqGen != null) { int lastSpace = line.LastIndexOf(' '); String proceduresName = line.Substring(lastSpace + 1); FieldInfo[] procedureFields = proceduresTypes[proceduresName].GetFields(); for(int i = 0; i < procedureFields.Length; ++i) { if(procedureFields[i].Name.StartsWith("XGRSInfo_") && procedureFields[i].FieldType == typeof(EmbeddedSequenceInfo)) { EmbeddedSequenceInfo xgrsInfo = (EmbeddedSequenceInfo)procedureFields[i].GetValue(null); if(!seqGen.GenerateXGRSCode(procedureFields[i].Name.Substring("XGRSInfo_".Length), xgrsInfo.Package, xgrsInfo.XGRS, xgrsInfo.Parameters, xgrsInfo.ParameterTypes, xgrsInfo.OutParameters, xgrsInfo.OutParameterTypes, source, xgrsInfo.LineNr)) { return ErrorType.GrGenNetError; } } } while((line = sr.ReadLine()) != null) { if(line.StartsWith("#")) break; } } else if(line.Length > 0 && line[0] == '/' && line.StartsWith("// GrGen insert Actions here")) { actionPointFound = true; break; } else { source.Append(line); source.Append("\n"); } } } return ErrorType.NoError; }
private void GenerateAndInsertMatcherSourceCode(IGraphModel model, String actionsName, String unitName, string externalActionsExtensionFilename, LGSPRuleAndMatchingPatterns ruleAndMatchingPatterns, LGSPSequenceGenerator seqGen, bool isAutoGeneratedFilterExisting, bool isExternalFilterFunctionExisting, LGSPGraphStatistics graphStatistics, string statisticsPath, SourceBuilder externalSource, SourceBuilder source) { // analyze the matching patterns, inline the subpatterns when expected to be benefitial // the analyzer must be run before the matcher generation AnalyzeAndInlineMatchingPatterns((flags & ProcessSpecFlags.Noinline) == 0, ruleAndMatchingPatterns); LGSPMatcherGenerator matcherGen = new LGSPMatcherGenerator(model); if((flags & ProcessSpecFlags.KeepGeneratedFiles) != 0) matcherGen.CommentSourceCode = true; if((flags & ProcessSpecFlags.LazyNIC) != 0) matcherGen.LazyNegativeIndependentConditionEvaluation = true; if((flags & ProcessSpecFlags.Noinline) != 0) matcherGen.InlineIndependents = false; if((flags & ProcessSpecFlags.Profile) != 0) matcherGen.Profile = true; foreach(LGSPMatchingPattern matchingPattern in ruleAndMatchingPatterns.RulesAndSubpatterns) { GenerateScheduledSearchPlans(matchingPattern.patternGraph, graphStatistics, matcherGen, !(matchingPattern is LGSPRulePattern), false, null); matcherGen.MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(matchingPattern.patternGraph); matcherGen.ParallelizeAsNeeded(matchingPattern); matcherGen.GenerateActionAndMatcher(source, matchingPattern, true); } GenerateDefinedSequencesAndFiltersAndFilterStubs(externalActionsExtensionFilename, isAutoGeneratedFilterExisting, isExternalFilterFunctionExisting, ruleAndMatchingPatterns, seqGen, externalSource, source); // the actions class referencing the generated stuff is generated now into // a source builder which is appended at the end of the other generated stuff SourceBuilder endSource = GenerateActionsClass(model, actionsName, unitName, statisticsPath, ruleAndMatchingPatterns, matcherGen.LazyNegativeIndependentConditionEvaluation, matcherGen.InlineIndependents, matcherGen.Profile); source.Append(endSource.ToString()); source.Append("}"); }
private static void GenerateDefinedSequencesAndFiltersAndFilterStubs(string externalActionsExtensionFilename, bool isAutoGeneratedFilterExisting, bool isExternalFilterFunctionExisting, LGSPRuleAndMatchingPatterns ruleAndMatchingPatterns, LGSPSequenceGenerator seqGen, SourceBuilder externalSource, SourceBuilder source) { foreach(DefinedSequenceInfo sequence in ruleAndMatchingPatterns.DefinedSequences) { if(sequence is ExternalDefinedSequenceInfo) seqGen.GenerateExternalDefinedSequencePlaceholder(externalSource, (ExternalDefinedSequenceInfo)sequence, externalActionsExtensionFilename); } if(isAutoGeneratedFilterExisting || isExternalFilterFunctionExisting) { externalSource.Append("\n"); if(isExternalFilterFunctionExisting) { externalSource.AppendFrontFormat("// You must implement the following filter functions in the same partial class in ./{0}\n", externalActionsExtensionFilename); externalSource.Append("\n"); foreach(LGSPRulePattern rulePattern in ruleAndMatchingPatterns.Rules) { seqGen.GenerateFilterStubs(externalSource, rulePattern); } } if(isAutoGeneratedFilterExisting) { if(isExternalFilterFunctionExisting) externalSource.Append("\n").AppendFront("// ------------------------------------------------------\n\n"); externalSource.AppendFront("// The following filter functions are automatically generated, you don't need to supply any further implementation\n"); externalSource.Append("\n"); foreach(LGSPRulePattern rulePattern in ruleAndMatchingPatterns.Rules) { seqGen.GenerateFilters(externalSource, rulePattern); } } } if(externalSource != null) { externalSource.Append("\n"); externalSource.AppendFront("// ------------------------------------------------------\n"); } foreach(DefinedSequenceInfo sequence in ruleAndMatchingPatterns.DefinedSequences) { if(sequence is ExternalDefinedSequenceInfo) seqGen.GenerateExternalDefinedSequence(externalSource, (ExternalDefinedSequenceInfo)sequence); else seqGen.GenerateDefinedSequence(source, sequence); } }
private ErrorType GenerateActionsSourceCode(CompileConfiguration cc, IGraphModel model, String statisticsPath, out String actionsOutputSource) { /////////////////////////////////////////////// // compile the intermediate action files generated by the java frontend // to gain access via reflection to their content needed for matcher code generation // and collect that content actionsOutputSource = null; Assembly initialAssembly; ErrorType result = CompileIntermediateActions(cc.modelAssemblyName, cc.actionsFilename, out initialAssembly); if(result != ErrorType.NoError) return result; Dictionary<String, Type> actionTypes; Dictionary<String, Type> proceduresTypes; LGSPRuleAndMatchingPatterns ruleAndMatchingPatterns; CollectActionTypes(initialAssembly, out actionTypes, out proceduresTypes, out ruleAndMatchingPatterns); Dictionary<String, List<IFilter>> rulesToFilters; Dictionary<String, List<String>> filterFunctionsToInputTypes; Dictionary<String, List<String>> rulesToInputTypes; Dictionary<String, List<String>> rulesToOutputTypes; Dictionary<String, List<String>> sequencesToInputTypes; Dictionary<String, List<String>> sequencesToOutputTypes; Dictionary<String, List<String>> proceduresToInputTypes; Dictionary<String, List<String>> proceduresToOutputTypes; Dictionary<String, bool> proceduresToIsExternal; Dictionary<String, List<String>> functionsToInputTypes; Dictionary<String, String> functionsToOutputType; Dictionary<String, bool> functionsToIsExternal; Dictionary<String, List<String>> rulesToTopLevelEntities; Dictionary<String, List<String>> rulesToTopLevelEntityTypes; CollectActionParameterTypes(ruleAndMatchingPatterns, model, out rulesToFilters, out filterFunctionsToInputTypes, out rulesToInputTypes, out rulesToOutputTypes, out rulesToTopLevelEntities, out rulesToTopLevelEntityTypes, out sequencesToInputTypes, out sequencesToOutputTypes, out proceduresToInputTypes, out proceduresToOutputTypes, out proceduresToIsExternal, out functionsToInputTypes, out functionsToOutputType, out functionsToIsExternal); LGSPSequenceGenerator seqGen = new LGSPSequenceGenerator(this, model, rulesToFilters, filterFunctionsToInputTypes, rulesToInputTypes, rulesToOutputTypes, rulesToTopLevelEntities, rulesToTopLevelEntityTypes, sequencesToInputTypes, sequencesToOutputTypes, proceduresToInputTypes, proceduresToOutputTypes, proceduresToIsExternal, functionsToInputTypes, functionsToOutputType, functionsToIsExternal); /////////////////////////////////////////////// // generate external extension source if needed (cause there are external action extension) bool isAutoGeneratedFilterExisting; bool isExternalFilterFunctionExisting; bool isExternalSequenceExisting; DetermineWhetherExternalActionsFileIsNeeded(ruleAndMatchingPatterns, out isAutoGeneratedFilterExisting, out isExternalFilterFunctionExisting, out isExternalSequenceExisting); SourceBuilder externalSource = null; if(isAutoGeneratedFilterExisting || isExternalFilterFunctionExisting || isExternalSequenceExisting) { EmitExternalActionsFileHeader(cc, model, isExternalFilterFunctionExisting || isExternalSequenceExisting, ref externalSource); } /////////////////////////////////////////////// // take action intermediate file until action insertion point as base for action file SourceBuilder source = new SourceBuilder((flags & ProcessSpecFlags.KeepGeneratedFiles) != 0); source.Indent(); source.Indent(); bool actionPointFound; String actionsNamespace; result = CopyIntermediateCodeInsertingSequencesCode(cc.actionsFilename, actionTypes, proceduresTypes, seqGen, source, out actionPointFound, out actionsNamespace); if(result != ErrorType.NoError) return result; if(!actionPointFound) { Console.Error.WriteLine("Illegal actions C# input source code: Actions insertion point not found!"); return ErrorType.GrGenJavaError; } source.Unindent(); source.Append("\n"); /////////////////////////////////////////////// // generate and insert the matcher source code into the action file // already filled with the content of the action intermediate file until the action insertion point String unitName; int lastDot = actionsNamespace.LastIndexOf("."); if(lastDot == -1) unitName = ""; else unitName = actionsNamespace.Substring(lastDot + 8); // skip ".Action_" LGSPGraphStatistics graphStatistics = null; if(statisticsPath != null) { Console.WriteLine("Reading graph statistics from {0}", statisticsPath); graphStatistics = new LGSPGraphStatistics(model); graphStatistics.Parse(statisticsPath); } GenerateAndInsertMatcherSourceCode(model, cc.actionsName, unitName, cc.externalActionsExtensionFilename, ruleAndMatchingPatterns, seqGen, isAutoGeneratedFilterExisting, isExternalFilterFunctionExisting, graphStatistics, statisticsPath, externalSource, source); actionsOutputSource = WriteSourceAndExternalSource(externalSource, source, cc.actionsOutputFilename, cc.externalActionsExtensionOutputFilename); return ErrorType.NoError; }