KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > antlr > works > interpreter > EditorInterpreter


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

31
32 package org.antlr.works.interpreter;
33
34 import org.antlr.runtime.ANTLRStringStream;
35 import org.antlr.runtime.CharStream;
36 import org.antlr.runtime.CommonTokenStream;
37 import org.antlr.runtime.tree.ParseTree;
38 import org.antlr.tool.ErrorManager;
39 import org.antlr.tool.Grammar;
40 import org.antlr.tool.Interpreter;
41 import org.antlr.works.ate.syntax.misc.ATEToken;
42 import org.antlr.works.awtree.AWTreePanel;
43 import org.antlr.works.awtree.AWTreePanelDelegate;
44 import org.antlr.works.components.grammar.CEditorGrammar;
45 import org.antlr.works.editor.EditorMenu;
46 import org.antlr.works.editor.EditorTab;
47 import org.antlr.works.grammar.EngineGrammar;
48 import org.antlr.works.menu.ContextualMenuFactory;
49 import org.antlr.works.prefs.AWPrefs;
50 import org.antlr.works.stats.StatisticsAW;
51 import org.antlr.works.swing.Toolbar;
52 import org.antlr.works.syntax.element.ElementRule;
53 import org.antlr.works.utils.ErrorListener;
54 import org.antlr.works.utils.IconManager;
55 import org.antlr.works.utils.TextUtils;
56 import org.antlr.works.utils.Utils;
57 import org.antlr.xjlib.appkit.gview.GView;
58 import org.antlr.xjlib.appkit.utils.XJDialogProgress;
59
60 import javax.swing.*;
61 import javax.swing.tree.TreeNode JavaDoc;
62 import java.awt.*;
63 import java.awt.event.ActionEvent JavaDoc;
64 import java.awt.event.ActionListener JavaDoc;
65 import java.util.HashMap JavaDoc;
66 import java.util.List JavaDoc;
67 import java.util.Map JavaDoc;
68 import java.util.StringTokenizer JavaDoc;
69
70 public class EditorInterpreter extends EditorTab implements Runnable JavaDoc, AWTreePanelDelegate {
71
72     protected JPanel panel;
73     protected JSplitPane splitPane;
74     protected JTextPane textPane;
75     protected JScrollPane textScrollPane;
76     protected EditorInterpreterTreeModel treeModel;
77     protected AWTreePanel awTreePanel;
78     protected JComboBox rulesCombo;
79     protected JComboBox eolCombo;
80     protected JLabel tokensToIgnoreLabel;
81
82     protected XJDialogProgress progress;
83
84     protected String JavaDoc startSymbol = null;
85
86     protected CEditorGrammar editor;
87
88     public EditorInterpreter(CEditorGrammar editor) {
89         this.editor = editor;
90     }
91
92     public void awake() {
93         panel = new JPanel(new BorderLayout());
94
95         textPane = new JTextPane();
96         textPane.setBackground(Color.white);
97         textPane.setBorder(null);
98         textPane.setPreferredSize(new Dimension(300, 100));
99
100         textPane.setFont(new Font(AWPrefs.getEditorFont(), Font.PLAIN, AWPrefs.getEditorFontSize()));
101         TextUtils.createTabs(textPane);
102         TextUtils.setDefaultTextPaneProperties(textPane);
103
104         textScrollPane = new JScrollPane(textPane);
105         textScrollPane.setWheelScrollingEnabled(true);
106
107         treeModel = new EditorInterpreterTreeModel();
108         awTreePanel = new AWTreePanel(treeModel);
109         awTreePanel.setDelegate(this);
110
111         splitPane = new JSplitPane();
112         splitPane.setBorder(null);
113         splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
114         splitPane.setLeftComponent(textScrollPane);
115         splitPane.setRightComponent(awTreePanel);
116         splitPane.setContinuousLayout(true);
117         splitPane.setOneTouchExpandable(true);
118
119         panel.add(createControlPanel(), BorderLayout.NORTH);
120         panel.add(splitPane, BorderLayout.CENTER);
121
122         editor.getXJFrame().registerUndo(null, textPane);
123     }
124
125     public void componentShouldLayout() {
126         splitPane.setDividerLocation(0.2);
127     }
128
129     public Box createControlPanel() {
130         Toolbar box = Toolbar.createHorizontalToolbar();
131         box.addElement(createRunButton());
132         box.addElement(createRulesPopUp());
133         box.addGroupSeparator();
134         box.addElement(new JLabel("Line Endings:"));
135         box.addElement(createEOLCombo());
136         box.addGroupSeparator();
137         createTokensToIgnoreField(box);
138         return box;
139     }
140
141     public JButton createRunButton() {
142         JButton button = new JButton(IconManager.shared().getIconRun());
143         button.setToolTipText("Run");
144         button.addActionListener(new ActionListener JavaDoc() {
145             public void actionPerformed(ActionEvent JavaDoc event) {
146                 StatisticsAW.shared().recordEvent(StatisticsAW.EVENT_INTERPRETER_BUTTON);
147                 interpret();
148             }
149         });
150         return button;
151     }
152
153     public JComboBox createRulesPopUp() {
154         rulesCombo = new JComboBox();
155         rulesCombo.setFocusable(false);
156         rulesCombo.setMaximumSize(new Dimension(Short.MAX_VALUE, rulesCombo.getPreferredSize().height));
157         rulesCombo.addActionListener(new ActionListener JavaDoc() {
158             public void actionPerformed(ActionEvent JavaDoc event) {
159                 String JavaDoc rule = (String JavaDoc)rulesCombo.getSelectedItem();
160                 if(rule != null)
161                     startSymbol = rule;
162             }
163         });
164         return rulesCombo;
165     }
166
167     public JComboBox createEOLCombo() {
168         eolCombo = new JComboBox();
169         eolCombo.setFocusable(false);
170         eolCombo.setMaximumSize(new Dimension(Short.MAX_VALUE, eolCombo.getPreferredSize().height));
171         Utils.fillComboWithEOL(eolCombo);
172         return eolCombo;
173     }
174
175     public Box createTokensToIgnoreField(Toolbar box) {
176         box.addElement(new JLabel("Ignore rules:"));
177
178         tokensToIgnoreLabel = new JLabel();
179         tokensToIgnoreLabel.setFont(tokensToIgnoreLabel.getFont().deriveFont(Font.ITALIC));
180         box.addElement(tokensToIgnoreLabel);
181
182         JButton button = new JButton("Guess");
183         button.setFocusable(false);
184         button.setToolTipText("Find the name of all rules containing an action with channel=99");
185         button.addActionListener(new ActionListener JavaDoc() {
186             public void actionPerformed(ActionEvent JavaDoc event) {
187                 editor.findTokensToIgnore(true);
188             }
189         });
190         box.add(Box.createHorizontalGlue());
191         box.addElement(button);
192
193         return box;
194     }
195
196     public Container getContainer() {
197         return panel;
198     }
199
200     public void setRules(List JavaDoc<ElementRule> rules) {
201         updateRulesCombo(rules);
202         updateIgnoreTokens(rules);
203     }
204
205     public void updateRulesCombo(List JavaDoc<ElementRule> rules) {
206         Object JavaDoc selectedItem = rulesCombo.getSelectedItem();
207
208         rulesCombo.removeAllItems();
209         if(rules != null) {
210             for (ElementRule rule : rules) {
211                 rulesCombo.addItem(rule.toString());
212             }
213         }
214
215         if(selectedItem != null)
216             rulesCombo.setSelectedItem(selectedItem);
217     }
218
219     public void updateIgnoreTokens(List JavaDoc<ElementRule> rules) {
220         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
221         if(rules != null) {
222             for (ElementRule r : rules) {
223                 if (r.ignored) {
224                     if (sb.length() > 0)
225                         sb.append(" ");
226                     sb.append(r.name);
227                 }
228             }
229         }
230         if(sb.length() == 0)
231             tokensToIgnoreLabel.setText("-");
232         else
233             tokensToIgnoreLabel.setText(sb.toString());
234     }
235
236     public void interpret() {
237         editor.console.makeCurrent();
238
239         if(progress == null)
240             progress = new XJDialogProgress(editor.getXJFrame());
241
242         if(editor.getEngineGrammar().isDirty()) {
243             progress.setInfo("Preparing...");
244         } else {
245             progress.setInfo("Interpreting...");
246         }
247
248         // AW-42: guess always before running the interpreter
249
editor.findTokensToIgnore(false);
250
251         progress.setCancellable(false);
252         progress.setIndeterminate(true);
253         progress.display();
254
255         new Thread JavaDoc(this).start();
256     }
257
258     public void run() {
259         ErrorManager.setErrorListener(ErrorListener.shared());
260
261         try {
262             editor.getEngineGrammar().analyze();
263             process();
264         } catch(Exception JavaDoc e) {
265             editor.console.print(e);
266         } finally {
267             runEnded();
268         }
269     }
270
271     public void runEnded() {
272         SwingUtilities.invokeLater(new Runnable JavaDoc() {
273             public void run() {
274                 progress.close();
275             }
276         });
277     }
278
279     protected void process() {
280         progress.setInfo("Interpreting...");
281         editor.console.println("Interpreting...");
282
283         CharStream input = new ANTLRStringStream(Utils.convertRawTextWithEOL(textPane.getText(), eolCombo));
284
285         EngineGrammar eg = editor.getEngineGrammar();
286         Grammar parser;
287         Grammar lexer;
288         try {
289             eg.createGrammars();
290         } catch (Exception JavaDoc e) {
291             editor.console.print(e);
292             return;
293         }
294
295         parser = eg.getParserGrammar();
296         lexer = eg.getLexerGrammar();
297
298         Interpreter lexEngine = new Interpreter(lexer, input);
299         CommonTokenStream tokens = new CommonTokenStream(lexEngine);
300
301         StringTokenizer JavaDoc tk = new StringTokenizer JavaDoc(tokensToIgnoreLabel.getText(), " ");
302         while ( tk.hasMoreTokens() ) {
303             String JavaDoc tokenName = tk.nextToken();
304             tokens.setTokenTypeChannel(lexer.getTokenType(tokenName), 99);
305         }
306
307         Interpreter parseEngine = new Interpreter(parser, tokens);
308
309         ParseTree t = null;
310         try {
311             if(ATEToken.isLexerName(startSymbol)) {
312                 t = lexEngine.parse(startSymbol);
313             } else {
314                 t = parseEngine.parse(startSymbol);
315             }
316         } catch (Exception JavaDoc e) {
317             editor.console.print(e);
318         }
319
320         if(parser != null && t != null) {
321             SwingUtilities.invokeLater(new Refresh(parser, t));
322         }
323     }
324
325     public class Refresh implements Runnable JavaDoc {
326         Grammar g;
327         ParseTree t;
328
329         public Refresh(Grammar grammar, ParseTree t) {
330             this.g = grammar;
331             this.t = t;
332         }
333
334         public void run() {
335             treeModel.setGrammar(g);
336             treeModel.setTree(t);
337
338             awTreePanel.setRoot((TreeNode JavaDoc)treeModel.getRoot());
339             awTreePanel.refresh();
340         }
341     }
342
343     public boolean canExportToBitmap() {
344         return true;
345     }
346
347     public boolean canExportToEPS() {
348         return true;
349     }
350
351     public GView getExportableGView() {
352         return awTreePanel.getGraphView();
353     }
354
355     public String JavaDoc getTabName() {
356         return "Interpreter";
357     }
358
359     public Component getTabComponent() {
360         return getContainer();
361     }
362
363     public void awTreeDidSelectTreeNode(TreeNode JavaDoc node, boolean shiftKey) {
364         // not implemented
365
}
366
367     public JPopupMenu awTreeGetContextualMenu() {
368         ContextualMenuFactory factory = new ContextualMenuFactory(editor.editorMenu);
369         factory.addItem(EditorMenu.MI_EXPORT_AS_EPS);
370         factory.addItem(EditorMenu.MI_EXPORT_AS_IMAGE);
371         return factory.menu;
372     }
373
374     public static final String JavaDoc KEY_SPLITPANE_A = "KEY_SPLITPANE_A";
375
376     public void setPersistentData(Map JavaDoc data) {
377         if(data == null)
378             return;
379
380         Integer JavaDoc i = (Integer JavaDoc)data.get(KEY_SPLITPANE_A);
381         if(i != null)
382             splitPane.setDividerLocation(i.intValue());
383     }
384
385     public Map JavaDoc<String JavaDoc,Integer JavaDoc> getPersistentData() {
386         Map JavaDoc<String JavaDoc,Integer JavaDoc> data = new HashMap JavaDoc<String JavaDoc, Integer JavaDoc>();
387         data.put(KEY_SPLITPANE_A, splitPane.getDividerLocation());
388         return data;
389     }
390
391 }
392
Popular Tags