/****************************************************************************** * Compilation: javac NFA.java * Execution: java NFA regexp text * Dependencies: Stack.java Bag.java Digraph.java DirectedDFS.java * * % java NFA "(A*B|AC)D" AAAABD * true * * % java NFA "(A*B|AC)D" AAAAC * false * * % java NFA "(a|(bc)*d)*" abcbcd * true * * % java NFA "(a|(bc)*d)*" abcbcbcdaaaabcbcdaaaddd * true * * Remarks * ----------- * The following features are not supported: * - The + operator * - Multiway or * - Metacharacters in the text * - Character classes. * ******************************************************************************/ /** * The {@code NFA} class provides a data type for creating a * nondeterministic finite state automaton (NFA) from a regular * expression and testing whether a given string is matched by that regular * expression. * It supports the following operations: concatenation, * closure, binary or, and parentheses. * It does not support mutiway or, character classes, * metacharacters (either in the text or pattern), * capturing capabilities, greedy or reluctant * modifiers, and other features in industrial-strength implementations * such as {@link java.util.regex.Pattern} and {@link java.util.regex.Matcher}. *
* This implementation builds the NFA using a digraph and a stack * and simulates the NFA using digraph search (see the textbook for details). * The constructor takes time proportional to m, where m * is the number of characters in the regular expression. * The recognizes method takes time proportional to m n, * where n is the number of characters in the text. *
* For additional documentation,
* see Section 5.4 of
* Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class NFA {
private Digraph graph; // digraph of epsilon transitions
private String regexp; // regular expression
private final int m; // number of characters in regular expression
/**
* Initializes the NFA from the specified regular expression.
*
* @param regexp the regular expression
*/
public NFA(String regexp) {
this.regexp = regexp;
m = regexp.length();
Stack