public void EmitRewriting(SourceBuilder source, SequenceGenerator seqGen, String matchListName, String enumeratorName, bool fireDebugEvents) { source.AppendFrontFormat("case \"{0}\":\n", plainRuleName); source.AppendFront("{\n"); source.Indent(); source.AppendFront(matchType + " " + matchName + " = (" + matchType + ")" + enumeratorName + ".Current;\n"); String returnParameterDeclarations; String returnArguments; String returnAssignments; String returnParameterDeclarationsAllCall; String intermediateReturnAssignmentsAllCall; String returnAssignmentsAllCall; seqHelper.BuildReturnParameters(seqRule, ReturnVars, out returnParameterDeclarations, out returnArguments, out returnAssignments, out returnParameterDeclarationsAllCall, out intermediateReturnAssignmentsAllCall, out returnAssignmentsAllCall); // start a transaction if (fireDebugEvents) { source.AppendFront("procEnv.Matched(" + matchesName + ", " + matchName + ", " + specialStr + ");\n"); } if (fireDebugEvents) { source.AppendFront("procEnv.Finishing(" + matchesName + ", " + specialStr + ");\n"); } if (returnParameterDeclarations.Length != 0) { source.AppendFront(returnParameterDeclarations + "\n"); } source.AppendFront(ruleName + ".Modify(procEnv, " + matchName + returnArguments + ");\n"); if (returnAssignments.Length != 0) { source.AppendFront(returnAssignments + "\n"); } source.AppendFront("++procEnv.PerformanceInfo.RewritesPerformed;\n"); if (fireDebugEvents) { source.AppendFront("procEnv.Finished(" + matchesName + ", " + specialStr + ");\n"); } // rule applied, now execute the sequence seqGen.EmitSequence(seqSeq, source); source.AppendFront(COMP_HELPER.SetResultVar(seqMulti, COMP_HELPER.GetResultVar(seqSeq))); source.AppendFront("break;\n"); source.Unindent(); source.AppendFront("}\n"); }
public void Emit(SourceBuilder source, SequenceGenerator seqGen, bool fireDebugEvents) { source.AppendFront(COMP_HELPER.SetResultVar(seqFor, "true")); String parameters = seqHelper.BuildParameters(seqRule, ArgumentExpressions, source); source.AppendFront(matchesType + " " + matchesName + " = " + ruleName + ".Match(procEnv, procEnv.MaxMatches" + parameters + ");\n"); source.AppendFront("procEnv.PerformanceInfo.MatchesFound += " + matchesName + ".Count;\n"); for (int i = 0; i < seqRule.Filters.Count; ++i) { seqExprGen.EmitFilterCall(source, (SequenceFilterCallCompiled)seqRule.Filters[i], patternName, matchesName, seqRule.PackagePrefixedName, false); } source.AppendFront("if(" + matchesName + ".Count != 0) {\n"); source.Indent(); source.AppendFront(matchesName + " = (" + matchesType + ")" + matchesName + ".Clone();\n"); if (fireDebugEvents) { source.AppendFront("procEnv.Finishing(" + matchesName + ", " + specialStr + ");\n"); } String returnParameterDeclarations; String returnArguments; String returnAssignments; String returnParameterDeclarationsAllCall; String intermediateReturnAssignmentsAllCall; String returnAssignmentsAllCall; seqHelper.BuildReturnParameters(seqRule, ReturnVars, out returnParameterDeclarations, out returnArguments, out returnAssignments, out returnParameterDeclarationsAllCall, out intermediateReturnAssignmentsAllCall, out returnAssignmentsAllCall); // apply the sequence for every match found String enumeratorName = "enum_" + seqFor.Id; source.AppendFront("IEnumerator<" + matchType + "> " + enumeratorName + " = " + matchesName + ".GetEnumeratorExact();\n"); source.AppendFront("while(" + enumeratorName + ".MoveNext())\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront(matchType + " " + matchName + " = " + enumeratorName + ".Current;\n"); source.AppendFront(seqHelper.SetVar(seqFor.Var, matchName)); seqGen.EmitSequence(seqFor.Seq, source); source.AppendFront(COMP_HELPER.SetResultVar(seqFor, COMP_HELPER.GetResultVar(seqFor) + " & " + COMP_HELPER.GetResultVar(seqFor.Seq))); source.Unindent(); source.AppendFront("}\n"); source.Unindent(); source.AppendFront("}\n"); }
/// <summary> /// pre-run for emitting the needed entities before emitting the real code /// - emits sequence variable declarations (only once for every variable, declaration only possible at assignment targets) /// </summary> private void EmitNeededVarEntities(SequenceComputation seqComp, SourceBuilder source) { source.AppendFront(COMP_HELPER.DeclareResultVar(seqComp)); switch (seqComp.SequenceComputationType) { case SequenceComputationType.Assignment: { SequenceComputationAssignment assign = (SequenceComputationAssignment)seqComp; EmitNeededVarEntities(assign.Target, source); if (assign.SourceValueProvider is SequenceComputationAssignment) { EmitNeededVarEntities(assign.SourceValueProvider, source); } break; } case SequenceComputationType.ProcedureCall: { SequenceComputationProcedureCall seqProc = (SequenceComputationProcedureCall)seqComp; // no handling for the input arguments seqProc.ArgumentExpressions needed // because there can only be variable uses for (int i = 0; i < seqProc.ReturnVars.Length; ++i) { EmitVarIfNew(seqProc.ReturnVars[i], source); } break; } case SequenceComputationType.BuiltinProcedureCall: { SequenceComputationBuiltinProcedureCall seqProc = (SequenceComputationBuiltinProcedureCall)seqComp; // no handling for the input arguments seqProc.ArgumentExpressions needed // because there can only be variable uses for (int i = 0; i < seqProc.ReturnVars.Count; ++i) { EmitVarIfNew(seqProc.ReturnVars[i], source); } break; } default: foreach (SequenceComputation childSeqComp in seqComp.Children) { EmitNeededVarEntities(childSeqComp, source); } break; } }
public void Emit(SourceBuilder source, SequenceGenerator seqGen, bool fireDebugEvents) { source.AppendFront(COMP_HELPER.SetResultVar(seqFor, "true")); seqMatcherGen.EmitMatchingAndCloning(source, "procEnv.MaxMatches"); SequenceRuleCallMatcherGenerator.EmitPreMatchEventFiring(source, matchesName); seqMatcherGen.EmitFiltering(source); source.AppendFront("if(" + matchesName + ".Count != 0) {\n"); source.Indent(); if (fireDebugEvents) { source.AppendFront("procEnv.Finishing(" + matchesName + ", " + specialStr + ");\n"); } String returnParameterDeclarations; String returnArguments; String returnAssignments; String returnParameterDeclarationsAllCall; String intermediateReturnAssignmentsAllCall; String returnAssignmentsAllCall; seqHelper.BuildReturnParameters(seqRule, ReturnVars, out returnParameterDeclarations, out returnArguments, out returnAssignments, out returnParameterDeclarationsAllCall, out intermediateReturnAssignmentsAllCall, out returnAssignmentsAllCall); // apply the sequence for every match found String enumeratorName = "enum_" + seqFor.Id; source.AppendFront("IEnumerator<" + matchType + "> " + enumeratorName + " = " + matchesName + ".GetEnumeratorExact();\n"); source.AppendFront("while(" + enumeratorName + ".MoveNext())\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront(matchType + " " + matchName + " = " + enumeratorName + ".Current;\n"); source.AppendFront(seqHelper.SetVar(seqFor.Var, matchName)); seqGen.EmitSequence(seqFor.Seq, source); source.AppendFront(COMP_HELPER.SetResultVar(seqFor, COMP_HELPER.GetResultVar(seqFor) + " & " + COMP_HELPER.GetResultVar(seqFor.Seq))); source.Unindent(); source.AppendFront("}\n"); source.Unindent(); source.AppendFront("}\n"); }
public void EmitMatching(SourceBuilder source, SequenceGenerator seqGen) { String parameters = seqHelper.BuildParameters(seqRule, ArgumentExpressions, source); source.AppendFront(matchesType + " " + matchesName + " = " + ruleName + ".Match(procEnv, " + (seqRule.SequenceType == SequenceType.RuleCall ? "1" : "procEnv.MaxMatches") + parameters + ");\n"); source.AppendFront("procEnv.PerformanceInfo.MatchesFound += " + matchesName + ".Count;\n"); for (int i = 0; i < seqRule.Filters.Count; ++i) { seqExprGen.EmitFilterCall(source, (SequenceFilterCallCompiled)seqRule.Filters[i], patternName, matchesName, seqRule.PackagePrefixedName, false); } source.AppendFront("if(" + matchesName + ".Count != 0) {\n"); source.Indent(); source.AppendFront(COMP_HELPER.SetResultVar(seqSome, "true")); source.Unindent(); source.AppendFront("}\n"); }
/// <summary> /// pre-run for emitting the needed entities before emitting the real code /// - emits sequence variable declarations (only once for every variable, declaration only possible at assignment targets) /// </summary> private void EmitNeededVarEntities(AssignmentTarget tgt, SourceBuilder source) { source.AppendFront(COMP_HELPER.DeclareResultVar(tgt)); switch (tgt.AssignmentTargetType) { case AssignmentTargetType.Var: { AssignmentTargetVar var = (AssignmentTargetVar)tgt; EmitVarIfNew(var.DestVar, source); break; } case AssignmentTargetType.YieldingToVar: { AssignmentTargetYieldingVar var = (AssignmentTargetYieldingVar)tgt; EmitVarIfNew(var.DestVar, source); break; } default: break; } }
public void Emit(SourceBuilder source, SequenceGenerator seqGen, bool fireDebugEvents) { String parameters = seqHelper.BuildParameters(seqRule, ArgumentExpressions, source); seqMatcherGen.EmitMatching(source, parameters, "procEnv.MaxMatches"); SequenceRuleCallMatcherGenerator.EmitPreMatchEventFiring(source, matchesName); seqMatcherGen.EmitFiltering(source); seqMatcherGen.EmitCloning(source); source.AppendFront("if(" + matchesName + ".Count == 0) {\n"); source.Indent(); source.AppendFront(COMP_HELPER.SetResultVar(seq, "false")); source.Unindent(); source.AppendFront("} else {\n"); source.Indent(); source.AppendFront(COMP_HELPER.SetResultVar(seq, "false")); if (fireDebugEvents) { source.AppendFront("procEnv.Finishing(" + matchesName + ", " + specialStr + ");\n"); } String returnParameterDeclarations; String returnArguments; String returnAssignments; String returnParameterDeclarationsAllCall; String intermediateReturnAssignmentsAllCall; String returnAssignmentsAllCall; seqHelper.BuildReturnParameters(seqRule, ReturnVars, out returnParameterDeclarations, out returnArguments, out returnAssignments, out returnParameterDeclarationsAllCall, out intermediateReturnAssignmentsAllCall, out returnAssignmentsAllCall); // apply the rule and the following sequence for every match found String enumeratorName = "enum_" + seq.Id; source.AppendFront("IEnumerator<" + matchType + "> " + enumeratorName + " = " + matchesName + ".GetEnumeratorExact();\n"); source.AppendFront("while(" + enumeratorName + ".MoveNext())\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront(matchType + " " + matchName + " = " + enumeratorName + ".Current;\n"); source.AppendFront("procEnv.Matched(" + matchesName + ", " + matchName + ", " + specialStr + ");\n"); if (returnParameterDeclarations.Length != 0) { source.AppendFront(returnParameterDeclarations + "\n"); } source.AppendFront(ruleName + ".Modify(procEnv, " + matchName + returnArguments + ");\n"); if (returnAssignments.Length != 0) { source.AppendFront(returnAssignments + "\n"); } source.AppendFront("++procEnv.PerformanceInfo.RewritesPerformed;\n"); if (fireDebugEvents) { source.AppendFront("procEnv.Finished(" + matchesName + ", " + specialStr + ");\n"); } // rule applied, now execute the sequence seqGen.EmitSequence(seq.Sequence, source); source.AppendFront(COMP_HELPER.SetResultVar(seq, COMP_HELPER.GetResultVar(seq) + "|" + COMP_HELPER.GetResultVar(seq.Sequence))); source.Unindent(); source.AppendFront("}\n"); source.Unindent(); source.AppendFront("}\n"); }
public void Emit(SourceBuilder source, SequenceGenerator seqGen, bool fireDebugEvents) { String parameterDeclarations = null; String parameters = null; if (seqRule.Subgraph != null) { parameters = seqHelper.BuildParametersInDeclarations(seqRule, ArgumentExpressions, source, out parameterDeclarations); } else { parameters = seqHelper.BuildParameters(seqRule, ArgumentExpressions, source); } if (seqRule.Subgraph != null) { source.AppendFront(parameterDeclarations + "\n"); source.AppendFront("procEnv.SwitchToSubgraph((GRGEN_LIBGR.IGraph)" + seqHelper.GetVar(seqRule.Subgraph) + ");\n"); source.AppendFront("graph = ((GRGEN_LGSP.LGSPActionExecutionEnvironment)procEnv).graph;\n"); } source.AppendFront(matchesType + " " + matchesName + " = " + ruleName + ".Match(procEnv, " + (seqRule.SequenceType == SequenceType.RuleCall ? "1" : "procEnv.MaxMatches") + parameters + ");\n"); source.AppendFront("procEnv.PerformanceInfo.MatchesFound += " + matchesName + ".Count;\n"); for (int i = 0; i < seqRule.Filters.Count; ++i) { seqExprGen.EmitFilterCall(source, (SequenceFilterCallCompiled)seqRule.Filters[i], patternName, matchesName, seqRule.PackagePrefixedName, false); } if (seqRule is SequenceRuleCountAllCall) { SequenceRuleCountAllCall seqRuleCountAll = (SequenceRuleCountAllCall)seqRule; source.AppendFront(seqHelper.SetVar(seqRuleCountAll.CountResult, matchesName + ".Count")); } String insufficientMatchesCondition; if (seqRule is SequenceRuleAllCall && ((SequenceRuleAllCall)seqRule).ChooseRandom && ((SequenceRuleAllCall)seqRule).MinSpecified) { SequenceRuleAllCall seqRuleAll = (SequenceRuleAllCall)seqRule; String minMatchesVarName = "minmatchesvar_" + seqRuleAll.Id; source.AppendFrontFormat("int {0} = (int){1};\n", minMatchesVarName, seqHelper.GetVar(seqRuleAll.MinVarChooseRandom)); insufficientMatchesCondition = matchesName + ".Count < " + minMatchesVarName; } else { insufficientMatchesCondition = matchesName + ".Count == 0"; } source.AppendFrontFormat("if({0}) {{\n", insufficientMatchesCondition); source.Indent(); source.AppendFront(COMP_HELPER.SetResultVar(seqRule, "false")); source.Unindent(); source.AppendFront("} else {\n"); source.Indent(); source.AppendFront(COMP_HELPER.SetResultVar(seqRule, "true")); if (fireDebugEvents) { source.AppendFront("procEnv.Matched(" + matchesName + ", null, " + specialStr + ");\n"); } if (fireDebugEvents) { source.AppendFront("procEnv.Finishing(" + matchesName + ", " + specialStr + ");\n"); } SequenceRuleOrRuleAllCallRewritingGenerator rewritingGen = new SequenceRuleOrRuleAllCallRewritingGenerator(this); if (seqRule.SequenceType == SequenceType.RuleCall) { rewritingGen.EmitRewritingRuleCall(source); } else if (seqRule.SequenceType == SequenceType.RuleCountAllCall || !((SequenceRuleAllCall)seqRule).ChooseRandom) // seq.SequenceType == SequenceType.RuleAll { rewritingGen.EmitRewritingRuleCountAllCallOrRuleAllCallNonRandom(source); } else // seq.SequenceType == SequenceType.RuleAll && ((SequenceRuleAll)seqRule).ChooseRandom { rewritingGen.EmitRewritingRuleAllCallRandom(source); } if (fireDebugEvents) { source.AppendFront("procEnv.Finished(" + matchesName + ", " + specialStr + ");\n"); } source.Unindent(); source.AppendFront("}\n"); if (seqRule.Subgraph != null) { source.AppendFront("procEnv.ReturnFromSubgraph();\n"); source.AppendFront("graph = ((GRGEN_LGSP.LGSPActionExecutionEnvironment)procEnv).graph;\n"); } }
public void Emit(SourceBuilder source, SequenceGenerator seqGen, bool fireDebugEvents) { String parameters = seqHelper.BuildParameters(seqRule, ArgumentExpressions, source); seqMatcherGen.EmitMatching(source, parameters, "procEnv.MaxMatches"); SequenceRuleCallMatcherGenerator.EmitPreMatchEventFiring(source, matchesName); seqMatcherGen.EmitFiltering(source); seqMatcherGen.EmitCloning(source); source.AppendFront("if(" + matchesName + ".Count == 0) {\n"); source.Indent(); source.AppendFront(COMP_HELPER.SetResultVar(seq, "false")); source.Unindent(); source.AppendFront("} else {\n"); source.Indent(); source.AppendFront(COMP_HELPER.SetResultVar(seq, "true")); // shut up compiler if (fireDebugEvents) { source.AppendFront("procEnv.Finishing(" + matchesName + ", " + specialStr + ");\n"); } String returnParameterDeclarations; String returnArguments; String returnAssignments; String returnParameterDeclarationsAllCall; String intermediateReturnAssignmentsAllCall; String returnAssignmentsAllCall; seqHelper.BuildReturnParameters(seqRule, ReturnVars, out returnParameterDeclarations, out returnArguments, out returnAssignments, out returnParameterDeclarationsAllCall, out intermediateReturnAssignmentsAllCall, out returnAssignmentsAllCall); // apply the rule and the following sequence for every match found, // until the first rule and sequence execution succeeded // rolling back the changes of failing executions until then String enumeratorName = "enum_" + seq.Id; String matchesTriedName = "matchesTried_" + seq.Id; source.AppendFront("int " + matchesTriedName + " = 0;\n"); source.AppendFront("IEnumerator<" + matchType + "> " + enumeratorName + " = " + matchesName + ".GetEnumeratorExact();\n"); source.AppendFront("while(" + enumeratorName + ".MoveNext())\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront(matchType + " " + matchName + " = " + enumeratorName + ".Current;\n"); source.AppendFront("++" + matchesTriedName + ";\n"); // start a transaction String transactionIdName = "transID_" + seq.Id; source.AppendFront("int " + transactionIdName + " = procEnv.TransactionManager.Start();\n"); String oldRewritesPerformedName = "oldRewritesPerformed_" + seq.Id; source.AppendFront("int " + oldRewritesPerformedName + " = procEnv.PerformanceInfo.RewritesPerformed;\n"); if (fireDebugEvents) { source.AppendFront("procEnv.Matched(" + matchesName + ", " + matchName + ", " + specialStr + ");\n"); } if (returnParameterDeclarations.Length != 0) { source.AppendFront(returnParameterDeclarations + "\n"); } source.AppendFront(ruleName + ".Modify(procEnv, " + matchName + returnArguments + ");\n"); if (returnAssignments.Length != 0) { source.AppendFront(returnAssignments + "\n"); } source.AppendFront("++procEnv.PerformanceInfo.RewritesPerformed;\n"); if (fireDebugEvents) { source.AppendFront("procEnv.Finished(" + matchesName + ", " + specialStr + ");\n"); } // rule applied, now execute the sequence seqGen.EmitSequence(seq.Seq, source); // if sequence execution failed, roll the changes back and try the next match of the rule source.AppendFront("if(!" + COMP_HELPER.GetResultVar(seq.Seq) + ") {\n"); source.Indent(); source.AppendFront("procEnv.TransactionManager.Rollback(" + transactionIdName + ");\n"); source.AppendFront("procEnv.PerformanceInfo.RewritesPerformed = " + oldRewritesPerformedName + ";\n"); source.AppendFront("if(" + matchesTriedName + " < " + matchesName + ".Count) {\n"); // further match available -> try it source.Indent(); source.AppendFront("continue;\n"); source.Unindent(); source.AppendFront("} else {\n"); // all matches tried, all failed later on -> end in fail source.Indent(); source.AppendFront(COMP_HELPER.SetResultVar(seq, "false")); source.AppendFront("break;\n"); source.Unindent(); source.AppendFront("}\n"); source.Unindent(); source.AppendFront("}\n"); // if sequence execution succeeded, commit the changes so far and succeed source.AppendFront("procEnv.TransactionManager.Commit(" + transactionIdName + ");\n"); source.AppendFront(COMP_HELPER.SetResultVar(seq, "true")); source.AppendFront("break;\n"); source.Unindent(); source.AppendFront("}\n"); source.Unindent(); source.AppendFront("}\n"); }
public void Emit(SourceBuilder source, SequenceGenerator seqGen, bool fireDebugEvents) { String matchListName = "MatchList_" + seqMulti.Id; source.AppendFrontFormat("List<GRGEN_LIBGR.IMatch> {0} = new List<GRGEN_LIBGR.IMatch>();\n", matchListName); // emit code for matching all the contained rules for (int i = 0; i < seqMulti.MultiRulePrefixedSequence.RulePrefixedSequences.Count; ++i) { new SequenceMultiSequenceBacktrackRuleGenerator(seqMulti, seqMulti.MultiRulePrefixedSequence.RulePrefixedSequences[i].Rule, seqMulti.MultiRulePrefixedSequence.RulePrefixedSequences[i].Sequence, seqExprGen, seqHelper) .EmitMatching(source, seqGen, matchListName); } // emit code for match class (non-rule-based) filtering foreach (SequenceFilterCall sequenceFilterCall in seqMulti.MultiRulePrefixedSequence.Filters) { seqExprGen.EmitMatchClassFilterCall(source, (SequenceFilterCallCompiled)sequenceFilterCall, matchListName, false); } source.AppendFront("if(" + matchListName + ".Count == 0) {\n"); source.Indent(); source.AppendFront(COMP_HELPER.SetResultVar(seqMulti, "false")); source.Unindent(); source.AppendFront("} else {\n"); source.Indent(); source.AppendFront(COMP_HELPER.SetResultVar(seqMulti, "true")); // shut up compiler String originalToCloneName = "originalToClone_" + seqMulti.Id; source.AppendFrontFormat("Dictionary<GRGEN_LIBGR.IMatch, GRGEN_LIBGR.IMatch> {0} = new Dictionary<GRGEN_LIBGR.IMatch, GRGEN_LIBGR.IMatch>();\n", originalToCloneName); // emit code for cloning the matches objects of the rules for (int i = 0; i < seqMulti.MultiRulePrefixedSequence.RulePrefixedSequences.Count; ++i) { new SequenceMultiSequenceBacktrackRuleGenerator(seqMulti, seqMulti.MultiRulePrefixedSequence.RulePrefixedSequences[i].Rule, seqMulti.MultiRulePrefixedSequence.RulePrefixedSequences[i].Sequence, seqExprGen, seqHelper) .EmitCloning(source, seqGen, matchListName, originalToCloneName); } String originalMatchList = "originalMatchList_" + seqMulti.Id; source.AppendFrontFormat("List<GRGEN_LIBGR.IMatch> {0} = new List<GRGEN_LIBGR.IMatch>({1});\n", originalMatchList, matchListName); source.AppendFrontFormat("{0}.Clear();\n", matchListName); String originalMatch = "originalMatch_" + seqMulti.Id; source.AppendFrontFormat("foreach(GRGEN_LIBGR.IMatch {0} in {1})\n", originalMatch, originalMatchList); source.AppendFrontIndentedFormat("{0}.Add({1}[{2}]);", matchListName, originalToCloneName, originalMatch); // apply the rules and the following sequence for every match found, // until the first rule and sequence execution succeeded // rolling back the changes of failing executions until then String enumeratorName = "enum_" + seqMulti.Id; String matchesTriedName = "matchesTried_" + seqMulti.Id; source.AppendFront("int " + matchesTriedName + " = 0;\n"); source.AppendFront("IEnumerator<GRGEN_LIBGR.IMatch> " + enumeratorName + " = " + matchListName + ".GetEnumerator();\n"); source.AppendFront("while(" + enumeratorName + ".MoveNext())\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront("++" + matchesTriedName + ";\n"); String transactionIdName = "transID_" + seqMulti.Id; source.AppendFront("int " + transactionIdName + " = procEnv.TransactionManager.Start();\n"); String oldRewritesPerformedName = "oldRewritesPerformed_" + seqMulti.Id; source.AppendFront("int " + oldRewritesPerformedName + " = procEnv.PerformanceInfo.RewritesPerformed;\n"); source.AppendFront("switch(" + enumeratorName + ".Current.Pattern.PackagePrefixedName)\n"); source.AppendFront("{\n"); source.Indent(); // emit code for rewriting the current match (for each rule, rule fitting to the match is selected by rule name) // and code for executing the corresponding sequence for (int i = 0; i < seqMulti.MultiRulePrefixedSequence.RulePrefixedSequences.Count; ++i) { new SequenceMultiSequenceBacktrackRuleGenerator(seqMulti, seqMulti.MultiRulePrefixedSequence.RulePrefixedSequences[i].Rule, seqMulti.MultiRulePrefixedSequence.RulePrefixedSequences[i].Sequence, seqExprGen, seqHelper) .EmitRewriting(source, seqGen, matchListName, enumeratorName, fireDebugEvents); } source.AppendFrontFormat("default: throw new Exception(\"Unknown pattern \" + {0}.Current.Pattern.PackagePrefixedName + \" in match!\");", enumeratorName); source.Unindent(); source.AppendFront("}\n"); // if sequence execution failed, roll the changes back and try the next match source.AppendFront("if(!" + COMP_HELPER.GetResultVar(seqMulti) + ") {\n"); source.Indent(); source.AppendFront("procEnv.TransactionManager.Rollback(" + transactionIdName + ");\n"); source.AppendFront("procEnv.PerformanceInfo.RewritesPerformed = " + oldRewritesPerformedName + ";\n"); source.AppendFront("if(" + matchesTriedName + " < " + matchListName + ".Count) {\n"); // further match available -> try it source.Indent(); source.AppendFront("continue;\n"); source.Unindent(); source.AppendFront("} else {\n"); // all matches tried, all failed later on -> end in fail source.Indent(); source.AppendFront("break;\n"); source.Unindent(); source.AppendFront("}\n"); source.Unindent(); source.AppendFront("}\n"); // if sequence execution succeeded, commit the changes so far and succeed source.AppendFront("procEnv.TransactionManager.Commit(" + transactionIdName + ");\n"); source.AppendFront("break;\n"); source.Unindent(); source.AppendFront("}\n"); source.Unindent(); source.AppendFront("}\n"); }
public void Emit(SourceBuilder source, SequenceGenerator seqGen, bool fireDebugEvents) { String matchListName = "MatchList_" + seqMulti.Id; source.AppendFrontFormat("List<GRGEN_LIBGR.IMatch> {0} = new List<GRGEN_LIBGR.IMatch>();\n", matchListName); // emit code for matching all the contained rules SequenceRuleCallMatcherGenerator[] ruleMatcherGenerators = new SequenceRuleCallMatcherGenerator[seqMulti.Rules.Sequences.Count]; for (int i = 0; i < seqMulti.Rules.Sequences.Count; ++i) { ruleMatcherGenerators[i] = new SequenceRuleCallMatcherGenerator((SequenceRuleCall)seqMulti.Rules.Sequences[i], seqExprGen, seqHelper); ruleMatcherGenerators[i].EmitMatchingAndCloning(source, "procEnv.MaxMatches"); } SequenceRuleCallMatcherGenerator.EmitPreMatchEventFiring(source, ruleMatcherGenerators); // emit code for rule-based filtering for (int i = 0; i < seqMulti.Rules.Sequences.Count; ++i) { ruleMatcherGenerators[i].EmitFiltering(source); ruleMatcherGenerators[i].EmitAddRange(source, matchListName); } // emit code for match class (non-rule-based) filtering foreach (SequenceFilterCallBase sequenceFilterCall in seqMulti.Rules.Filters) { seqExprGen.EmitMatchClassFilterCall(source, sequenceFilterCall, matchListName, false); } source.AppendFront("if(" + matchListName + ".Count == 0) {\n"); source.Indent(); source.AppendFront(COMP_HELPER.SetResultVar(seqMulti, "false")); source.Unindent(); source.AppendFront("} else {\n"); source.Indent(); source.AppendFront(COMP_HELPER.SetResultVar(seqMulti, "true")); // shut up compiler // apply the rules and the following sequence for every match found, // until the first rule and sequence execution succeeded // rolling back the changes of failing executions until then String enumeratorName = "enum_" + seqMulti.Id; String matchesTriedName = "matchesTried_" + seqMulti.Id; source.AppendFront("int " + matchesTriedName + " = 0;\n"); source.AppendFront("IEnumerator<GRGEN_LIBGR.IMatch> " + enumeratorName + " = " + matchListName + ".GetEnumerator();\n"); source.AppendFront("while(" + enumeratorName + ".MoveNext())\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront("++" + matchesTriedName + ";\n"); String transactionIdName = "transID_" + seqMulti.Id; source.AppendFront("int " + transactionIdName + " = procEnv.TransactionManager.Start();\n"); String oldRewritesPerformedName = "oldRewritesPerformed_" + seqMulti.Id; source.AppendFront("int " + oldRewritesPerformedName + " = procEnv.PerformanceInfo.RewritesPerformed;\n"); source.AppendFront("switch(" + enumeratorName + ".Current.Pattern.PackagePrefixedName)\n"); source.AppendFront("{\n"); source.Indent(); // emit code for rewriting the current match (for each rule, rule fitting to the match is selected by rule name) for (int i = 0; i < seqMulti.Rules.Sequences.Count; ++i) { SequenceMultiBacktrackRuleRewritingGenerator ruleRewritingGenerator = new SequenceMultiBacktrackRuleRewritingGenerator( seqMulti, (SequenceRuleCall)seqMulti.Rules.Sequences[i], seqExprGen, seqHelper); ruleRewritingGenerator.EmitRewriting(source, seqGen, matchListName, enumeratorName, fireDebugEvents); } source.AppendFrontFormat("default: throw new Exception(\"Unknown pattern \" + {0}.Current.Pattern.PackagePrefixedName + \" in match!\");", enumeratorName); source.Unindent(); source.AppendFront("}\n"); // rule applied, now execute the sequence seqGen.EmitSequence(seqMulti.Seq, source); // if sequence execution failed, roll the changes back and try the next match source.AppendFront("if(!" + COMP_HELPER.GetResultVar(seqMulti.Seq) + ") {\n"); source.Indent(); source.AppendFront("procEnv.TransactionManager.Rollback(" + transactionIdName + ");\n"); source.AppendFront("procEnv.PerformanceInfo.RewritesPerformed = " + oldRewritesPerformedName + ";\n"); source.AppendFront("if(" + matchesTriedName + " < " + matchListName + ".Count) {\n"); // further match available -> try it source.Indent(); source.AppendFront("continue;\n"); source.Unindent(); source.AppendFront("} else {\n"); // all matches tried, all failed later on -> end in fail source.Indent(); source.AppendFront(COMP_HELPER.SetResultVar(seqMulti, "false")); source.AppendFront("break;\n"); source.Unindent(); source.AppendFront("}\n"); source.Unindent(); source.AppendFront("}\n"); // if sequence execution succeeded, commit the changes so far and succeed source.AppendFront("procEnv.TransactionManager.Commit(" + transactionIdName + ");\n"); source.AppendFront(COMP_HELPER.SetResultVar(seqMulti, "true")); source.AppendFront("break;\n"); source.Unindent(); source.AppendFront("}\n"); source.Unindent(); source.AppendFront("}\n"); }
/// <summary> /// pre-run for emitting the needed entities before emitting the real code /// - emits result variable declarations /// - emits sequence variable declarations (only once for every variable, declaration only possible at assignment targets) /// - collects used rules into knownRules, emit local rule declaration (only once for every rule) /// </summary> public void EmitNeededVarAndRuleEntities(Sequence seq, SourceBuilder source) { source.AppendFront(COMP_HELPER.DeclareResultVar(seq)); switch (seq.SequenceType) { case SequenceType.AssignUserInputToVar: case SequenceType.AssignRandomIntToVar: case SequenceType.AssignRandomDoubleToVar: case SequenceType.DeclareVariable: case SequenceType.AssignConstToVar: case SequenceType.AssignContainerConstructorToVar: case SequenceType.AssignVarToVar: { SequenceAssignToVar toVar = (SequenceAssignToVar)seq; EmitVarIfNew(toVar.DestVar, source); break; } case SequenceType.AssignSequenceResultToVar: case SequenceType.OrAssignSequenceResultToVar: case SequenceType.AndAssignSequenceResultToVar: { SequenceAssignSequenceResultToVar seqToVar = (SequenceAssignSequenceResultToVar)seq; EmitVarIfNew(seqToVar.DestVar, source); EmitNeededVarAndRuleEntities(seqToVar.Seq, source); break; } case SequenceType.RuleCall: case SequenceType.RuleAllCall: case SequenceType.RuleCountAllCall: { SequenceRuleCall seqRule = (SequenceRuleCall)seq; String ruleName = seqRule.PackagePrefixedName; if (!knownRules.ContainsKey(ruleName)) { knownRules.Add(ruleName, null); source.AppendFront("GRGEN_ACTIONS." + TypesHelper.GetPackagePrefixDot(seqRule.Package) + "Action_" + seqRule.Name + " " + "rule_" + TypesHelper.PackagePrefixedNameUnderscore(seqRule.Package, seqRule.Name)); source.Append(" = " + "GRGEN_ACTIONS." + TypesHelper.GetPackagePrefixDot(seqRule.Package) + "Action_" + seqRule.Name + ".Instance;\n"); } // no handling for the input arguments seqRule.ArgumentExpressions needed // because there can only be variable uses for (int i = 0; i < seqRule.ReturnVars.Length; ++i) { EmitVarIfNew(seqRule.ReturnVars[i], source); } if (seq.SequenceType == SequenceType.RuleCountAllCall) { SequenceRuleCountAllCall seqCountRuleAll = (SequenceRuleCountAllCall)seqRule; EmitVarIfNew(seqCountRuleAll.CountResult, source); } break; } case SequenceType.SequenceCall: { SequenceSequenceCall seqSeq = (SequenceSequenceCall)seq; // no handling for the input arguments seqSeq.ArgumentExpressions or the optional Subgraph needed // because there can only be variable uses for (int i = 0; i < seqSeq.ReturnVars.Length; ++i) { EmitVarIfNew(seqSeq.ReturnVars[i], source); } break; } case SequenceType.ForContainer: { SequenceForContainer seqFor = (SequenceForContainer)seq; EmitVarIfNew(seqFor.Var, source); if (seqFor.VarDst != null) { EmitVarIfNew(seqFor.VarDst, source); } EmitNeededVarAndRuleEntities(seqFor.Seq, source); break; } case SequenceType.ForIntegerRange: { SequenceForIntegerRange seqFor = (SequenceForIntegerRange)seq; EmitVarIfNew(seqFor.Var, source); EmitNeededVarAndRuleEntities(seqFor.Seq, source); break; } case SequenceType.ForIndexAccessEquality: { SequenceForIndexAccessEquality seqFor = (SequenceForIndexAccessEquality)seq; EmitVarIfNew(seqFor.Var, source); EmitNeededVarAndRuleEntities(seqFor.Seq, source); break; } case SequenceType.ForIndexAccessOrdering: { SequenceForIndexAccessOrdering seqFor = (SequenceForIndexAccessOrdering)seq; EmitVarIfNew(seqFor.Var, source); EmitNeededVarAndRuleEntities(seqFor.Seq, source); break; } case SequenceType.ForAdjacentNodes: case SequenceType.ForAdjacentNodesViaIncoming: case SequenceType.ForAdjacentNodesViaOutgoing: case SequenceType.ForIncidentEdges: case SequenceType.ForIncomingEdges: case SequenceType.ForOutgoingEdges: case SequenceType.ForReachableNodes: case SequenceType.ForReachableNodesViaIncoming: case SequenceType.ForReachableNodesViaOutgoing: case SequenceType.ForReachableEdges: case SequenceType.ForReachableEdgesViaIncoming: case SequenceType.ForReachableEdgesViaOutgoing: case SequenceType.ForBoundedReachableNodes: case SequenceType.ForBoundedReachableNodesViaIncoming: case SequenceType.ForBoundedReachableNodesViaOutgoing: case SequenceType.ForBoundedReachableEdges: case SequenceType.ForBoundedReachableEdgesViaIncoming: case SequenceType.ForBoundedReachableEdgesViaOutgoing: case SequenceType.ForNodes: case SequenceType.ForEdges: { SequenceForFunction seqFor = (SequenceForFunction)seq; EmitVarIfNew(seqFor.Var, source); EmitNeededVarAndRuleEntities(seqFor.Seq, source); break; } case SequenceType.ForMatch: { SequenceForMatch seqFor = (SequenceForMatch)seq; EmitVarIfNew(seqFor.Var, source); EmitNeededVarAndRuleEntities(seqFor.Seq, source); EmitNeededVarAndRuleEntities(seqFor.Rule, source); break; } case SequenceType.BooleanComputation: { SequenceBooleanComputation seqBoolComp = (SequenceBooleanComputation)seq; EmitNeededVarEntities(seqBoolComp.Computation, source); break; } default: foreach (Sequence childSeq in seq.Children) { EmitNeededVarAndRuleEntities(childSeq, source); } break; } }