/** 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 tokenTypes, String startRule) {
NFAState state = g.getRuleStartState(startRule);
NFAState stopState = g.getRuleStopState(startRule);
Stack ruleInvocationStack = new Stack();
while ( true ) {
if ( state==stopState && ruleInvocationStack.size()==0 ) {
break;
}
//System.out.println("state "+state);
if ( state.getNumberOfTransitions()==0 ) {
//System.out.println("dangling state: "+state);
return;
}
// end of rule node
if ( state.isAcceptState() ) {
NFAState invokingState = (NFAState)ruleInvocationStack.pop();
// System.out.println("pop invoking state "+invokingState);
RuleClosureTransition invokingTransition =
(RuleClosureTransition)invokingState.transition(0);
// move to node after state that invoked this rule
state = invokingTransition.getFollowState();
continue;
}
if ( state.getNumberOfTransitions()==1 ) {
// no branching, just take this path
Transition t0 = state.transition(0);
if ( t0 instanceof RuleClosureTransition ) {
ruleInvocationStack.push(state);
// System.out.println("push state "+state);
int ruleIndex = ((RuleClosureTransition)t0).getRuleIndex();
//System.out.println("invoke "+g.getRuleName(ruleIndex));
}
else if ( !t0.label.isEpsilon() ) {
tokenTypes.add( getTokenType(t0.label) );
//System.out.println(t0.label.toString(g));
}
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;
//System.out.println("randomAlt="+randomAlt);
NFAState altStartState =
g.getNFAStateForAltOfDecision(state, randomAlt);
Transition t = altStartState.transition(0);
/*
start of a decision could never be a labeled transition
if ( !t.label.isEpsilon() ) {
tokenTypes.add( getTokenType(t.label) );
}