001 /* 002 * * mesopotamia @mesopotamia.version@ 003 * Multilingual parser and repository. 004 * Copyright (C) 2005 Hammurapi Group 005 * 006 * This program is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 2 of the License, or (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with this library; if not, write to the Free Software 018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 019 * 020 * URL: http://http://www.hammurapi.biz 021 * e-Mail: support@hammurapi.biz 022 */ 023 package org.mesopotamia.util; 024 025 import gnu.trove.TIntHashSet; 026 027 import java.io.Reader; 028 import java.io.StringReader; 029 import java.lang.reflect.Constructor; 030 import java.lang.reflect.Method; 031 import java.util.ArrayList; 032 import java.util.Collections; 033 import java.util.Date; 034 import java.util.Iterator; 035 import java.util.List; 036 import java.util.StringTokenizer; 037 038 import javax.swing.JFrame; 039 040 import antlr.ASTFactory; 041 import antlr.Parser; 042 import antlr.Token; 043 import antlr.TokenStream; 044 import antlr.TokenStreamException; 045 import antlr.collections.AST; 046 import biz.hammurapi.antlr.ASTFrame.JTreeASTModel; 047 048 049 /** 050 * @author Pavel Vlasov 051 * 052 */ 053 public class AstDebugger extends JFrame { 054 055 private javax.swing.JPanel jContentPane = null; 056 057 private javax.swing.JLabel jLabel = null; 058 059 private javax.swing.JTextField lexerField = null; 060 061 private javax.swing.JTree jTree = null; 062 063 private javax.swing.JLabel jLabel1 = null; 064 065 private javax.swing.JTextField parserField = null; 066 067 private javax.swing.JLabel jLabel2 = null; 068 069 private javax.swing.JTextPane jTextPane = null; 070 071 private javax.swing.JLabel statusLabel = null; // @jve:visual-info 072 // decl-index=0 073 // visual-constraint="415,698" 074 075 private javax.swing.JComboBox methodComboBox = null; 076 077 private javax.swing.JSplitPane jSplitPane = null; 078 079 private javax.swing.JPanel jPanel1 = null; 080 081 private javax.swing.JScrollPane jScrollPane = null; 082 083 private javax.swing.JLabel jLabel3 = null; 084 085 private javax.swing.JTextField wsTokensField = null; 086 087 /** 088 * This is the default constructor 089 */ 090 public AstDebugger() { 091 super(); 092 initialize(); 093 } 094 095 /** 096 * This method initializes this 097 * 098 * @return void 099 */ 100 private void initialize() { 101 this.setContentPane(getJContentPane()); 102 this.setSize(841, 709); 103 this.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE); 104 this.setTitle("AST Debugger"); 105 } 106 107 /** 108 * This method initializes jContentPane 109 * 110 * @return javax.swing.JPanel 111 */ 112 private javax.swing.JPanel getJContentPane() { 113 if (jContentPane == null) { 114 jContentPane = new javax.swing.JPanel(); 115 java.awt.GridBagConstraints consGridBagConstraints12 = new java.awt.GridBagConstraints(); 116 java.awt.GridBagConstraints consGridBagConstraints31 = new java.awt.GridBagConstraints(); 117 consGridBagConstraints12.gridx = 0; 118 consGridBagConstraints12.gridy = 4; 119 consGridBagConstraints12.gridwidth = 5; 120 consGridBagConstraints31.fill = java.awt.GridBagConstraints.BOTH; 121 consGridBagConstraints31.weighty = 1.0; 122 consGridBagConstraints31.weightx = 1.0; 123 consGridBagConstraints31.gridy = 3; 124 consGridBagConstraints31.gridx = 2; 125 consGridBagConstraints31.gridwidth = 3; 126 jContentPane.setLayout(new java.awt.GridBagLayout()); 127 jContentPane.add(getJSplitPane(), consGridBagConstraints31); 128 jContentPane.add(getStatusLabel(), consGridBagConstraints12); 129 } 130 return jContentPane; 131 } 132 133 /** 134 * This method initializes jLabel 135 * 136 * @return javax.swing.JLabel 137 */ 138 private javax.swing.JLabel getJLabel() { 139 if (jLabel == null) { 140 jLabel = new javax.swing.JLabel(); 141 jLabel.setText("Lexer "); 142 } 143 return jLabel; 144 } 145 146 /** 147 * This method initializes wsTokensField 148 * 149 * @return javax.swing.JTextField 150 */ 151 private javax.swing.JTextField getLexerField() { 152 if (lexerField == null) { 153 lexerField = new javax.swing.JTextField(); 154 lexerField.addKeyListener(new java.awt.event.KeyAdapter() { 155 public void keyTyped(java.awt.event.KeyEvent e) { 156 lastUpdate = System.currentTimeMillis(); 157 } 158 }); 159 } 160 return lexerField; 161 } 162 163 /** 164 * This method initializes jTree 165 * 166 * @return javax.swing.JTree 167 */ 168 private javax.swing.JTree getJTree() { 169 if (jTree == null) { 170 jTree = new javax.swing.JTree(); 171 } 172 return jTree; 173 } 174 175 /** 176 * This method initializes jLabel1 177 * 178 * @return javax.swing.JLabel 179 */ 180 private javax.swing.JLabel getJLabel1() { 181 if (jLabel1 == null) { 182 jLabel1 = new javax.swing.JLabel(); 183 jLabel1.setText("WS tokens"); 184 } 185 return jLabel1; 186 } 187 188 /** 189 * This method initializes jTextField1 190 * 191 * @return javax.swing.JTextField 192 */ 193 private javax.swing.JTextField getParserField() { 194 if (parserField == null) { 195 parserField = new javax.swing.JTextField(); 196 parserField.addKeyListener(new java.awt.event.KeyAdapter() { 197 public void keyTyped(java.awt.event.KeyEvent e) { 198 lastUpdate = System.currentTimeMillis(); 199 parserClassUpdated = true; 200 } 201 }); 202 } 203 return parserField; 204 } 205 206 /** 207 * This method initializes jLabel2 208 * 209 * @return javax.swing.JLabel 210 */ 211 private javax.swing.JLabel getJLabel2() { 212 if (jLabel2 == null) { 213 jLabel2 = new javax.swing.JLabel(); 214 jLabel2.setText("Method "); 215 } 216 return jLabel2; 217 } 218 219 /** 220 * This method initializes jTextPane 221 * 222 * @return javax.swing.JTextPane 223 */ 224 private javax.swing.JTextPane getJTextPane() { 225 if (jTextPane == null) { 226 jTextPane = new javax.swing.JTextPane(); 227 jTextPane.addKeyListener(new java.awt.event.KeyAdapter() { 228 public void keyTyped(java.awt.event.KeyEvent e) { 229 lastUpdate = System.currentTimeMillis(); 230 } 231 }); 232 } 233 return jTextPane; 234 } 235 236 /** 237 * This method initializes jLabel3 238 * 239 * @return javax.swing.JLabel 240 */ 241 private javax.swing.JLabel getStatusLabel() { 242 if (statusLabel == null) { 243 statusLabel = new javax.swing.JLabel(); 244 statusLabel.setText(" "); 245 } 246 return statusLabel; 247 } 248 249 /** 250 * This method initializes jComboBox 251 * 252 * @return javax.swing.JComboBox 253 */ 254 private javax.swing.JComboBox getMethodComboBox() { 255 if (methodComboBox == null) { 256 methodComboBox = new javax.swing.JComboBox(); 257 methodComboBox.addActionListener(new java.awt.event.ActionListener() { 258 public void actionPerformed(java.awt.event.ActionEvent e) { 259 lastUpdate = System.currentTimeMillis(); 260 } 261 }); 262 } 263 return methodComboBox; 264 } 265 266 /** 267 * This method initializes jSplitPane 268 * 269 * @return javax.swing.JSplitPane 270 */ 271 private javax.swing.JSplitPane getJSplitPane() { 272 if (jSplitPane == null) { 273 jSplitPane = new javax.swing.JSplitPane(); 274 jSplitPane.setLeftComponent(getJPanel1()); 275 jSplitPane.setRightComponent(getJPanel()); 276 jSplitPane.setDividerLocation(400); 277 } 278 return jSplitPane; 279 } 280 281 private static class MethodEntry implements Comparable { 282 Method method; 283 284 /** 285 * @param method 286 */ 287 public MethodEntry(Method method) { 288 super(); 289 // TODO Auto-generated constructor stub 290 this.method = method; 291 } 292 293 public String toString() { 294 return method.getName(); 295 } 296 297 public int compareTo(Object o) { 298 return toString().compareTo(((MethodEntry) o).toString()); 299 } 300 301 } 302 303 /** 304 * This method initializes jPanel1 305 * 306 * @return javax.swing.JPanel 307 */ 308 private javax.swing.JPanel getJPanel1() { 309 if (jPanel1 == null) { 310 jPanel1 = new javax.swing.JPanel(); 311 java.awt.GridBagConstraints consGridBagConstraints51 = new java.awt.GridBagConstraints(); 312 java.awt.GridBagConstraints consGridBagConstraints61 = new java.awt.GridBagConstraints(); 313 java.awt.GridBagConstraints consGridBagConstraints8 = new java.awt.GridBagConstraints(); 314 java.awt.GridBagConstraints consGridBagConstraints9 = new java.awt.GridBagConstraints(); 315 java.awt.GridBagConstraints consGridBagConstraints10 = new java.awt.GridBagConstraints(); 316 java.awt.GridBagConstraints consGridBagConstraints11 = new java.awt.GridBagConstraints(); 317 java.awt.GridBagConstraints consGridBagConstraints13 = new java.awt.GridBagConstraints(); 318 java.awt.GridBagConstraints consGridBagConstraints14 = new java.awt.GridBagConstraints(); 319 java.awt.GridBagConstraints consGridBagConstraints71 = new java.awt.GridBagConstraints(); 320 consGridBagConstraints13.gridy = 2; 321 consGridBagConstraints13.gridx = 0; 322 consGridBagConstraints14.fill = java.awt.GridBagConstraints.HORIZONTAL; 323 consGridBagConstraints14.weightx = 1.0; 324 consGridBagConstraints14.gridy = 3; 325 consGridBagConstraints14.gridx = 2; 326 consGridBagConstraints51.gridy = 0; 327 consGridBagConstraints51.gridx = 0; 328 consGridBagConstraints9.gridy = 4; 329 consGridBagConstraints9.gridx = 0; 330 consGridBagConstraints8.gridy = 3; 331 consGridBagConstraints8.gridx = 0; 332 consGridBagConstraints61.fill = java.awt.GridBagConstraints.HORIZONTAL; 333 consGridBagConstraints61.weightx = 1.0; 334 consGridBagConstraints61.gridy = 0; 335 consGridBagConstraints61.gridx = 2; 336 consGridBagConstraints10.fill = java.awt.GridBagConstraints.HORIZONTAL; 337 consGridBagConstraints10.anchor = java.awt.GridBagConstraints.WEST; 338 consGridBagConstraints10.weightx = 1.0; 339 consGridBagConstraints10.gridy = 4; 340 consGridBagConstraints10.gridx = 2; 341 consGridBagConstraints11.fill = java.awt.GridBagConstraints.BOTH; 342 consGridBagConstraints11.weighty = 1.0; 343 consGridBagConstraints11.weightx = 1.0; 344 consGridBagConstraints11.gridy = 5; 345 consGridBagConstraints11.gridx = 0; 346 consGridBagConstraints11.gridwidth = 3; 347 consGridBagConstraints61.gridwidth = 2; 348 consGridBagConstraints71.fill = java.awt.GridBagConstraints.HORIZONTAL; 349 consGridBagConstraints71.weightx = 1.0; 350 consGridBagConstraints71.gridy = 2; 351 consGridBagConstraints71.gridx = 2; 352 consGridBagConstraints71.gridwidth = 2; 353 jPanel1.setLayout(new java.awt.GridBagLayout()); 354 jPanel1.add(getJLabel(), consGridBagConstraints51); 355 jPanel1.add(getLexerField(), consGridBagConstraints61); 356 jPanel1.add(getParserField(), consGridBagConstraints71); 357 jPanel1.add(getJLabel1(), consGridBagConstraints8); 358 jPanel1.add(getJLabel2(), consGridBagConstraints9); 359 jPanel1.add(getMethodComboBox(), consGridBagConstraints10); 360 jPanel1.add(getJScrollPane(), consGridBagConstraints11); 361 jPanel1.add(getJLabel3(), consGridBagConstraints13); 362 jPanel1.add(getWsTokensField(), consGridBagConstraints14); 363 } 364 return jPanel1; 365 } 366 367 /** 368 * This method initializes jScrollPane 369 * 370 * @return javax.swing.JScrollPane 371 */ 372 private javax.swing.JScrollPane getJScrollPane() { 373 if (jScrollPane == null) { 374 jScrollPane = new javax.swing.JScrollPane(); 375 jScrollPane.setViewportView(getJTextPane()); 376 } 377 return jScrollPane; 378 } 379 380 /** 381 * This method initializes jLabel3 382 * 383 * @return javax.swing.JLabel 384 */ 385 private javax.swing.JLabel getJLabel3() { 386 if (jLabel3 == null) { 387 jLabel3 = new javax.swing.JLabel(); 388 jLabel3.setText("Parser"); 389 } 390 return jLabel3; 391 } 392 393 /** 394 * This method initializes wsTokensField 395 * 396 * @return javax.swing.JTextField 397 */ 398 private javax.swing.JTextField getWsTokensField() { 399 if (wsTokensField == null) { 400 wsTokensField = new javax.swing.JTextField(); 401 wsTokensField.addKeyListener(new java.awt.event.KeyAdapter() { 402 public void keyTyped(java.awt.event.KeyEvent e) { 403 lastUpdate = System.currentTimeMillis(); 404 } 405 }); 406 } 407 return wsTokensField; 408 } 409 410 private long lastUpdate; 411 412 private boolean parserClassUpdated; 413 414 private javax.swing.JPanel jPanel = null; 415 private javax.swing.JButton jButton = null; 416 private javax.swing.JButton jButton1 = null; 417 private javax.swing.JButton jButton2 = null; 418 { 419 Thread performer = new Thread() { 420 public void run() { 421 while (true) { 422 try { 423 sleep(100); 424 } catch (InterruptedException e1) { 425 return; 426 } 427 428 if (lastUpdate != 0 && System.currentTimeMillis() - lastUpdate > 2000) { 429 lastUpdate = 0; 430 process(); 431 } 432 } 433 } 434 435 /** 436 * 437 */ 438 private void process() { 439 getJTree().setModel(null); 440 status(" "); 441 try { 442 String lexerClassName = getLexerField().getText(); 443 if (lexerClassName == null || lexerClassName.trim().length() == 0) { 444 status("Enter lexer class name"); 445 return; 446 } 447 448 Class lexerClass = Class.forName(lexerClassName); 449 if (!TokenStream.class.isAssignableFrom(lexerClass)) { 450 status(lexerClass.getName() + " does not implement " + TokenStream.class); 451 return; 452 } 453 454 Constructor lc = lexerClass.getConstructor(new Class[] { Reader.class }); 455 456 String parserClassName = getParserField().getText(); 457 if (parserClassName == null || parserClassName.trim().length() == 0) { 458 status("Enter parser class name"); 459 return; 460 } 461 462 Class parserClass = Class.forName(parserClassName); 463 if (!Parser.class.isAssignableFrom(parserClass)) { 464 status(parserClass.getName() + " does is not a subclass of " + Parser.class); 465 return; 466 } 467 468 if (parserClassUpdated) { 469 parserClassUpdated = false; 470 methodComboBox.removeAllItems(); 471 List<MethodEntry> methods = new ArrayList<MethodEntry>(); 472 Method[] parserMethods = parserClass.getMethods(); 473 for (int i = 0; i < parserMethods.length; i++) { 474 if (parserMethods[i].getParameterTypes().length == 0) { 475 methods.add(new MethodEntry(parserMethods[i])); 476 } 477 } 478 479 Collections.sort(methods); 480 Iterator<MethodEntry> mit = methods.iterator(); 481 while (mit.hasNext()) { 482 methodComboBox.addItem(mit.next()); 483 } 484 } 485 486 if (methodComboBox.getSelectedItem() == null) { 487 status("Select parse method"); 488 return; 489 } 490 491 final TIntHashSet wsTokens = new TIntHashSet(); 492 String[] tokenNames = (String[]) parserClass.getField("_tokenNames").get(null); 493 String wsTokensString = getWsTokensField().getText(); 494 if (wsTokensString.trim().length() > 0) { 495 StringTokenizer st = new StringTokenizer(wsTokensString, ", "); 496 W: while (st.hasMoreTokens()) { 497 String wsToken = st.nextToken().trim(); 498 for (int i = 0; i < tokenNames.length; i++) { 499 if (wsToken.equals(tokenNames[i])) { 500 wsTokens.add(i); 501 continue W; 502 } 503 } 504 status("Invalid token name: " + wsToken); 505 return; 506 } 507 } 508 509 String text = getJTextPane().getText(); 510 if (text.length() == 0) { 511 status("Type text to parse"); 512 return; 513 } 514 515 final Object lexer = lc.newInstance(new Object[] { new StringReader(text) }); 516 Constructor pc = parserClass.getConstructor(new Class[] { TokenStream.class }); 517 Object parser = pc.newInstance(new Object[] { new TokenStream() { 518 519 public Token nextToken() throws TokenStreamException { 520 Token ret = ((TokenStream) lexer).nextToken(); 521 return wsTokens.contains(ret.getType()) ? nextToken() : ret; 522 } 523 524 } }); 525 526 Method selectedMethod = ((MethodEntry) methodComboBox.getSelectedItem()).method; 527 selectedMethod.invoke(parser); 528 AST ast = ((Parser) parser).getAST(); 529 530 ASTFactory astFactory = new ASTFactory(); 531 532 AST r = astFactory.create(0, selectedMethod.getName()); 533 r.setFirstChild(ast); 534 535 JTreeASTModel model = new JTreeASTModel(r, tokenNames); 536 getJTree().setModel(model); 537 status(new Date().toString()); 538 } catch (Exception e) { 539 Throwable cause=e; 540 while (cause.getCause()!=null && cause.getCause()!=cause) { 541 cause=cause.getCause(); 542 } 543 status(cause.toString()); 544 cause.printStackTrace(); 545 } 546 } 547 }; 548 549 performer.setName("Parsing thread"); 550 performer.setDaemon(true); 551 performer.start(); 552 } 553 554 private void status(String status) { 555 getStatusLabel().setText(status); 556 } 557 558 public static void main(String[] args) { 559 AstDebugger astDebugger = new AstDebugger(); 560 astDebugger.getJTree().setModel(null); 561 astDebugger.setVisible(true); 562 } 563 /** 564 * This method initializes jPanel 565 * 566 * @return javax.swing.JPanel 567 */ 568 private javax.swing.JPanel getJPanel() { 569 if(jPanel == null) { 570 jPanel = new javax.swing.JPanel(); 571 java.awt.GridBagConstraints consGridBagConstraints3 = new java.awt.GridBagConstraints(); 572 java.awt.GridBagConstraints consGridBagConstraints4 = new java.awt.GridBagConstraints(); 573 java.awt.GridBagConstraints consGridBagConstraints5 = new java.awt.GridBagConstraints(); 574 java.awt.GridBagConstraints consGridBagConstraints6 = new java.awt.GridBagConstraints(); 575 consGridBagConstraints5.gridy = 1; 576 consGridBagConstraints5.gridx = 2; 577 consGridBagConstraints6.fill = java.awt.GridBagConstraints.BOTH; 578 consGridBagConstraints6.weighty = 1.0; 579 consGridBagConstraints6.weightx = 1.0; 580 consGridBagConstraints6.gridy = 0; 581 consGridBagConstraints6.gridx = 0; 582 consGridBagConstraints6.gridwidth = 3; 583 consGridBagConstraints3.gridy = 1; 584 consGridBagConstraints3.gridx = 0; 585 consGridBagConstraints4.gridy = 1; 586 consGridBagConstraints4.gridx = 1; 587 jPanel.setLayout(new java.awt.GridBagLayout()); 588 jPanel.add(getJButton(), consGridBagConstraints3); 589 jPanel.add(getJButton1(), consGridBagConstraints4); 590 jPanel.add(getJButton2(), consGridBagConstraints5); 591 jPanel.add(getJTree(), consGridBagConstraints6); 592 } 593 return jPanel; 594 } 595 /** 596 * This method initializes jButton 597 * 598 * @return javax.swing.JButton 599 */ 600 private javax.swing.JButton getJButton() { 601 if(jButton == null) { 602 jButton = new javax.swing.JButton(); 603 jButton.setText("Expand all"); 604 jButton.addActionListener(new java.awt.event.ActionListener() { 605 public void actionPerformed(java.awt.event.ActionEvent e) { 606 System.out.println("actionPerformed()"); // TODO Auto-generated Event stub actionPerformed() 607 } 608 }); 609 } 610 return jButton; 611 } 612 /** 613 * This method initializes jButton1 614 * 615 * @return javax.swing.JButton 616 */ 617 private javax.swing.JButton getJButton1() { 618 if(jButton1 == null) { 619 jButton1 = new javax.swing.JButton(); 620 jButton1.setText("Collapse All"); 621 jButton1.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); 622 jButton1.addActionListener(new java.awt.event.ActionListener() { 623 public void actionPerformed(java.awt.event.ActionEvent e) { 624 System.out.println("actionPerformed()"); // TODO Auto-generated Event stub actionPerformed() 625 } 626 }); 627 } 628 return jButton1; 629 } 630 /** 631 * This method initializes jButton2 632 * 633 * @return javax.swing.JButton 634 */ 635 private javax.swing.JButton getJButton2() { 636 if(jButton2 == null) { 637 jButton2 = new javax.swing.JButton(); 638 jButton2.setText("Print"); 639 jButton2.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); 640 jButton2.addActionListener(new java.awt.event.ActionListener() { 641 public void actionPerformed(java.awt.event.ActionEvent e) { 642 new ComponentPrinter(getJTree()).print(); 643 } 644 }); 645 } 646 return jButton2; 647 } 648 } // @jve:visual-info decl-index=0 visual-constraint="10,10" @jve:visual-info decl-index=0 visual-constraint="4,5"