// package NFAGraph; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Hashtable; import dir.Tree; /* * Exception for NFA */ class NFAException extends Exception { private static final long serialVersionUID = 1L; public NFAException(String message) { super(message); } } /* * structure for NFAGraph */ class NFAGraph{ private Integer start; private ArrayList endList; // List of end node num. private ArrayList graphTable; // graph shown as table public String toString(){ String returnString = ""; returnString += String.format("%d [shape=Diamond]\n" , this.start); if (this.graphTable.length == 0){ returnString += "\n"; } else{ for (int i=0; i < this.graphTable.size() ; i++ ){ Integer orig = this.graphTable.get(i).getOrig(); Integer dest = this.graphTable.get(i).getDest(); returnString += String.format("%d -> %d\n" , orig , dest); } } String endString = ""; for (int i=0; i getEndList(){ return this.endList; } /** * @return the start */ public Integer getStart() { return this.start; } public ArrayList getGraphTable(){ return this.graphTable; } public setEndList(ArrayList endList){ this.endList = endList; } public setStart(Integer startId){ this.start = startId; } public addGraphPath(NFAGraphPath path){ this.graphTable.add(path); } public static void main(String[] args) { NFAGraph _a = new NFAGraph(); _a.start = 1; NFAGraphPath p1 = new NFAGraphPath(1, 2, "a"); NFAGraphPath p2 = new NFAGraphPath(2, 3, "g"); NFAGraphPath p3 = new NFAGraphPath(2, 4, "c"); Tree pattern = new Tree("SET"); pattern.appendChildrenList(Arrays.asList("F", "G", "H")); NFAGraphPath p4 = new NFAGraphPath(2, 5, pattern); _a.graphTable.add(p1); _a.graphTable.add(p2); _a.graphTable.add(p3); _a.graphTable.add(p4); try{ Hashtable h = _a.nfaTableToHashMap(); int z = 1 + 1; } catch (NFAException e) { System.out.println(e); } } public NFAGraph(int orig, int dest, NFAGraphPath path){ this.start = (Integer) orig; this.endList = new ArrayList(Arrays.asList((Integer) dest)); this.graphTable = new ArrayList(Arrays.asList(path)); } public NFAGraph(){ this.start = (Integer)-1 ; // impossible value this.endList = new ArrayList(); this.graphTable = new ArrayList(); } public NFAGraph(int orig, ArrayList destList, NFAGraphPath path){ this.start = (Integer)orig; this.endList = destList; this.graphTable = new ArrayList(Arrays.asList(path)); } /* return a Hashtable in the form of: * Hashtable< OrigId, > * */ Hashtable,Integer>> nfaTableToHashMap () throws NFAException{ Hashtable,Integer>> graphHashMap = new Hashtable(); for (int i=0;i pattern = this.graphTable.get(i).getPatt(); if (graphHashMap.containsKey(orig)){ if (graphHashMap.get(orig).containsKey(pattern)){ throw new NFAException( "Each 2 links from the same link shouldn't have the same value."); } }else{ // graph_dict[orig] = dict() graphHashMap.put(orig, new Hashtable()); } graphHashMap.get(orig).put(pattern, dest); } return graphHashMap; } /* * (value_match) * Match a char string with char pattern string (1-char) "pattern". */ boolean charPatternMatch(String patt, String c) throws NFAException{ if (c.length()>1){ throw NFAException("Char or pattern input too many."); } else if(patt.length()>1){ throw NFAException("patt or pattern input too many."); } else{ if(c == patt){ return true; } else{ return false; } } } /* * Match a char string with char pattern (tree) "pattern". */ boolean charPatternMatch(Tree patt, String c) throws NFAException{ if (c.length()>1){ throw NFAException("Char input too many."); } else{ head = patt.getNode(); if (head == "NOT"){ if(patt.getChildrenList().size()>1){ throw NFAException("in char pattern NOT contains only 1 sub-pattern"); return not(this.charPatternMatch(patt.getChildrenList().get(0),c)); } } else if(patt.getNode() == "SET"){ this.charPatternMatchSet(patt, c); } else if (patt.getNode() == "RANGE"){ this.charPatternMatchRange(patt, c); } else if (patt.getNode().length() == 1){ thischarPatternMatch(patt.getNode(),c); // char-to-char matching } else{ throw NFAException("The form of a char pattern tree is not acceptable."); } } } /* * check part for patt of which head node is "SET". */ boolean charPatternMatchSet(Tree patt, String c) throws NFAException{ if (patt.getChildrenList().size() == 0){ throw NFAException("in char pattern SET contains at least 1 sub-pattern"); }else{ for (int i=0;i patt, String c) throws NFAException{ if (patt.getChildrenList().size() > 2){ throw NFAException("in char pattern RANGE contains only 2 chars"); } else if (patt.getChildrenList().get(0).length()>1 || patt.getChildrenList().get(1).length()>1){ throw NFAException("In char pattern RANGE contains no string of which length > 1."); } else { char lowerBound = patt.getChildrenList().get(0).charAt(0); char upperBound = patt.getChildrenList().get(1).charAt(0); if (lowerBound > upperBound){ throw NFAException("In char pattern RANGE the lower_bound must not bigger than upper bound."); } else{ if (c.charAt(0) >= lowerBound && c.charAt(0) <= upperBound){ return true; } else{ return false; } } } } public Integer transitStrInGraph(int startPoint, String str){ Integer status = (Integer) startPoint; Hashtable,Integer>> nfaHashMap = this.nfaTableToHashMap(); for (int i=0;i treeKey : nfaHashMap.get(status).keySet()){ boolean treeKeyMatched = this.charPatternMatch(treeKey, c); if (treeKeyMatched){ status = nfaHashMap.get(status).get(treeKey); } } } return status; } } /* * Path for NFAGraph.graph * [2]-- a ->[3] * orig = 2; * dest = 3; * patt = ['a']; */ class NFAGraphPath { private Integer orig; private Integer dest; private Tree patt; public NFAGraphPath(int ori, int des, String ptn) { this.orig = (Integer) ori; this.dest = (Integer) des; this.patt = new Tree(ptn); } public NFAGraphPath(int ori, int des, Tree ptnTree) { this.orig = (Integer) ori; this.dest = (Integer) des; this.patt = ptnTree; } Integer getOrig() { return this.orig; } Integer getDest() { return this.dest; } Tree getPatt() { return this.patt; } } /** * containing mainaulations for the nfa graph genarating. */ class NfaManipulation{ Integer id; // the id number that will be returned by nextId public NNfaManipulation(){ this.id = (Integer) 0; } Integer nextId (){ Integer retId = this.id; this.id += 1; return retId; } public NFAGraph makeSimpleNFA(String pattern){ Integer start = this.nextId(); Integer end = this.nextId(); NFAGraphPath path = NFAGraphPath(start, end, pattern); NFAGraph nfa = NFAGraph(start, end, path); return nfa; } public NFAGraph makeSimpleNFA(Tree pattern){ Integer start = this.nextId(); Integer end = this.nextId(); NFAGraphPath path = NFAGraphPath(start, end, pattern); NFAGraph nfa = NFAGraph(start, end, path); return nfa; } /** * xy */ public nfaConcat(NFAGraph nfa1, NFAGraph nfa2){ Integer nfa1Start = nfa1.getStart(); ArrayList nfa1EndList = nfa1.getEndList(); ArrayList nfa1NFAGraphList = nfa1.getGraphTable(); ArrayList nfa2NFAGraphList = nfa2.getGraphTable(); NFAGraph resultNFA = new NFAGraph(); resultNFA.setStart(nfa1Start); concatNFAGraph(nfa2, nfa1EndList, nfa1NFAGraphList, nfa2NFAGraphList, resultNFA); resultNFA.setEndList(nfa2.getEndList()); return resultNFA; } private void concatNFAGraph(NFAGraph nfa2, ArrayList nfa1EndList, ArrayList nfa1NFAGraphList, ArrayList nfa2NFAGraphList, NFAGraph resultNFA) { for(int i=0; i nfa1EndList = nfa1.getEndList(); ArrayList nfa2EndList = nfa2.getEndList(); ArrayList nfa1NFAGraphList = nfa1.getGraphTable(); ArrayList nfa2NFAGraphList = nfa2.getGraphTable(); NFAGraph resultNFA = new NFAGraph(); resultNFA.setStart(nfa1Start); ArrayList NewEndList = nfa1EndList; for(int i=0; i resultNFAEndList = nfa1.getEndList(); for (int i=0; i nfa1EndList = nfa1.getEndList(); ArrayList nfa2EndList = nfa2.getEndList(); for(int i=0;i