/*
* JFLAP - Formal Languages and Automata Package
*
*
* Susan H. Rodger
* Computer Science Department
* Duke University
* August 27, 2009
* Copyright (c) 2002-2009
* All rights reserved.
* JFLAP is open source software. Please see the LICENSE for terms.
*
*/
package grammar.cfg;
import grammar.Grammar;
import grammar.GrammarToAutomatonConverter;
import grammar.Production;
import automata.Automaton;
import automata.State;
import automata.StatePlacer;
import automata.Transition;
import automata.pda.PDATransition;
/**
* The CFG to PDA (LR parsing) converter can be used to convert a context free
* grammar to an equivalent pushdown automaton that can be used for LR parsing.
* You can perform this conversion simply by calling convertToAutomaton, or you
* can do it step by step by first calling createStatesForConversion, which will
* add the necessary states for the conversion to your pushdown automaton, and
* then calling getTransitionForProduction for each production in the grammar.
* Of course you must then add the returned transition to your pushdown
* automaton for each call to getTransitionForProduction. When you have done
* this for every production in your grammar, you will have an equivalent
* pushdown automaton.
*
* @author Ryan Cavalcante
*/
public class CFGToPDALRConverter extends GrammarToAutomatonConverter {
/**
* Creates an instance of CFGToPDALRConverter
.
*/
public CFGToPDALRConverter() {
}
/**
* Returns the reverse of string
e.g. it would return "cba"
* for "abc".
*
* @param string
* the string
* @return the reverse of string
*/
private String getReverse(String string) {
StringBuffer buffer = new StringBuffer();
for (int k = string.length() - 1; k >= 0; k--) {
buffer.append(string.charAt(k));
}
return buffer.toString();
}
/**
* Returns the transition created by converting production
to
* its equivalent transition.
*
* @param production
* the production
* @return the equivalent transition.
*/
public Transition getTransitionForProduction(Production production) {
String lhs = production.getLHS();
String rhs = production.getRHS();
String rrhs = getReverse(rhs);
Transition transition = new PDATransition(START_STATE, START_STATE, "",
rrhs, lhs);
return transition;
}
/**
* Adds all states to automaton
necessary for the conversion
* of grammar
to its equivalent automaton. This creates three
* states--an initial state, an intermediate state, and a final state. It
* also adds transitions connecting the three states, and transitions for
* each terminal in grammar
*
* @param grammar
* the grammar being converted.
* @param automaton
* the automaton being created.
*/
public void createStatesForConversion(Grammar grammar, Automaton automaton) {
initialize();
StatePlacer sp = new StatePlacer();
State initialState = automaton.createState(sp
.getPointForState(automaton));
automaton.setInitialState(initialState);
START_STATE = initialState;
State intermediateState = automaton.createState(sp
.getPointForState(automaton));
State finalState = automaton
.createState(sp.getPointForState(automaton));
automaton.addFinalState(finalState);
String startVariable = grammar.getStartVariable();
PDATransition trans1 = new PDATransition(initialState,
intermediateState, "", startVariable, "");
automaton.addTransition(trans1);
PDATransition trans2 = new PDATransition(intermediateState, finalState,
"", BOTTOM_OF_STACK, "");
automaton.addTransition(trans2);
String[] terminals = grammar.getTerminals();
for (int k = 0; k < terminals.length; k++) {
PDATransition trans = new PDATransition(initialState, initialState,
terminals[k], "", terminals[k]);
automaton.addTransition(trans);
}
}
/** The start state. */
protected State START_STATE;
}