这两天时间不多啊, 明天下午要考AI了, 没什么时间写这个, 今天抽空把昨天的留下的作业(用C写不下去的那个...)转移到了java上, 只完成了Thompson那一部分, 之后的两部分估计要等考试完再继续了, 因为代码还没写完就不扔github上了... 直接贴代码了 :
包结构如图...
Entry 是我用来测试代码的, 暂时可以认为是程序入口...
Dfa.java
1 package lexerGenerator.dataStructure.dfaAndNfa; 2 3 import lexerGenerator.dataStructure.pointsAndEdges.Edge; 4 import lexerGenerator.dataStructure.pointsAndEdges.State; 5 6 public class Dfa { 7 public int start; 8 public int accept; 9 public State state; 10 11 public Dfa() { 12 start = -1; 13 accept = -1; 14 state = null; 15 } 16 17 @Override 18 public String toString() { 19 String str = ""; 20 str += "start : " + start + " accept : " + accept + "\n"; 21 State cur = state; 22 while(cur != null){ 23 Edge edge = cur.edges; 24 while(edge != null){ 25 str += edge.from.num + "---->" + edge.ch + "---->" + edge.to.num + "\n"; 26 edge = edge.next; 27 } 28 cur = cur.next; 29 } 30 return str; 31 } 32 }
Edge.java
1 package lexerGenerator.dataStructure.pointsAndEdges; 2 3 import lexerGenerator.dataStructure.dfaAndNfa.Dfa; 4 5 public class Edge { 6 public int ch; 7 public State from; 8 public State to; 9 public Edge next; 10 11 public Edge(State from, State to, int ch) { 12 this.from = from; 13 this.to = to; 14 this.ch = ch; 15 } 16 17 public static void addEdge(Dfa dfa, int from, int to, int ch){ 18 State left = lookUp(dfa, from); 19 State right = lookUp(dfa, to); 20 if(left.edges == null){ 21 left.edges = new Edge(left, right, ch); 22 }else{ 23 Edge edge = left.edges; 24 while(edge.next != null){ 25 edge = edge.next; 26 } 27 edge.next = new Edge(left, right, ch); 28 } 29 } 30 31 public static State lookUp(Dfa dfa, int num){ 32 State state = dfa.state; 33 if(state == null){ 34 dfa.state = new State(num); 35 return dfa.state; 36 } 37 while(state != null){ 38 if(state.num == num){ 39 return state; 40 } 41 state = state.next; 42 } 43 State temp = new State(num); 44 dfa.state.append(temp); 45 return temp; 46 } 47 }
State.java
1 package lexerGenerator.dataStructure.pointsAndEdges; 2 3 public class State { 4 public int num; 5 public State next; 6 public Edge edges; 7 8 public State(int num) { 9 this.num = num; 10 edges = null; 11 next = null; 12 } 13 14 public void append(State state){ 15 State temp = this; 16 while(temp.next != null){ 17 temp = temp.next; 18 } 19 20 temp.next = state; 21 } 22 }
Re.java
1 package lexerGenerator.dataStructure.re; 2 3 public class Re { 4 5 6 public static final int EBS = -5; 7 8 public static enum Kind{ 9 Concat, Option, Closure, Char 10 }; 11 12 public Kind kind; 13 }
Re_char.java
1 package lexerGenerator.dataStructure.re; 2 3 public class Re_char extends Re{ 4 public int ch; 5 6 public Re_char(int ch) { 7 this.ch = ch; 8 kind = Kind.Char; 9 } 10 }
Re_closure.java
1 package lexerGenerator.dataStructure.re; 2 3 public class Re_closure extends Re{ 4 public Re re; 5 6 public Re_closure(Re re) { 7 this.re = re; 8 kind = Kind.Closure; 9 } 10 }
Re_concat.java
1 package lexerGenerator.dataStructure.re; 2 3 4 5 public class Re_concat extends Re{ 6 public Re left; 7 public Re right; 8 9 public Re_concat(Re left, Re right) { 10 this.left = left; 11 this.right = right; 12 kind = Kind.Concat; 13 } 14 }
Re_option.java
1 package lexerGenerator.dataStructure.re; 2 3 public class Re_option extends Re{ 4 public Re left; 5 public Re right; 6 7 public Re_option(Re left, Re right) { 8 this.left = left; 9 this.right = right; 10 kind = Kind.Option; 11 } 12 }
Thompson.java
1 package lexerGenerator.thompson; 2 3 import lexerGenerator.dataStructure.dfaAndNfa.Dfa; 4 import lexerGenerator.dataStructure.pointsAndEdges.Edge; 5 import lexerGenerator.dataStructure.re.*; 6 7 public class Thompson { 8 public static int num = 0; 9 public static Dfa dfa; 10 11 public static Dfa thompson(Re re){ 12 dfa = new Dfa(); 13 thompsonLoop(re); 14 return dfa; 15 } 16 17 static void thompsonLoop(Re re){ 18 switch (re.kind){ 19 case Char: 20 Re_char re_char = (Re_char)re; 21 int from = next(); 22 int to = next(); 23 Edge.addEdge(dfa ,from, to, re_char.ch); 24 dfa.start = from; 25 dfa.accept = to; 26 break; 27 case Concat: 28 Re_concat re_concat = (Re_concat) re; 29 thompsonLoop(re_concat.left); 30 int preStart = dfa.start; 31 int preAccept = dfa.accept; 32 thompsonLoop(re_concat.right); 33 Edge.addEdge(dfa, preAccept, dfa.start, Re.EBS); 34 dfa.start = preStart; 35 break; 36 case Option: 37 Re_option re_option = (Re_option)re; 38 thompsonLoop(re_option.left); 39 int leftStart = dfa.start; 40 int leftAccept = dfa.accept; 41 thompsonLoop(re_option.right); 42 int newStart = next(); 43 int newAccept = next(); 44 Edge.addEdge(dfa, newStart, leftStart, Re.EBS); 45 Edge.addEdge(dfa, newStart, dfa.start, Re.EBS); 46 Edge.addEdge(dfa, leftAccept, newAccept, Re.EBS); 47 Edge.addEdge(dfa, dfa.accept, newAccept, Re.EBS); 48 dfa.start = newStart; 49 dfa.accept = newAccept; 50 break; 51 case Closure: 52 Re_closure re_closure = (Re_closure) re; 53 thompsonLoop(re_closure.re); 54 newStart = next(); 55 newAccept = next(); 56 Edge.addEdge(dfa, newStart, dfa.start, Re.EBS); 57 Edge.addEdge(dfa, newStart, newAccept, Re.EBS); 58 Edge.addEdge(dfa, dfa.accept, newAccept, Re.EBS); 59 Edge.addEdge(dfa, dfa.accept, dfa.start, Re.EBS); 60 dfa.start = newStart; 61 dfa.accept = newAccept; 62 break; 63 default: 64 break; 65 } 66 } 67 68 private static int next(){ 69 return num++; 70 } 71 }
Entry.java
package lexerGenerator; import lexerGenerator.dataStructure.dfaAndNfa.Dfa; import lexerGenerator.dataStructure.re.*; import lexerGenerator.thompson.Thompson; public class Entry { public static void main(String[] args) { Re re1 = new Re_closure(new Re_option(new Re_char('a'), new Re_char('b'))); Dfa dfa = Thompson.thompson(re1); System.out.println(dfa); } }
代码比较简单, 所以没加注释, 测试结果如下 :
考完AI之后再补缺的部分...