1

我有一个语法 Gram.ge 我必须用 Jasmin 测试它。文件夹目录包含:

  • 代码生成器.java
  • 指令.java
  • 主.java
  • 操作码.java
  • 符号表.java
  • 类型.java
  • 茉莉.jar
  • 包含一些程序(例如 A.pas)的库目录非常简单,根据我的语法编写并保存在 .pas

而父文件夹(上面的那个)包含:

  • antlr-3.5-complete.jar

然后从命令提示符 (Windows) 我定位到目录并启动以下命令:

java -cp .;../antlr-3.5-complete.jar Org.anltr.Tool Gram.g

javac -cp .;../antlr-3.5-complete.jar *.java

java -cp .;../antlr-3.5-complete.jar Main/Library/A.pas > Output.j

java -jar jasmin.jar 输出.j

java 输出

CodeGenerator.java 文件:导入 java.util.*;

public class CodeGenerator {

    private Vector<Instruction> instructions = new Vector<Instruction>(); 
    private int counter = 0;

    public Instruction emit(Opcode opCode) {
        Instruction ist = new Instruction(opCode); 
        instructions.add(ist); 
        return ist; 
    }

    public Instruction emit(Opcode opCode, int operand) {
        Instruction ist = new Instruction(opCode, operand);
        instructions.add(ist);
        return ist;
    }

    public void emitLabel(int operand) {
        emit(Opcode.LABEL, operand);
    }

    public int newLabel() {
        return counter++;
    }

    public String toJasmin() {
        String temp = "";
        temp += header; 
        for(Instruction ist : instructions) 
            temp += ist.toJasmin() + "\n";
        temp += footer;
        return temp;
    }

    public String toString() {
        String temp = "";
        for(Instruction ist : instructions)
            temp += ist + "\n";
        return temp;
    }

    private static final String header =
        ".class public Output \n"
        + ".super java/lang/Object \n"
        + "\n"
        + ".method public <init>()V\n"
        + "  aload_0 \n"
        + "  invokenonvirtual java/lang/Object/<init>()V\n"
        + "  return \n"
        + ".end method \n"
        + "\n"
        + ".method public static printBool(I)V\n"
        + "  .limit stack 3\n"
        + "  getstatic java/lang/System/out Ljava/io/PrintStream;\n"
        + "  iload_0 \n"
        + "  bipush 1\n"
        + "  if_icmpeq Ltrue \n"
        + "  ldc \"false\"\n"
        + "  goto Lnext \n"
        + "Ltrue:\n"
        + "  ldc \"true\"\n"
        + "Lnext:\n"
        + "  invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V\n"
        + "  return \n"
        + ".end method \n"
        + "\n"
        + ".method public static printInt(I)V\n"
        + "  .limit stack 2\n"
        + "  getstatic java/lang/System/out Ljava/io/PrintStream;\n"
        + "  iload_0 \n"
        + "  invokestatic java/lang/Integer/toString(I)Ljava/lang/String;\n"
        + "  invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V\n"
        + "  return \n"
        + ".end method \n"
        + "\n"
        + ".method public static run()V\n"
        + "  .limit stack 1024\n"
        + "  .limit locals 256\n";

    private static final String footer =
        "  return \n"
        + ".end method \n"
        + "\n"
        + ".method public static main([Ljava/lang/String;)V\n"
        + "  invokestatic Output/run()V\n"
        + "  return \n"
        + ".end method \n";     

}       

除了生成此错误的最后一个(java 输出)之外,这些命令的执行没有任何问题:

    Exception in thread "main" java.lang.NoClassDefFoundError:
            at Output.run(Output.j)
            at Output.main(Output.j)
    Caused by: java.lang.ClassNotFoundException:
            at java.net.URLClassLoader$1.run(Unknown Source)
            at java.net.URLClassLoader$1.run(Unknown Source)
            at java.security.AccessController.doPrivileged(Native Method)
            at java.net.URLClassLoader.findClass(Unknown Source)
            at java.lang.ClassLoader.loadClass(Unknown Source)
            at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
            at java.lang.ClassLoader.loadClass(Unknown Source)
            ... 2 more

Output.j 文件是:

.class public Output 
.super java/lang/Object 

.method public <init>()V
  aload_0 
  invokenonvirtual java/lang/Object/<init>()V
  return 
.end method 

.method public static printBool(I)V
  .limit stack 3
  getstatic java/lang/System/out Ljava/io/PrintStream;
  iload_0 
  bipush 1
  if_icmpeq Ltrue 
  ldc "false"
  goto Lnext 
Ltrue:
  ldc "true"
Lnext:
  invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
  return 
.end method 

.method public static printInt(I)V
  .limit stack 2
  getstatic java/lang/System/out Ljava/io/PrintStream;
  iload_0 
  invokestatic java/lang/Integer/toString(I)Ljava/lang/String;
  invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
  return 
.end method 

.method public static run()V
  .limit stack 1024
  .limit locals 256
  ldc 10
  ldc 20
  ldc 30
  imul
  iadd
  invokestatic printInt(I)V
  return 
.end method 

.method public static main([Ljava/lang/String;)V
  invokestatic Output/run()V
  return 
.end method 

A.pas 文件是:

print(10 + 20 * 30)

错误可能在哪里?谢谢

4

1 回答 1

2

您的错误消息说:

java.lang.ClassNotFoundException:

但此消息的格式通常如下所示:

java.lang.ClassNotFoundException: SomeNonExistingClass

找不到的类名怎么不见了?因为您的示例中有一条指令引用了一个空的类名(“”)。因此,您需要查找忘记指定类名的指令。就在这里:

invokestatic printInt(I)V

相反,它应该是:

invokestatic Output/printInt(I)V

这将解决您的问题。

于 2014-06-10T21:24:55.723 回答