// A -> X B => (A)--[X]-->(B)
convertComponent(comp.getComponent(p.getNonterminal1()), mlfa);
mlfa.addIdentityTransition(nt_states[a.getKey()], nt_states[p.getNonterminal2().getKey()], getMLFAStatePair(p.getNonterminal1()));
} else {
// A -> X Y => (A)--[X]-->(R), (R)--[Y]-->(T)
MLFAState r = mlfa.addState();
convertComponent(comp.getComponent(p.getNonterminal1()), mlfa);
convertComponent(comp.getComponent(p.getNonterminal2()), mlfa);
mlfa.addIdentityTransition(nt_states[a.getKey()], r, getMLFAStatePair(p.getNonterminal1()));
mlfa.addIdentityTransition(r, c.getState(), getMLFAStatePair(p.getNonterminal2()));
}
}
public void visitAutomatonProduction(Nonterminal a, AutomatonProduction p) {
// A -> reg => (A)--[reg]-->(T)
mlfa.addAutomatonTransition(nt_states[a.getKey()], c.getState(), p.getAutomaton());
}
public void visitUnaryProduction(Nonterminal a, UnaryProduction p) {
// A -> op1(X) => (A)--[op1(X)]-->(T)
convertComponent(comp.getComponent(p.getNonterminal()), mlfa);
mlfa.addUnaryTransition(nt_states[a.getKey()], c.getState(), p.getOperation(), getMLFAStatePair(p.getNonterminal()));
}
public void visitBinaryProduction(Nonterminal a, BinaryProduction p) {
// A -> op2(X,Y) => (A)--[op2(X,Y)]-->(T)
convertComponent(comp.getComponent(p.getNonterminal1()), mlfa);
convertComponent(comp.getComponent(p.getNonterminal2()), mlfa);
mlfa.addBinaryTransition(nt_states[a.getKey()], c.getState(), p.getOperation(),
getMLFAStatePair(p.getNonterminal1()), getMLFAStatePair(p.getNonterminal2()));
}
public void visitEpsilonProduction(Nonterminal a, EpsilonProduction p) {
// A -> "" => (A)--e-->(T)
mlfa.addEpsilonTransition(nt_states[a.getKey()], c.getState());
}
});
} else {
// component is left recursive
p.visitBy(a, new ProductionVisitor() {
public void visitUnitProduction(Nonterminal a, UnitProduction p) {
if (c.contains(p.getNonterminal())) {
// A -> B => (B)---e--->(A)
mlfa.addEpsilonTransition(nt_states[p.getNonterminal().getKey()], nt_states[a.getKey()]);
} else {
// A -> X => (S)--[X]-->(A)
convertComponent(comp.getComponent(p.getNonterminal()), mlfa);
mlfa.addIdentityTransition(c.getState(), nt_states[a.getKey()], getMLFAStatePair(p.getNonterminal()));
}
}
public void visitPairProduction(Nonterminal a, PairProduction p) {
if (c.contains(p.getNonterminal1())) {
// A -> B X => (B)--[X]-->(A)
convertComponent(comp.getComponent(p.getNonterminal2()), mlfa);
mlfa.addIdentityTransition(nt_states[p.getNonterminal1().getKey()], nt_states[a.getKey()], getMLFAStatePair(p.getNonterminal2()));
} else {
// A -> X Y => (S)--[X]-->(R), (R)--[Y]-->(A)
MLFAState r = mlfa.addState();
convertComponent(comp.getComponent(p.getNonterminal1()), mlfa);
convertComponent(comp.getComponent(p.getNonterminal2()), mlfa);
mlfa.addIdentityTransition(c.getState(), r, getMLFAStatePair(p.getNonterminal1()));
mlfa.addIdentityTransition(r, nt_states[a.getKey()], getMLFAStatePair(p.getNonterminal2()));
}