1 package org.codehaus.groovy.antlr;
2 import java.awt.*;
3 import java.awt.event.*;
4 import java.io.*;
5 import java.lang.reflect.*;
6 import java.util.Hashtable;
7
8 import javax.swing.*;
9 import javax.swing.border.Border;
10 import javax.swing.text.BadLocationException;
11 import org.codehaus.groovy.antlr.parser.*;
12
13 import antlr.*;
14
15 /***
16 * @author Santhosh Kumar T
17 * @version 1.0
18 */
19
20 public class LexerFrame extends JFrame implements ActionListener{
21 JSplitPane jSplitPane1 = new JSplitPane();
22 JScrollPane jScrollPane1 = new JScrollPane();
23 JScrollPane jScrollPane2 = new JScrollPane();
24 JTextPane tokenPane = new HScrollableTextPane();
25 JButton jbutton = new JButton("open");
26 JPanel mainPanel = new JPanel(new BorderLayout());
27 JTextArea scriptPane = new JTextArea();
28 Border border1;
29 Border border2;
30
31 Class lexerClass;
32
33 public LexerFrame(Class lexerClass, Class tokenTypesClass){
34 super("Token Steam Viewer");
35 this.lexerClass = lexerClass;
36 try{
37 jbInit();
38 setSize(500, 500);
39 listTokens(tokenTypesClass);
40
41 final JPopupMenu popup = new JPopupMenu();
42 popup.add(loadFileAction);
43
44 jbutton.setSize(30,30);
45 jbutton.addMouseListener(new MouseAdapter(){
46 public void mouseReleased(MouseEvent e) {
47
48 popup.show(scriptPane, e.getX(), e.getY());
49 }
50 });
51 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
52 } catch(Exception e){
53 e.printStackTrace();
54 }
55 }
56
57 Hashtable tokens = new Hashtable();
58
59 private void listTokens(Class tokenTypes) throws Exception{
60 Field field[] = tokenTypes.getDeclaredFields();
61 for(int i = 0; i<field.length; i++)
62 tokens.put(field[i].get(null), field[i].getName());
63 }
64
65 public void actionPerformed(ActionEvent ae){
66 Token token = (Token) ((JComponent) ae.getSource()).getClientProperty("token");
67 if(token.getType()==Token.EOF_TYPE){
68 scriptPane.select(0, 0);
69 return;
70 }
71 try{
72 int start = scriptPane.getLineStartOffset(token.getLine()-1)+token.getColumn()-1;
73 scriptPane.select(start, start+token.getText().length());
74 scriptPane.requestFocus();
75 } catch(BadLocationException ex){
76 }
77 }
78
79 private Action loadFileAction = new AbstractAction("Open File..."){
80 public void actionPerformed(ActionEvent ae){
81 JFileChooser jfc = new JFileChooser();
82 int response = jfc.showOpenDialog(LexerFrame.this);
83 if(response!=JFileChooser.APPROVE_OPTION)
84 return;
85 try{
86 scanScript(jfc.getSelectedFile());
87 } catch(Exception ex){
88 ex.printStackTrace();
89 }
90 }
91 };
92
93 private void scanScript(File file) throws Exception{
94 scriptPane.read(new FileReader(file), null);
95
96
97 Constructor constructor = lexerClass.getConstructor(new Class[]{InputStream.class});
98 CharScanner lexer = (CharScanner) constructor.newInstance(new Object[]{new FileInputStream(file)});
99
100 tokenPane.setEditable(true);
101 tokenPane.setText("");
102
103 int line = 1;
104 ButtonGroup bg = new ButtonGroup();
105 Token token = null;
106
107 while(true){
108 token = lexer.nextToken();
109 JToggleButton tokenButton = new JToggleButton((String) tokens.get(new Integer(token.getType())));
110 bg.add(tokenButton);
111 tokenButton.addActionListener(this);
112 tokenButton.setToolTipText(token.getText());
113 tokenButton.putClientProperty("token", token);
114 tokenButton.setMargin(new Insets(0, 1, 0, 1));
115 tokenButton.setFocusPainted(false);
116 if(token.getLine()>line){
117 tokenPane.getDocument().insertString(tokenPane.getDocument().getLength(), "\n", null);
118 line = token.getLine();
119 }
120 insertComponent(tokenButton);
121 if(token.getType()==Token.EOF_TYPE)
122 break;
123 }
124
125 tokenPane.setEditable(false);
126 tokenPane.setCaretPosition(0);
127 }
128
129 private void insertComponent(JComponent comp){
130 try{
131 tokenPane.getDocument().insertString(tokenPane.getDocument().getLength(), " ", null);
132 } catch(BadLocationException ex1){
133 }
134 try{
135 tokenPane.setCaretPosition(tokenPane.getDocument().getLength()-1);
136 } catch(Exception ex){
137 tokenPane.setCaretPosition(0);
138 }
139 tokenPane.insertComponent(comp);
140 }
141
142 private void jbInit() throws Exception{
143 border1 = BorderFactory.createEmptyBorder();
144 border2 = BorderFactory.createEmptyBorder();
145 jSplitPane1.setOrientation(JSplitPane.VERTICAL_SPLIT);
146 tokenPane.setEditable(false);
147 tokenPane.setText("");
148 scriptPane.setFont(new java.awt.Font("DialogInput", 0, 12));
149 scriptPane.setEditable(false);
150 scriptPane.setMargin(new Insets(5, 5, 5, 5));
151 scriptPane.setText("");
152 jScrollPane1.setBorder(border1);
153 jScrollPane2.setBorder(border1);
154 jSplitPane1.setMinimumSize(new Dimension(800,600));
155 mainPanel.add(jSplitPane1, BorderLayout.CENTER);
156 mainPanel.add(jbutton,BorderLayout.NORTH);
157 this.getContentPane().add(mainPanel);
158 jSplitPane1.add(jScrollPane1, JSplitPane.LEFT);
159 jScrollPane1.getViewport().add(tokenPane, null);
160 jSplitPane1.add(jScrollPane2, JSplitPane.RIGHT);
161 jScrollPane2.getViewport().add(scriptPane, null);
162
163 jScrollPane1.setColumnHeaderView(new JLabel(" Token Stream:"));
164 jScrollPane2.setColumnHeaderView(new JLabel(" Input Script:"));
165 jSplitPane1.setResizeWeight(0.5);
166 }
167
168 public static void main(String[] args) throws Exception{
169 try{
170 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
171 } catch(Exception ignore){
172 }
173 new LexerFrame(GroovyLexer.class, GroovyTokenTypes.class).setVisible(true);
174 }
175 }
176
177
178 class HScrollableTextPane extends JTextPane{
179 public boolean getScrollableTracksViewportWidth(){
180 return(getSize().width<getParent().getSize().width);
181 }
182
183 public void setSize(Dimension d){
184 if(d.width<getParent().getSize().width){
185 d.width = getParent().getSize().width;
186 }
187 super.setSize(d);
188 }
189 }