protected virtual StringTemplate WalkFixedDFAGeneratingStateMachine( TemplateGroup templates, DFA dfa, DFAState s, int k) { //System.Console.Out.WriteLine( "walk " + s.stateNumber + " in dfa for decision " + dfa.decisionNumber ); if (s.IsAcceptState) { StringTemplate dfaST2 = templates.GetInstanceOf("dfaAcceptState"); dfaST2.SetAttribute("alt", s.GetUniquelyPredictedAlt()); return(dfaST2); } // the default templates for generating a state and its edges // can be an if-then-else structure or a switch string dfaStateName = "dfaState"; string dfaLoopbackStateName = "dfaLoopbackState"; string dfaOptionalBlockStateName = "dfaOptionalBlockState"; string dfaEdgeName = "dfaEdge"; if (_parentGenerator.CanGenerateSwitch(s)) { dfaStateName = "dfaStateSwitch"; dfaLoopbackStateName = "dfaLoopbackStateSwitch"; dfaOptionalBlockStateName = "dfaOptionalBlockStateSwitch"; dfaEdgeName = "dfaEdgeSwitch"; } StringTemplate dfaST = templates.GetInstanceOf(dfaStateName); if (dfa.NFADecisionStartState.decisionStateType == NFAState.LOOPBACK) { dfaST = templates.GetInstanceOf(dfaLoopbackStateName); } else if (dfa.NFADecisionStartState.decisionStateType == NFAState.OPTIONAL_BLOCK_START) { dfaST = templates.GetInstanceOf(dfaOptionalBlockStateName); } dfaST.SetAttribute("k", k); dfaST.SetAttribute("stateNumber", s.StateNumber); dfaST.SetAttribute("semPredState", s.IsResolvedWithPredicates); /* * string description = dfa.getNFADecisionStartState().Description; * description = parentGenerator.target.getTargetStringLiteralFromString( description ); * //System.Console.Out.WriteLine( "DFA: " + description + " associated with AST " + dfa.getNFADecisionStartState() ); * if ( description != null ) * { * dfaST.SetAttribute( "description", description ); * } */ int EOTPredicts = NFA.INVALID_ALT_NUMBER; DFAState EOTTarget = null; //System.Console.Out.WriteLine( "DFA state " + s.stateNumber ); for (int i = 0; i < s.NumberOfTransitions; i++) { Transition edge = (Transition)s.GetTransition(i); //System.Console.Out.WriteLine( "edge " + s.stateNumber + "-" + edge.label.ToString() + "->" + edge.target.stateNumber ); if (edge.Label.Atom == Label.EOT) { // don't generate a real edge for EOT; track alt EOT predicts // generate that prediction in the else clause as default case EOTTarget = (DFAState)edge.Target; EOTPredicts = EOTTarget.GetUniquelyPredictedAlt(); /* * System.Console.Out.WriteLine("DFA s"+s.stateNumber+" EOT goes to s"+ * edge.target.stateNumber+" predicates alt "+ * EOTPredicts); */ continue; } StringTemplate edgeST = templates.GetInstanceOf(dfaEdgeName); // If the template wants all the label values delineated, do that if (edgeST.impl.TryGetFormalArgument("labels") != null) { List <string> labels = edge.Label.Set.Select(value => _parentGenerator.GetTokenTypeAsTargetLabel(value)).ToList(); edgeST.SetAttribute("labels", labels); } else { // else create an expression to evaluate (the general case) edgeST.SetAttribute("labelExpr", _parentGenerator.GenLabelExpr(templates, edge, k)); } // stick in any gated predicates for any edge if not already a pred if (!edge.Label.IsSemanticPredicate) { DFAState target = (DFAState)edge.Target; SemanticContext preds = target.GetGatedPredicatesInNFAConfigurations(); if (preds != null) { //System.Console.Out.WriteLine( "preds=" + target.getGatedPredicatesInNFAConfigurations() ); StringTemplate predST = preds.GenExpr(_parentGenerator, _parentGenerator.Templates, dfa); edgeST.SetAttribute("predicates", predST); } } StringTemplate targetST = WalkFixedDFAGeneratingStateMachine(templates, dfa, (DFAState)edge.Target, k + 1); edgeST.SetAttribute("targetState", targetST); dfaST.SetAttribute("edges", edgeST); //System.Console.Out.WriteLine( "back to DFA " + dfa.decisionNumber + "." + s.stateNumber ); } // HANDLE EOT EDGE if (EOTPredicts != NFA.INVALID_ALT_NUMBER) { // EOT unique predicts an alt dfaST.SetAttribute("eotPredictsAlt", EOTPredicts); } else if (EOTTarget != null && EOTTarget.NumberOfTransitions > 0) { // EOT state has transitions so must split on predicates. // Generate predicate else-if clauses and then generate // NoViableAlt exception as else clause. // Note: these predicates emanate from the EOT target state // rather than the current DFAState s so the error message // might be slightly misleading if you are looking at the // state number. Predicates emanating from EOT targets are // hoisted up to the state that has the EOT edge. for (int i = 0; i < EOTTarget.NumberOfTransitions; i++) { Transition predEdge = (Transition)EOTTarget.GetTransition(i); StringTemplate edgeST = templates.GetInstanceOf(dfaEdgeName); edgeST.SetAttribute("labelExpr", _parentGenerator.GenSemanticPredicateExpr(templates, predEdge)); // the target must be an accept state //System.Console.Out.WriteLine( "EOT edge" ); StringTemplate targetST = WalkFixedDFAGeneratingStateMachine(templates, dfa, (DFAState)predEdge.Target, k + 1); edgeST.SetAttribute("targetState", targetST); dfaST.SetAttribute("edges", edgeST); } } return(dfaST); }