本章的最后将尝试运行由代码清单3.3的Lexer类实现的词法分析器。相应的main方法如代码清单3.5所示。它将对输入的字符串做词法分析,并逐行显示分析得到的每一个单词(图3.1)。 代码清单3.6中的CodeDialog对象是Lexer类的构造函数中的参数。CodeDialog是java.io.Reader的子类。Lexer在调用read方法从该对象中读取字符时,界面上将显示一个对话框,用户输入的文本将成为read方法的返回值。如果上一次显示对话框时输入的文本没有被删除,这些文本将首先被返回。用户点击对话框的取消按钮后,输入结束。 图3.1 执行LexerRunner 代码清单3.5 LexerRunner.java package chap3; import stone.*; public class LexerRunner { public static void main(String[] args) throws ParseException { Lexer l = new Lexer(new CodeDialog()); for (Token t; (t = l.read()) != Token.EOF; ) System.out.println("=> " + t.getText()); } } 代码清单3.6 CodeDialog.java package stone; import java.io.FileReader; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; import java.io.Reader; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTextArea; public class CodeDialog extends Reader { private String buffer = null; private int pos = 0; public int read(char[] cbuf, int off, int len) throws IOException { if (buffer == null) { String in = showDialog(); if (in == null) return -1; else { print(in); buffer = in + "n"; pos = 0; } } int size = 0; int length = buffer.length(); while (pos < length && size < len) cbuf[off + size++] = buffer.charAt(pos++); if (pos == length) buffer = null; return size; } protected void print(String s) { System.out.println(s); } public void close() throws IOException {} protected String showDialog() { JTextArea area = new JTextArea(20, 40); JScrollPane pane = new JScrollPane(area); int result = JOptionPane.showOptionDialog(null, pane, "Input", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null); if (result == JOptionPane.OK_OPTION) return area.getText(); else return null; } public static Reader file() throws FileNotFoundException { JFileChooser chooser = new JFileChooser(); if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) return new BufferedReader(new FileReader(chooser.getSelectedFile())); else throw new FileNotFoundException("no file specified"); } }