📄 mycompiler.java
字号:
/* * MyCompiler.java * * Created on 2006年3月15日, 下午9:51 * *Convert the assembly (LC - 2) into binary code */package os.compiler;/** * * @author Vernkin */import java.util.*;import java.io.*;/** * 编译单元 * 语法按照 LC-2 * @version 1.1 2006.03.03 * decrease the wrong stuation that may end the programe */public class MyCompiler implements BaseInstruction{ /** * Store the wrong report message */ private static String report = ""; /** * 对于无效的编译返回整数的最大值 * 即语法错误。包括: * 1。 立即数超过范围 * 2。 所使用的标签没有声称 * @param in The line to be compiled * @param line line number * @param dat the declared symbols list * @return the binary string code * If fail , return MAX_VALUE in integer */ public int compilerSingleLine(String in,int line,DataAddress[] dat){ StringTokenizer st = new StringTokenizer(in," ,\t"); int count = 0;//count for elements String temp="",name = "",ret = ""; String result = "";//store the binary String /**确定操作名**/ while(st.hasMoreTokens()){ count++; if(count>2){ report += "\n Line"+line+" :没有操作指令"; return -1; } temp = st.nextToken(); if(!isInstruction(temp)) continue; if(isInstruction(temp)){ result += instructionToCode(temp); break; } } name = temp.toUpperCase(); String[] param = new String[3]; for(count=0;count<3 && st.hasMoreTokens();count++) param[count] = st.nextToken(); if(name.equals("ADD") || name.equals("AND")){ result += getBianaryRegisterNum(param[0]); result += getBianaryRegisterNum(param[1]); /**imm5**/ if(param[2].charAt(0) != 'r' && param[2].charAt(0) != 'R'){ ret = convertBinary(param[2],5,-16,15); if(ret == null) return Integer.MAX_VALUE; result += "1" + ret; }else{ result += "000" + getBianaryRegisterNum(param[2]); } }else if(name.equals("LD") || name.equals("LDI") || name.equals("LEA") || name.equals("ST") || name.equals("STI")){ result += getBianaryRegisterNum(param[0]); ret = labelToValue(param[1],dat);//Wrong!!! Label required if(ret == null){ System.out.println("ret == null"); return Integer.MAX_VALUE; } result += ret; }else if(name.equals("LDR") || name.equals("STR")){ result += getBianaryRegisterNum(param[0]); result += getBianaryRegisterNum(param[1]); ret = convertBinary(param[2],6,0,63); if(ret == null) return Integer.MAX_VALUE; result += ret; }else if(name.equals("NOT")){ result += getBianaryRegisterNum(param[0]); result += getBianaryRegisterNum(param[1]); result += "111111"; }else if(name.equals("RET") || name.equals("HALT")){ result += "000000000000"; }else if(name.equals("TRAP")){ ret = convertBinary(param[0],8,0,255); if(ret == null) return Integer.MAX_VALUE; result += "0000" + ret; }else if(name.equals("JSRR")){ /**put return pc in R7**/ result += "100" + getBianaryRegisterNum(param[0]); ret = convertBinary(param[1],6,0,63); if(ret == null) return Integer.MAX_VALUE; result += ret; }else if(name.equals("JSR")){ ret = labelToValue(param[0],dat); if(ret == null) return Integer.MAX_VALUE; result += "100" + ret;//Wrong!!! Label required }else if(name.equals("BR")){ /**negetive**/ if(param[0].indexOf('n')>=0 || param[0].indexOf('N')>=0) result += "1"; else result += "0"; /**zero**/ if(param[0].indexOf('z')>=0 || param[0].indexOf('Z')>=0) result += "1"; else result += "0"; /**positive**/ if(param[0].indexOf('p')>=0 || param[0].indexOf('P')>=0) result += "1"; else result += "0"; if(result.endsWith("000")) ret = labelToValue(param[0],dat);//Wrong!!! Label required else ret = labelToValue(param[1],dat);//Wrong!!! Label required if(ret == null) return Integer.MAX_VALUE; result += ret; } System.out.println(result); return BinaryToInt(result,2); } /** * if the length of sour less than the int len * fill the string sour with char fill * @param len the return String length * @param sour source String * @param fill the char to be filled if neccesary * @return the filled string with length param len */ public static String fill(int len,String sour,char fill){ String ret = ""; if(sour.length()>len) return sour.substring(sour.length()-len); while(ret.length() <(len-sour.length())) ret += fill; ret += sour; return ret; } /** * 将其它进制转换成二进制的字符串 * @param in * @param len * @param low bound * @param high bound * @return the String indicated the value */ public static String convertBinary(String in,int len,int low,int high){ if(in == null || in.length() == 0) return null; int temp=0; try{ if(in.charAt(0) == '#') temp = Integer.parseInt(in.substring(1),10); else if(in.charAt(0) == 'X' || in.charAt(0) == 'x') temp = Integer.parseInt(in.substring(1),16); if(temp > high || temp < low){ System.out.println(in + " 参数超过范围"); report += "Error : " + in + " 参数超过范围\n"; return null; } char fill = '0'; if(temp<0) fill = '1'; return fill(len,String.valueOf(Integer.toBinaryString(temp)),fill); }catch(NumberFormatException nfe){ System.out.println(nfe.getMessage()); report += "Error : convert "+in.substring(1)+" to int"; return null; } } /** * 讲二进制字符串转化成整数 * @param in * @param radix * @return */ public static int BinaryToInt(String in,int radix){ try{ return Integer.parseInt("0"+in,radix); }catch(NumberFormatException e){ System.err.println("BinaryToInt\n"+e.getMessage()); report += "BinaryToInt\n"+e.getMessage(); // System.exit(1); } return Integer.MAX_VALUE; } /** * Compile a assembly file , differnt instructions * seperated by '\n' * @param file the assembly source file * @return The binary code , stored in the int array * If fail , return null */ public int[] compileFile(String file){ report = ""; if(file.indexOf("HALT") < 0 && file.indexOf("halt") < 0){ report += "Warning : The assembly doesn't have HALT statement\nThe programe can't be end."; return null; } if(!file.endsWith(".END") && !file.endsWith(".end")){ report += "The assembly must be end with .END or .end"; return null; } StringTokenizer st = new StringTokenizer(file,"\n"); int count = 0; int retS = 0 ; //store the result compilerSingleLine String temp,tempW; String file1 = new String(file); LinkedList data = new LinkedList(); /**first scan *find all labelr**/ while(st.hasMoreTokens()){ temp = st.nextToken(); tempW = getWordAt(temp,0); if(!isInstruction(tempW) && tempW.charAt(0) != '.'){ data.add(new DataAddress(tempW,convertBinary("x"+Integer.toHexString(count),16,0,(int)Math.pow(2, 16)-1))); } count++; } DataAddress[] dataArray = new DataAddress[data.size()]; for(int j=0;j<data.size();j++){ dataArray[j] = (DataAddress)data.get(j); // System.out.println(dataArray[j]); } /**second scan , convert to binary code**/ StringTokenizer st2 = new StringTokenizer(file1,"\n"); int[] ret = new int[st2.countTokens()-1]; count = 0; while(st2.hasMoreTokens()){ temp = st2.nextToken(); if(temp.indexOf('.')>=0){ //特殊语句 if(temp.indexOf(".end")>=0 || temp.indexOf(".END")>=0) break; if(getWordAt(temp,0).charAt(0) == '.') retS = BinaryToInt(convertBinary(getWordAt(temp,1),9,0,511 ),2); else retS = BinaryToInt(convertBinary(getWordAt(temp,2),9,0,511 ),2); if(retS == Integer.MAX_VALUE) return null; ret[count] = retS; }else{ retS = compilerSingleLine(temp,count,dataArray); if(retS == Integer.MAX_VALUE) return null; ret[count] = retS; } count++; } return ret; } public static String getWrongReport(){ return report; } /**是否指令**/ public boolean isInstruction(String in){ return indexOf(instruction,in)>=0; } /**获得一句话中第index单元**/ public String getWordAt(String in,int index){ StringTokenizer st = new StringTokenizer(in," ,\t"); if(st.countTokens() < index) return null; int count = 0; String temp =""; while(st.hasMoreTokens() && count <= index){ temp = st.nextToken(); count++; } return temp; } private static int containData(DataAddress[] dat,String name){ for(int i=0;i<dat.length;i++) if(name.equals(dat[i].name)) return i; return -1; } /**convert label to true value**/ public static String labelToValue(String label,DataAddress[] sour){ int ret = containData(sour,label); if(ret < 0){ System.out.println("labelToValue\n"+"invalid label "+label); report += "Can't find symbol "+label + "\n"; return null; } return sour[ret].value; } /** * convert the instruction code to instruction name * @param in 四位的指令代码 * @return 对应的指令名,失败返回null */ public static String codeToInstruction(String in){ return convert(instructionCode,instruction,in); } /** * convert the instruction name to instruction code * @param in 指令名 * @return 对应的指令代码,失败返回null */ public static String instructionToCode(String in){ return convert(instruction,instructionCode,in); } /** * get the register number * @param in 寄存器的名称 * @return 寄存器的编号,不存在返回-1 */ public static int getRegisterNum(String in){ return indexOf(registerName,in); } /**将寄存器的编号转为三位的二进制**/ public static String getBianaryRegisterNum(String regNum){ return fill(3,Integer.toBinaryString(getRegisterNum(regNum)),'0'); } /**@param num 寄存器代号 *◎return 寄存器名称,失败返回null*/ public static String getRegisterName(int num){ if(num<0 || num >= registerName.length) return null; return registerName[num]; } /**寻找aid在sour的位置,返回dest对应字符串 *如果找不到返回null**/ private static String convert(String[] sour,String[] dest,String aid){ int i = indexOf(sour,aid); if(i < 0) return null; return dest[i]; } /**返回aid在sour中位置,不存在返回-1**/ private static int indexOf(String[] sour,String aid){ for(int i=0;i<sour.length;i++){ if(aid.equalsIgnoreCase(sour[i])) return i; } return -1; } private class DataAddress{ public String name; public String value; private DataAddress(String name,String value){ this.name = name; this.value = value; // System.out.println("Add "+name+" "+value); } public String toString(){ return "Name "+name+" row "+value; } } /** * Testing Method * @param name * @return */ public String readFile(String name){ BufferedReader br =null;// PrintWriter pw; String ret="",temp; try{ br = new BufferedReader(new FileReader(name));// pw = new PrintWriter(new FileWriter("des.txt")); temp = br.readLine(); if(temp!=null) ret += temp; temp = br.readLine(); while(temp!=null){ ret += "\n" + temp; temp = br.readLine(); } br.close(); }catch(IOException e){ System.out.println(e.getMessage()); return ret; } return ret; } /** * Test Method * @param args */ public static void main(String args[]){ MyCompiler mc = new MyCompiler(); /* String s = "ADD R1,R1,R2"; s += "\n row1 not r2,r5"; s += "\n br row1"; s += "\nrow3 .fill x25"; s += "\n.end";*/ String s = mc.readFile("sour.txt"); int[] ret = mc.compileFile(s); System.out.println("------------------------------------------"); for(int i =0;i<ret.length;i++){ System.out.println(MyCompiler.fill(16,Integer.toBinaryString(ret[i]),'0')); } try{ PrintWriter pw = new PrintWriter(new FileWriter("des.txt")); for(int i =0;i<ret.length;i++){ pw.println(MyCompiler.fill(16,Integer.toBinaryString(ret[i]),'0')); } pw.close(); }catch(IOException e){ System.out.println(e.getMessage()); } /* mc.compilerSingleLine("br nzp x188",0,null); mc.compilerSingleLine("br pn #7",0,null); mc.compilerSingleLine("br zn #1",0,null); mc.compilerSingleLine("br zp #0",0,null); mc.compilerSingleLine("BR pzn #5",0,null); */ } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -