1

だから私はいくつかの.mjavaファイルをコンパイルするこのコンパイラクラスを持っていますが、他のファイルは失敗し、誰かが理由を理解するのを手伝ってくれるかどうか疑問に思っています. 2 つの異なるファイルで壊れる 2 つの方法があります。コンパイルしようとする最初の consts.mjava ファイルは次のとおりです。

// demo of true local and global variables
int glob0;
int glob1;
final int two = 2;
final int three = 3;
main() {
    int loc1;
    int loc2;
    int loc3;
    final int four = 4;
    glob0 = three;
    //print("glob0=", glob0, "\n");
    loc1 = glob0*two+1;
    glob1 = glob0*loc1;
    loc2  = glob1+1;
    loc3 = glob1*loc2/four;
    print("glob0=", glob0, " (should be 3)\n");
    print("glob1=", glob1, " (should be 21)\n");
    print("loc1=",  loc1,  " (should be 7)\n");
    print("loc2=",  loc2,  " (should be 22)\n");
    print("loc3=",  loc3,  " (should be 115)\n");
}

これをコンパイラ クラスでコンパイルしようとすると、次のように壊れます。

private void compileFactor() {

    if (isIdent(theToken)) {
        String ident = theToken;
        theToken = t.token();            
        IdentInfo theInfo = symTable.lookup(ident);


        boolean its_a_variable = theInfo.isVar();  ***//Breaks Here for consts.mjava Null Exception***
        int theAddr; 
        boolean isGlobal = theInfo.getIsGlobal();
        int constValue;
        int theNumber = 0;

        if (its_a_variable) {   // pld12: CHANGE THIS!!
                 theAddr = theInfo.getAddr(); 
                 isGlobal = theInfo.getIsGlobal();
                 if (theAddr == -1) t.error("undeclared identifier used in expr: "+ident);
                 if (isGlobal) cs.emit(Machine.LOAD, theAddr);
                 else cs.emit(Machine.LOADF, theAddr);
        } else {
                 constValue = theInfo.getValue();
                 if (constValue == 0) 
                        t.error("undeclared identifier used in expr: "+ident);
                 else {
                          cs.emitLOADINT(theNumber);
                 }
                }
            } else if (isNumber(theToken)) {
                int theNumber = new Integer(theToken).intValue();
                cs.emitLOADINT(theNumber);
                theToken = t.token();
            } else if (equals(theToken, "(")) {  
                accept("(");
                compileExpr();
                accept(")");
            }
        }

次の locs.mjava ファイルを実行しようとすると、このメソッドが中断されます。

private void compileIdentStmt() {
        String ident = theToken;
        boolean isGlobal = true;
        int location = 0;
        int entryPoint = 0;
        IdentInfo varInfo = null;
        if (!isIdent(ident)) t.error("expected identifier, got " + theToken);
        theToken = t.token();
        if (equals(theToken, "=")) {    
            accept("=");

            varInfo = symTable.lookup(ident);
            if (varInfo.isVar() == true) {      ***//Breaks Here on locs.mjava: Null Exception***
                location = varInfo.getAddr();        
                isGlobal = varInfo.getIsGlobal();    
            }

            /*
            if (varInfo==null) {
                location = GHack(ident);
                isGlobal = true;
            }
            if (location == -1) {
                location = LHack(ident);
                isGlobal = false;
            }
            /* */
            compileExpr();
            if (isGlobal) cs.emit(Machine.STOR, location);
            else cs.emit(Machine.STORF, location);      
            accept(";");
        } else if (equals(theToken, "(")) {     
                         varInfo = symTable.lookup(ident);

             if (varInfo.isProc() == true) {  
                entryPoint = varInfo.getEntryPoint();
                dprint("call to function " + ident + "; generating JSR to location " + entryPoint);
                accept("(");
            }
            /* 
            if (!equals(theToken, ")")) {   
                compileExpr();
                while (equals(theToken, ",")) {
                    accept(",");
                    compileExpr();
                }
            }
            /* */
            accept(")");
            accept(";");
            cs.emit(Machine.JSR, entryPoint);
        } else t.error("expected \"=\" or \"(\", got " + theToken);
    }

役立つように、symTable() からルックアップ メソッドを提供することもできます。

public IdentInfo lookup(String ident) {
        IdentInfo ii;
        if (HMLocal != null) {
            ii = HMLocal.get(ident);
            if (ii != null) {
                return ii;
            }
            ii = HMGlobal.get(ident);
            if (ii != null) {
                return ii;
            }
        }
        return null;
    }
4

2 に答える 2

2

NullPointerExceptions を取得している場合は、例でtheInfovarInfoが null であるためです。

于 2009-12-10T15:23:34.497 に答える
1

IdentInfo theInfo = symTable.lookup(ident);

ルックアップメソッドはnullを返す可能性があることを明確に示しているため、Infoを操作する前に、TheInfoがnullであるかどうかを確認する必要があります。

于 2009-12-10T15:26:36.333 に答える