/** an experimental method to generate random phrases for a given
* grammar given a start rule. Return a list of token types.
*/
protected static void randomPhrase(Grammar g, List<Integer> tokenTypes, String startRule) {
NFAState state = g.getRuleStartState(startRule);
NFAState stopState = g.getRuleStopState(startRule);
Stack<NFAState> ruleInvocationStack = new Stack<NFAState>();
while ( true ) {
if ( state==stopState && ruleInvocationStack.isEmpty() ) {
break;
}
if ( debug ) System.out.println("state "+state);
if ( state.getNumberOfTransitions()==0 ) {
if ( debug ) System.out.println("dangling state: "+state);
return;
}
// end of rule node
if ( state.isAcceptState() ) {
NFAState invokingState = ruleInvocationStack.pop();
if ( debug ) System.out.println("pop invoking state "+invokingState);
//System.out.println("leave "+state.enclosingRule.name);
RuleClosureTransition invokingTransition =
(RuleClosureTransition)invokingState.transition[0];
// move to node after state that invoked this rule
state = invokingTransition.followState;
continue;
}
if ( state.getNumberOfTransitions()==1 ) {
// no branching, just take this path
Transition t0 = state.transition[0];
if ( t0 instanceof RuleClosureTransition ) {
ruleInvocationStack.push(state);
if ( debug ) System.out.println("push state "+state);
//System.out.println("call "+((RuleClosureTransition)t0).rule.name);
//System.out.println("stack depth="+ruleInvocationStack.size());
}
else if ( t0.label.isSet() || t0.label.isAtom() ) {
tokenTypes.add( getTokenType(t0.label) );
}
state = (NFAState)t0.target;
continue;
}
int decisionNumber = state.getDecisionNumber();
if ( decisionNumber==0 ) {
System.out.println("weird: no decision number but a choice node");
continue;
}
// decision point, pick ith alternative randomly
int n = g.getNumberOfAltsForDecisionNFA(state);
int randomAlt = random.nextInt(n) + 1;
if ( debug ) System.out.println("randomAlt="+randomAlt);
NFAState altStartState =
g.getNFAStateForAltOfDecision(state, randomAlt);
Transition t = altStartState.transition[0];
state = (NFAState)t.target;
}
}