Java空指针异常:Lexer的标记输入

时间:2015-10-02 10:46:09

标签: java tokenize

我在CMD提示符下运行.jar文件时出现以下错误:

C:\Users\Mikael\My Documents\NetBeansProjects\cs413CompilerProject\dist>
java -jar "cs413CompilerProject.jar" "C:\Users\Mikael\Documents\NetBeansProjects\cs413
CompilerProject\cs413Compiler\simple.x"
User's current working directory: 
C:\Users\Mikael\My Documents\NetBeansProjects\cs413CompilerProject\dist
java.io.FileNotFoundException: lexer\setup\tokens 
(The system cannot find the path specified)
Exception in thread "main" java.lang.NullPointerException
        at lexer.setup.TokenSetup.initTokenClasses(TokenSetup.java:77)
        at lexer.setup.TokenSetup.main(TokenSetup.java:35)

并且它引用的代码是(从TokenSetup.java的第24行开始到第35行结束):

24  public class TokenSetup {
25  private String type, value; // token type/value for new token
26  private int tokenCount = 0;
27  private BufferedReader in;
28  private PrintWriter table, symbols; // files used for new classes
29  
30  /**
31   *
32   * @param args
33   */
34  public static void main(String args[]) {
35      new TokenSetup().initTokenClasses();}

然后在TokenSetup.initTokenClasses下的另一个引用:

77  public void initTokenClasses() {
78      table.println("/*********************");
79      table.println("*");
80      table.println("* @Author Mikael M");
81  //... print a bunch of things
}

完整代码:

package lexer.setup;

import java.util.*;
import java.io.*;
//
///**
// *  TokenSetup class is used to read the tokens from file <i>tokens</i>
// *  and automatically build the 2 classes/files <i>TokenType.java</i> 
// *  and <i>Sym.java</i><br>
// *  Therefore, if there is any change to the tokens then we only need to
// *  modify the file <i>tokens</i> and run this program again before using the
// *  compiler
//*/
public class TokenSetup {
    private String type, value; // token type/value for new token
    private int tokenCount = 0;
    private BufferedReader in;
    private PrintWriter table, symbols; // files used for new classes

    /**
     *
     * @param args
     */
    public static void main(String args[]) {
        new TokenSetup().initTokenClasses();
    }

    TokenSetup() {
        try {
            System.out.println("User's current working directory: " + System.getProperty("user.dir"));          
            String sep = System.getProperty("file.separator");
            in = new BufferedReader( new FileReader("lexer" + sep + "setup" + sep + "tokens"));
            table = new PrintWriter(new FileOutputStream("lexer" + sep + "TokenType.java"));
            symbols = new PrintWriter(new FileOutputStream("lexer" + sep + "Tokens.java"));
        } catch (Exception e) {
            System.out.println(e);
        }
    }

///**
// *  read next line which contains token information;<br>
// *  each line will contain the token type used in lexical analysis and
// *  the printstring of the token: e.g.<br><ul>
// *  <li>Program program</li>
// *  <li>Int int</li>
// *  <li>BOOLean boolean</li></ul>
// * @throws IOException 
// */
    public void getNextToken() throws IOException {
        try {
            StringTokenizer st = new StringTokenizer(in.readLine());
            type = st.nextToken();
            value = st.nextToken();
        } catch (NoSuchElementException e) {
            System.out.println("***tokens file does not have 2 strings per line***");
            System.exit(1);
        } catch (NullPointerException ne) {
            throw new IOException("***End of File***");
        }
        tokenCount++;
    }

///**
// *  initTokenClasses will create the 2 files
//*/
    public void initTokenClasses() {
        table.println("/*********************");
        table.println("*");
        table.println("* @Author Mikael C. Miller");
        table.println("*");
        table.println("* SFSU 9/20/15");
        table.println("*");
        table.println("* CSc 413");
        table.println("*");
        table.println("*/");
        table.println("package lexer;");
        table.println(" ");
        table.println("/**");
        table.println(" *  This file is automatically generated<br>");
        table.println(" *  it contains the table of mappings from token");
        table.println(" *  constants to their Symbols");
        table.println("*/");
        table.println("public class TokenType {");
        table.println("   public static java.util.HashMap<Tokens,Symbol> tokens = new java.util.HashMap<Tokens,Symbol>();");
        table.println("   public TokenType() {");
        symbols.println("package lexer;");
        symbols.println(" ");
        symbols.println("/**");
        symbols.println(" *  This file is automatically generated<br>");
        symbols.println(" *  - it contains the enumberation of all of the tokens");
        symbols.println("*/");
        symbols.println("public enum Tokens {");
        symbols.print("  BogusToken");

        while (true) {
            try {
                getNextToken();
            } catch (IOException e) {break;}

            String symType = "Tokens." + type;

            table.println("     tokens.put(" + symType +
                ", Symbol.symbol(\"" + value + "\"," + symType + "));");

            if (tokenCount % 5 == 0) {
                symbols.print(",\n    "+ type);
            } else {
                symbols.print("," + type);
            }
        }

        table.println("   }");
        table.println("}");
        table.close();
        symbols.println("\n}");
        symbols.close();
        try {
            in.close();
        } catch (Exception e) {}
    }
}

1 个答案:

答案 0 :(得分:1)

TokenSetup的构造函数中,抛出了FileNotFound异常,但除了仅将异常消息打印到System.out之外,您不会对其执行任何操作。然后,您的构造函数返回就好像一切正​​常,并且main()函数继续在部分初始化的initTokenClasses()实例上调用TokenSetup。我甚至不想为此会发生什么。我甚至都不去研究它。这是无关紧要的。问题在于抛出的第一个异常FileNotFound异常。之后发生的NullPointerExceptionred herring (Wikipedia)

如果您有例外情况,则无法继续进行,就好像什么都没发生一样。不能在地毯下扫除例外情况。这样做:

public static void main(String args[]) throws Exception

    TokenSetup() throws Exception

如果您不知道如何处理异常,请停止尝试捕获异常。

这样,当抛出异常时,程序会立即停止,而不是继续向下进行操作,并使您遇到更多不可避免的例外情况。