【发布时间】:2010-01-26 00:13:12
【问题描述】:
大家好!
作为我自学 Java 的一部分,我正在尝试完成一项可用的 Java 初学者作业here(非常古老的东西 - 2001 年)
问题是我不知道如何应对这个挑战 :( 我会感谢任何建议,因为解决方案不再可用,只有指向压缩档案的链接可以正常工作。
问候, 玛丽
附言。作业:
**"**作业 3:主题 3、子类的作业
(这是对由 阿巴拉契亚州立大学计算机科学的 Cindy Norris 教授)
本次作业的目标是让您在一个特别有用的环境中练习子类。您将为最小的机器语言 - MML 编写一个解释器。机器语言指令的一般形式是
标签指令寄存器列表
label 是行的标签。其他说明可能会“跳转”到该标签。
instruction 是实际的指令。在 MML 中,有用于加法、乘法等、存储和检索整数以及有条件地跳转到其他标签(如 if 语句)的指令。
register-list 是指令操作的寄存器列表。寄存器是计算机内存中简单的整数存储区域,很像变量。在 MML 中,有 32 个寄存器,编号为 0、1、...、31。
MML 有以下指令:
L1 add r s1 s2 - 将寄存器 s1 和 s2 的内容相加,并将结果存入寄存器 r。
L1 sub r s1 s2 - 从 s1 的内容中减去寄存器 s2 的内容,并将结果存入寄存器 r。
L1 mul r s1 s2 - 将寄存器 s1 和 s2 的内容相乘并将结果存储在寄存器 r 中。
L1 div r s1 s2 - 将寄存器 s1 的内容除以寄存器 s2 的内容(Java 整数除法)并将结果存储在寄存器 r 中。
L1 out s1 - 在 Java 控制台上打印寄存器 s1 的内容(使用 println)。
L1 lin r x - 将整数 x 存储在寄存器 r 中。
L1 bnz s1 L2 如果寄存器 s1 的内容不为零,则使标记为 L2 的语句成为下一个要执行的语句。
我们减少了不同指令的数量,这样您就可以减少工作量。例如,可能存在其他分支指令、否定指令、输入指令等。但是一旦你实现了这个小语言,你将很容易添加更多的指令。
L1 是任何标识符——实际上,任何非空白字符序列。程序的每条语句都必须标有不同的标识符。 s1、s2 和 r 中的每一个都是 0..31 范围内的整数,并且引用执行语言 MML 的机器中的 32 个寄存器之一。这是一个计算阶乘 6 的 MML 程序示例。请注意,指令的相邻字段(标签、操作码和操作数)由空格分隔。
f0 lin 20 6
f1 lin 21 1
f2 lin 22 1
f3 mul 21 21 20
f4 sub 20 20 22
f5 bnz 20 f3
f6 out 21
程序的指令按顺序执行(从第一个开始),除非执行 bnz 指令改变了顺序。执行在其最后一条指令执行完毕时终止(并且不会更改执行顺序)。
您的口译员会
- 从用户那里获取包含该程序的文件的名称,
- 从文件中读取程序并翻译成内部形式,
- 打印程序,
- 执行程序,然后
- 打印寄存器的最终值。"
Machine.java
import java.util.*;
// The machine language interpreter
public class Machine {
// The labels in the MML program, in the order in which
// they appear (are defined) in the program
private Labels labels= new Labels();
// The MML program, consisting of prog.size() instructions, each
// of class Instruction (or one of its subclasses)
private Vector prog= new Vector();
// The registers of the MML machine
private Registers registers;
// The program counter; it contains the index (in prog) of
// the next instruction to be executed.
private int PC= 0;
public static void main (String[] pars) {
Machine m= new Machine();
Translator.readAndTranslate(m.labels, m.prog);
System.out.println("Here is the program; it has " +
m.prog.size() + " instructions.");
m.print();
System.out.println();
System.out.println("Beginning program execution.");
m.execute();
System.out.println("Ending program execution.");
System.out.println("Values of registers at program termination:");
System.out.println(m.registers + ".");
System.exit(0);
}
// Print the program
public void print() {
for (int i= 0; i != prog.size(); i++) {
System.out.println((Instruction) prog.elementAt(i));
}
}
// Execute the program in prog, beginning at instruction 0.
// Precondition: the program and its labels have been store properly.
public void execute() {
PC= 0;
registers= new Registers();
while (PC < prog.size()) {
Instruction ins= (Instruction)prog.elementAt(PC);
PC= PC+1;
ins.execute(this);
}
}
// = the registers of this machine
public Registers getRegisters() {
return registers;
}
// = the labels of this machine
public Labels getLabels() {
return labels;
}
// Set the program counter to pc
public void setPC(int pc) {
PC= pc;
}
}
Translator.java
import java.io.*;
import java.util.*;
import javax.swing.*;
// The translator of a small program. All the fields and methods are static.
public class Translator {
private static BufferedReader br; // Reader attached to the file chosen by the user
// word + line is the part of the current line that's not yet processed
// word has no whitespace
// If word and line are not empty, line begins with whitespace
private static String line="";
private static String word="";
private static Labels labels; // The labels of the program being translated
private static Vector program; // The program to be created
// Obtain a file name from the user and translate the
// small program in that file into lab (the labels) and
// prog (the program)
// return "no errors were detected"
public static boolean readAndTranslate(Labels lab, Vector prog) {
try {
getReader();
} catch(IOException ioE) {
System.out.println("Sai: IO error to start " );
return false;
}
labels= lab;
labels.reset();
program= prog;
program.removeAllElements();
try { line = br.readLine();
}
catch (IOException ioE) {
return false;
}
// Each iteration processes line and reads the next line into line
while (line != null) {
// Store the label in label
String label= scan();
if (label.length() > 0) {
Instruction ins= getInstruction(label);
if ( ins != null ) {
labels.addLabel(label);
program.addElement(ins);
}
}
try { line = br.readLine();
}
catch (IOException ioE) {
return false;
}
}
return true;
}
// line should consist of an MML instruction, with its label already
// removed. Translate line into an instruction with label label
// and return the instruction
public static Instruction getInstruction(String label) {
int s1; // Possible operands of the instruction
int s2;
int r;
int x;
String L2;
String ins= scan();
if (line.equals("")) return null;
if (ins.equals("add")) {
r= scanInt();
s1= scanInt();
s2= scanInt();
return new AddInstruction(label, r, s1, s2);
}
// You will have to write code here for the other instructions.
return null;
}
// Display a JFileChooser and set br to a reader for the file chosen
private static void getReader() throws IOException {
JFileChooser chooser = new JFileChooser("C:\\Windows\\Desktop\\compiler\\test0.txt");
chooser.setDialogTitle("Choose the File that contains the MML program to be executed");
chooser.showOpenDialog(null);
br = new BufferedReader(new FileReader(chooser.getSelectedFile()));
}
// Return the first word of line and remove it from line.
// If there is no word, return ""
public static String scan() {
line= line.trim();
if (line.length() == 0)
{ return ""; }
int i= 0;
while (i < line.length() &&
line.charAt(i) != ' ' &&
line.charAt(i) != '\t') {
i= i+1;
}
word= line.substring(0,i);
line= line.substring(i);
return word;
}
// Return the first word of line as an integer. If there is
// any error, return the maximum int
public static int scanInt() {
String word= scan();
if (word.length() == 0)
{ return Integer.MAX_VALUE; }
try {
return Integer.parseInt(word);
} catch (NumberFormatException e) {
return Integer.MAX_VALUE;
}
}
}
Labels.java
import java.util.*;
// An instance contains a list of Strings, called "labels",
// in the order in which they were added to the list.
public class Labels {
private Vector labels= new Vector();
// Constructor: an empty list of labels
public Labels() {
}
// Add label lab to this list and return its number in the list
// (the first one added is number 0)
// Precondition: the list has at most 49 entries
public int addLabel(String lab) {
labels.addElement(lab);
return labels.size()-1;
}
// = the number of label lab in the list
// (= -1 if lab is not in the list)
public int indexOf(String lab) {
// invariant: lab is not in labels[0..i-1]
for (int i= 0; i != labels.size(); i++) {
if (lab.equals((String)(labels.elementAt(i)))) {
return i;
}
}
return -1;
}
// representation of this instance, "(label 0, label 1, ..., label (n-1))"
public String toString() {
String r= "(";
// invariant: r contains the representation for labels[0..i-1]
// (with the opening "(" but no closing ")")
for (int i= 0; i != labels.size(); i++) {
if (i == 0) {
r= r + (String)(labels.elementAt(i));
} else {
r= r + ", " + (String)(labels.elementAt(i));
}
}
r= r + ")";
return r;
}
// Set the number of elements in the list to 0
public void reset() {
labels.removeAllElements();
}
}
Registers.java
// An instance contains 31 registers and methods to access
// and change them
public class Registers {
private int registers[]= new int[31];
// Constructor: an instance whose registers are set to 0
public Registers() {
for (int i= 0; i != registers.length; i++) {
registers[i]= 0;
}
}
// = the value in register i.
// Precondition: 0 <= i < 32
public int getRegister(int i) {
return registers[i];
}
// Set register i to v.
// Precondition: 0 <= i < 32
public void setRegister(int i, int v) {
registers[i]= v;
}
// = a representation of the registers,
// "(reg 0, reg 1, ..., reg 31)"
public String toString() {
String r= "(" + registers[0];
// invariant: r contains the representation for registers[0..i-1]
// (with the opening "(" but no closing ")")
for (int i= 1; i != registers.length; i++) {
r= r + ", " + registers[i];
}
r= r + ")";
return r;
}
}
Instruction.java
// This class is the superclass of the classes for machine instructions
public abstract class Instruction {
// Constructor: an instruction with label l and opcode op
// (op must be an operation of the language)
public Instruction(String l, String op) {
}
// = the representation "label: opcode" of this Instruction
public String toString() {
return "";
}
// Execute this instruction on machine m.
public abstract void execute(Machine m);
}
【问题讨论】:
-
第一种方法是阅读说明;)(我刚刚注意到这甚至是一个有用的评论)
-
不太可能有人愿意坐下来阅读所有内容。更有效的方法是发布您遇到的特定问题,并且只发布与它相关的信息。