KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > antlr > works > grammar > decisiondfa > DecisionDFAEngine


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 JavaDoc;
15
16 /*
17
18 [The "BSD licence"]
19 Copyright (c) 2005 Jean Bovet
20 All rights reserved.
21
22 Redistribution and use in source and binary forms, with or without
23 modification, are permitted provided that the following conditions
24 are met:
25
26 1. Redistributions of source code must retain the above copyright
27 notice, this list of conditions and the following disclaimer.
28 2. Redistributions in binary form must reproduce the above copyright
29 notice, this list of conditions and the following disclaimer in the
30 documentation and/or other materials provided with the distribution.
31 3. The name of the author may not be used to endorse or promote products
32 derived from this software without specific prior written permission.
33
34 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
35 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
37 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
38 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
39 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
40 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
41 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44
45 */

46
47 public class DecisionDFAEngine {
48
49     private CEditorGrammar editor;
50     private EngineGrammar engineGrammar;
51
52     private Set<Integer JavaDoc> usesSemPreds = new HashSet<Integer JavaDoc>();
53     private Set<Integer JavaDoc> usesSynPreds = new HashSet<Integer JavaDoc>();
54
55     private Map<Integer JavaDoc,List JavaDoc<Integer JavaDoc>> decisionDFA = new HashMap<Integer JavaDoc, List JavaDoc<Integer JavaDoc>>();
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 JavaDoc {
70         discover(0, editor.getTextEditor().getText().length());
71     }
72
73     public void discoverDecisionsAtCurrentRule() throws Exception JavaDoc {
74         ElementRule r = editor.rules.getEnclosingRuleAtPosition(editor.getCaretPosition());
75         if(r == null) {
76             throw new RuntimeException JavaDoc("No rule at cursor position.");
77         }
78         discover(r.getStartIndex(), r.getEndIndex());
79     }
80
81     private void discover(int start, int end) throws Exception JavaDoc {
82         Set<Integer JavaDoc> lineIndexes = new HashSet<Integer JavaDoc>();
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 JavaDoc> lineIndexes, Set<Integer JavaDoc> usesSemPreds, Set<Integer JavaDoc> 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         // Get the position information about each DFA decision
114
for(Integer JavaDoc lineIndex : lineIndexes) {
115             addPositions(lineIndex, g.getLookaheadDFAColumnsForLineInFile(lineIndex));
116         }
117     }
118
119     public void addPositions(Integer JavaDoc line, List JavaDoc<Integer JavaDoc> columnsForLineInFile) {
120         if(columnsForLineInFile.isEmpty()) return;
121
122         decisionDFA.put(line, columnsForLineInFile);
123     }
124
125     public boolean isDecisionPointAroundLocation(int line, int column) {
126         List JavaDoc s = decisionDFA.get(line+1);
127         return s != null && (s.contains(column-1) || s.contains(column));
128     }
129
130     public List JavaDoc<DecisionDFAItem> getDecisionDFAItems() {
131         List JavaDoc<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                     // Ignore tokens DFA
141
if(dfa.getDecisionNumber() == s.getDecisionNumber()) continue;
142                 }
143
144                 Color c = new Color(0, 128, 64);
145                 String JavaDoc title = "DFA decision "+dfa.getDecisionNumber();
146                 String JavaDoc 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