1 package org.antlr.works.grammar.decisiondfa; 2 3 import org.antlr.analysis.DFA; 4 import org.antlr.analysis.NFAState; 5 import org.antlr.tool.Grammar; 6 import org.antlr.tool.Rule; 7 import org.antlr.works.ate.ATEUnderlyingManager; 8 import org.antlr.works.components.grammar.CEditorGrammar; 9 import org.antlr.works.grammar.EngineGrammar; 10 import org.antlr.works.syntax.element.ElementRule; 11 12 import java.awt.*; 13 import java.util.*; 14 import java.util.List ; 15 16 46 47 public class DecisionDFAEngine { 48 49 private CEditorGrammar editor; 50 private EngineGrammar engineGrammar; 51 52 private Set<Integer > usesSemPreds = new HashSet<Integer >(); 53 private Set<Integer > usesSynPreds = new HashSet<Integer >(); 54 55 private Map<Integer ,List <Integer >> decisionDFA = new HashMap<Integer , List <Integer >>(); 56 57 public DecisionDFAEngine(CEditorGrammar editor) { 58 this.editor = editor; 59 } 60 61 public void reset() { 62 decisionDFA.clear(); 63 } 64 65 public int getDecisionDFACount() { 66 return decisionDFA.size(); 67 } 68 69 public void discoverAllDecisions() throws Exception { 70 discover(0, editor.getTextEditor().getText().length()); 71 } 72 73 public void discoverDecisionsAtCurrentRule() throws Exception { 74 ElementRule r = editor.rules.getEnclosingRuleAtPosition(editor.getCaretPosition()); 75 if(r == null) { 76 throw new RuntimeException ("No rule at cursor position."); 77 } 78 discover(r.getStartIndex(), r.getEndIndex()); 79 } 80 81 private void discover(int start, int end) throws Exception { 82 Set<Integer > lineIndexes = new HashSet<Integer >(); 83 for(int index = start; index < end; index++) { 84 lineIndexes.add(editor.getTextEditor().getLineIndexAtTextPosition(index)); 85 } 86 87 engineGrammar = editor.getEngineGrammar(); 88 engineGrammar.analyze(); 89 90 decisionDFA.clear(); 91 usesSynPreds.clear(); 92 usesSemPreds.clear(); 93 94 discover(engineGrammar.getLexerGrammar(), lineIndexes, usesSemPreds, usesSynPreds); 95 discover(engineGrammar.getParserGrammar(), lineIndexes, usesSemPreds, usesSynPreds); 96 } 97 98 private void discover(Grammar g, Set<Integer > lineIndexes, Set<Integer > usesSemPreds, Set<Integer > usesSynPreds) { 99 if(g == null) return; 100 101 if(g.decisionsWhoseDFAsUsesSemPreds != null) { 102 for(DFA dfa : (Set<DFA>)g.decisionsWhoseDFAsUsesSemPreds) { 103 usesSemPreds.add(dfa.getDecisionNumber()); 104 } 105 } 106 107 if(g.decisionsWhoseDFAsUsesSynPreds != null) { 108 for(DFA dfa : g.decisionsWhoseDFAsUsesSynPreds) { 109 usesSynPreds.add(dfa.getDecisionNumber()); 110 } 111 } 112 113 for(Integer lineIndex : lineIndexes) { 115 addPositions(lineIndex, g.getLookaheadDFAColumnsForLineInFile(lineIndex)); 116 } 117 } 118 119 public void addPositions(Integer line, List <Integer > columnsForLineInFile) { 120 if(columnsForLineInFile.isEmpty()) return; 121 122 decisionDFA.put(line, columnsForLineInFile); 123 } 124 125 public boolean isDecisionPointAroundLocation(int line, int column) { 126 List s = decisionDFA.get(line+1); 127 return s != null && (s.contains(column-1) || s.contains(column)); 128 } 129 130 public List <DecisionDFAItem> getDecisionDFAItems() { 131 List <DecisionDFAItem> items = new ArrayList<DecisionDFAItem>(); 132 for(int lineIndex : decisionDFA.keySet()) { 133 for(int columnIndex : decisionDFA.get(lineIndex)) { 134 DFA dfa = getDFAAtPosition(lineIndex, columnIndex); 135 136 Grammar g = engineGrammar.getLexerGrammar(); 137 if(g != null) { 138 Rule r = g.getRule(Grammar.ARTIFICIAL_TOKENS_RULENAME); 139 NFAState s = (NFAState)r.startState.transition(0).target; 140 if(dfa.getDecisionNumber() == s.getDecisionNumber()) continue; 142 } 143 144 Color c = new Color(0, 128, 64); 145 String title = "DFA decision "+dfa.getDecisionNumber(); 146 String info = ""; 147 if(usesSemPreds.contains(dfa.getDecisionNumber())) { 148 info += "uses semantic predicate"; 149 c = new Color(255, 220, 0); 150 } else if(usesSynPreds.contains(dfa.getDecisionNumber())) { 151 info += "uses syntactic predicate"; 152 c = new Color(255, 220, 0); 153 } 154 if(dfa.isCyclic()) { 155 if(info.length() > 0) info += ", "; 156 info += "cyclic"; 157 } 158 if(info.length() > 0) info += ", "; 159 info += dfa.getNumberOfStates()+" states"; 160 161 Point p = editor.textEditor.getLineTextPositionsAtLineIndex(lineIndex-1); 162 DecisionDFAItem item = new DecisionDFAItem(editor); 163 item.setAttributes(null, p.x+columnIndex-1, p.x+columnIndex, lineIndex-1, c, title+" ("+info+")"); 164 item.shape = ATEUnderlyingManager.SHAPE_RECT; 165 items.add(item); 166 } 167 } 168 return items; 169 } 170 171 public DFA getDFAAtPosition(int line, int column) { 172 DFA dfa = null; 173 Grammar g = engineGrammar.getParserGrammar(); 174 if(g != null) { 175 dfa = g.getLookaheadDFAFromPositionInFile(line, column); 176 } 177 if(dfa == null) { 178 g = engineGrammar.getLexerGrammar(); 179 if(g != null) { 180 dfa = g.getLookaheadDFAFromPositionInFile(line, column); 181 } 182 } 183 184 return dfa; 185 } 186 187 public void refreshMenu() { 188 editor.getXJFrame().getMainMenuBar().refreshMenuState(editor.editorMenu.menuGrammar); 189 } 190 191 public void refresh() { 192 editor.textEditor.damage(); 193 editor.textEditor.repaint(); 194 } 195 196 } 197 | Popular Tags |