1 package org.antlr.works.debugger.tree; 2 3 import org.antlr.xjlib.foundation.notification.XJNotificationCenter; 4 import org.antlr.xjlib.foundation.notification.XJNotificationObserver; 5 import org.antlr.runtime.Token; 6 import org.antlr.tool.Grammar; 7 import org.antlr.works.awtree.AWTreeModel; 8 import org.antlr.works.awtree.AWTreeNode; 9 import org.antlr.works.debugger.Debugger; 10 import org.antlr.works.prefs.AWPrefs; 11 import org.antlr.works.prefs.AWPrefsDialog; 12 13 import javax.swing.tree.TreeNode ; 14 import java.awt.*; 15 import java.util.*; 16 import java.util.List ; 17 47 48 public class DBParseTreeModel extends AWTreeModel implements XJNotificationObserver { 49 50 public Stack<ParseTreeNode> rules = new Stack<ParseTreeNode>(); 51 public Stack<Backtrack> backtrackStack = new Stack<Backtrack>(); 52 53 public Color lookaheadTokenColor; 54 public TreeNode lastNode; 55 public int line, pos; 56 57 public Debugger debugger; 58 59 public List <DBParseTreeModelListener> listeners = new ArrayList<DBParseTreeModelListener>(); 60 61 public DBParseTreeModel(Debugger debugger) { 62 this.debugger = debugger; 63 initRules(); 64 initColors(); 65 XJNotificationCenter.defaultCenter().addObserver(this, AWPrefsDialog.NOTIF_PREFS_APPLIED); 66 } 67 68 public void close() { 69 XJNotificationCenter.defaultCenter().removeObserver(this); 70 } 71 72 public void addListener(DBParseTreeModelListener listener) { 73 listeners.add(listener); 74 } 75 76 public void fireDataChanged() { 77 for (Iterator<DBParseTreeModelListener> iterator = listeners.iterator(); iterator.hasNext();) { 78 DBParseTreeModelListener listener = iterator.next(); 79 listener.modelChanged(this); 80 } 81 } 82 83 public void initRules() { 84 rules.clear(); 85 rules.push(new ParseTreeNode("root")); 86 } 87 88 public void initColors() { 89 lookaheadTokenColor = AWPrefs.getLookaheadTokenColor(); 90 } 91 92 public void clear() { 93 super.clear(); 94 95 initRules(); 96 backtrackStack.clear(); 97 98 setLastNode(null); 99 fireDataChanged(); 100 101 line = pos = 0; 102 } 103 104 public void setLastNode(TreeNode node) { 105 this.lastNode = node; 106 } 107 108 public TreeNode getLastNode() { 109 return lastNode; 110 } 111 112 public void setLocation(int line, int pos) { 113 this.line = line; 114 this.pos = pos; 115 } 116 117 public void pushRule(String name) { 118 ParseTreeNode parentRuleNode = rules.peek(); 119 120 ParseTreeNode ruleNode = new ParseTreeNode(name); 121 ruleNode.setPosition(line, pos); 122 rules.push(ruleNode); 123 124 addNode(parentRuleNode, ruleNode); 125 addNodeToCurrentBacktrack(ruleNode); 126 127 setLastNode(ruleNode); 128 } 129 130 public void popRule() { 131 rules.pop(); 132 } 133 134 public TreeNode getRootRule() { 135 return (TreeNode)rules.firstElement(); 136 } 137 138 public TreeNode peekRule() { 139 if(rules.isEmpty()) 140 return null; 141 else 142 return (TreeNode)rules.peek(); 143 } 144 145 public void addToken(Token token) { 146 ParseTreeNode ruleNode = rules.peek(); 147 ParseTreeNode elementNode = new ParseTreeNode(token, debugger.getGrammar().getANTLRGrammar()); 148 elementNode.setPosition(line, pos); 149 addNode(ruleNode, elementNode); 150 addNodeToCurrentBacktrack(elementNode); 151 setLastNode(elementNode); 152 } 153 154 public void addException(Exception e) { 155 ParseTreeNode ruleNode = rules.peek(); 156 ParseTreeNode errorNode = new ParseTreeNode(e); 157 errorNode.setPosition(line, pos); 158 addNode(ruleNode, errorNode); 159 addNodeToCurrentBacktrack(errorNode); 160 setLastNode(errorNode); 161 } 162 163 public void addNodeToCurrentBacktrack(ParseTreeNode node) { 164 if(backtrackStack.isEmpty()) 165 return; 166 167 Backtrack b = backtrackStack.peek(); 168 b.addNode(node); 169 } 170 171 public void beginBacktrack(int level) { 172 backtrackStack.push(new Backtrack(level)); 173 } 174 175 public void endBacktrack(int level, boolean success) { 176 Backtrack b = backtrackStack.pop(); 177 b.end(success); 178 setLastNode(b.getLastNode()); 179 } 180 181 public void notificationFire(Object source, String name) { 182 if(name.equals(AWPrefsDialog.NOTIF_PREFS_APPLIED)) { 183 initColors(); 184 } 185 } 186 187 public class ParseTreeNode extends DBTreeNode { 188 189 protected String s; 190 protected Exception e; 191 192 public ParseTreeNode(String s) { 193 this.s = s; 194 } 195 196 public ParseTreeNode(Exception e) { 197 this.e = e; 198 } 199 200 public ParseTreeNode(Token token, Grammar grammar) { 201 super(token, grammar); 202 } 203 204 public String toString() { 205 if(s != null) 206 return s; 207 else if(e != null) 208 return e.toString(); 209 else 210 return super.toString(); 211 } 212 213 } 214 215 public class Backtrack { 216 217 public int level; 218 public LinkedList<DBTreeNode> nodes = new LinkedList<DBTreeNode>(); 219 220 public Backtrack(int level) { 221 this.level = level; 222 } 223 224 228 229 public void addNode(DBTreeNode node) { 230 node.setColor(lookaheadTokenColor); 231 nodes.add(node); 232 } 233 234 public void end(boolean success) { 235 Color color = getColor(success); 236 for (int i = 0; i < nodes.size(); i++) { 237 DBTreeNode node = nodes.get(i); 238 node.setColor(color); 239 } 240 } 241 242 public AWTreeNode getLastNode() { 243 if(nodes.isEmpty()) 244 return null; 245 else 246 return (AWTreeNode) nodes.getLast(); 247 } 248 249 protected Color getColor(boolean success) { 250 Color c = success?Color.green.darker():Color.red; 251 for(int i=1; i<level; i++) { 252 c = c.darker().darker(); 253 } 254 return c; 255 } 256 257 } 258 259 } 260 | Popular Tags |