public static bool DependsOn(this SyntacticalDFARootState target, IOilexerGrammarProductionRuleEntry entry) { return(target.DependsOn(entry, new List <SyntacticalDFAState>())); }
private static bool DependsOn(this SyntacticalDFAState target, IOilexerGrammarProductionRuleEntry entry, List <SyntacticalDFAState> followed) { //Ensure that cyclic models don't recurse infinitely if (followed.Contains(target)) { return(target.ContainsRule(entry)); } //Add the current element to the followed elements followed.Add(target); var stateTransitionUnion = target.OutTransitions.FullCheck; var breakdown = stateTransitionUnion.Breakdown; //Step through the rules within the state. var helper = new DependsOnPredicatedHelper(); foreach (var rule in from rule in breakdown.Rules select rule.Source) { helper.rule = rule; SyntacticalDFARootState state = null; //Exit with true when found. if (rule == entry) { return(true); } //otherwise, if the root-state of the rule depends upon it... else if ((state = target[rule]).DependsOn(entry, followed)) { return(true); } /* * * ... in the event that the initial state of the rule is * an edge state, continue checking the state after that rule * is called for, to ensure that the dependencies after that * rule's reference point are considered. i.e. a hidden * dependency. * */ else if (state.CanBeEmpty && target.OutTransitions[target.OutTransitions.Keys.First(helper.rulePredicate)].DependsOn(entry, followed)) { return(true); } } /* * * Same thing as the above, but only on the tokens * instead of the rules. * */ foreach (var token in breakdown.Tokens) { helper.token = token as InlinedTokenEntry; if ((helper.token == null) || (helper.token.DFAState == null)) { continue; } if (helper.token.DFAState.IsEdge && target.OutTransitions[target.OutTransitions.Keys.First(helper.tokenPredicate)].DependsOn(entry, followed)) { return(true); } } helper.token = null; helper.rule = null; return(false); }