⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 generate.java

📁 基于c0文法写的生成p-code的编译器
💻 JAVA
字号:
import java.io.File;import java.io.FileNotFoundException;import java.io.FileWriter;import java.io.IOException;import java.util.LinkedList;/* * To change this template, choose Tools | Templates * and open the template in the editor. */import java.util.Vector;/** * * @author lilac */public class Generate {    private Vector<Constpair> topconst = null;    public Vector<String> topvar = null;    private LinkedList<Function> funclist = null;    public Vector<String> assembler = null;      //汇编输出    private Function ff = null;                   //当前函数    private int pcount = 0;                       //参数计数    private String condition = null;    public Vector<String> st = null;          //printf用字符串表    private int stc = 0;                         //字符串计数    private String path;    public String warn=null;    public Generate(Vector<Constpair> topconst, Vector<String> topvar, LinkedList<Function> funclist, String path) {        this.funclist =funclist;        this.topconst = topconst;        this.topvar = topvar;        this.assembler = new Vector<String>();        this.st = new Vector<String>();        this.path = path;        st.add("@_IO_DATA dword ?");        st.add("@_IO_STR byte \"%d\", 0");        st.add("@_NEWLINE byte 0dh,0ah,0");    }    //给出该参数或变量的地址表示,若为全局变量则返回原字符串    private String findadr(String ss) {        Integer i;        i = ff.pmap.get(ss);              //在参数表里找        if (i != null) {            return "[ebp + " + i + " ]";        }        i = ff.vmap.get(ss);        if (i != null) {                     //再在变量表里找            return "[ebp - " + i + " ]";        }        if (ss.equals("@teax")) {          //若去函数调用的返回值怎译为eax            return "eax";        }                if(ss.charAt(0)>='0' && ss.charAt(0)<='9'){    //当为全局常量时返回原数字            return ss;                               }else{            return "$"+ss;                    //当为全局变量时直接返回加$的字符串        }                                                  }    public void Generate() {        FileWriter fw = null;        for (Function func : this.funclist) {     //遍历所有函数            ff = func;                            //ff存当前函数,以为后面方法调用从中获得数据            int space = (ff.vmap.size() + 4) * 4;   //算出函数调用需要的保留区大小,存为space            assembler.add("@f" + func.name + ":");  //写入汇编函数头            assembler.add("push ebp");            assembler.add("mov ebp,esp");            assembler.add("sub esp," + space);            for (Four four : func.fourlist) {      //遍历该函数的所有四元式                switch (four.op) {                 //根据四元式的操作符op,转入相应的方法去添加对应的汇编代码                    case Compile.ADD:                        add(four);                        break;                    case Compile.SUB:                        sub(four);                        break;                    case Compile.MUL:                        mul(four);                        break;                    case Compile.DIV:                        div(four);                        break;                    case Compile.MOV:                        mov(four);                        break;                    case Compile.CALL:                        call(four);                        break;                    case Compile.CMP:                        cmp(four);                        break;                    case Compile.CONDITION:                        condition(four);                        break;                    case Compile.J:                        j(four);                        break;                    case Compile.JFALSE:                        jfalse(four);                        break;                    case Compile.PRINTF:                        print(four);                        break;                    case Compile.PUSHPARA:                        pushpara(four);                        break;                    case Compile.RETURN:                        ret(four);                        break;                    case Compile.SCANF:                        scan(four);                        break;                    case Compile.STAMP:                        stamp(four);                        break;                    }            }            if (func.fourlist.getLast().op != Compile.RETURN) {    //检查是否有返回语句,若没有自动添加,并向用户发出警告                warn="Warning:Return Missing!";                assembler.add("mov esp,ebp");                assembler.add("pop ebp");                assembler.add("ret");            }        }        File ofile = new File(path);        //汇编输出文件        try {            ofile.createNewFile();        } catch (IOException exc) {        }        try {            fw = new FileWriter(ofile);            fw.write(".386\n");            fw.write(".MODEL FLAT\n");            fw.write("includelib msvcrt.lib\n");            fw.write("puts proto C\n");            fw.write("printf proto C\n");            fw.write("scanf proto C\n");            fw.write(".STACK 4096\n");            fw.write(".DATA\n");            for(String s : this.topvar){                fw.write("$"+s + " DWORD 0\n");            }            for (String s : st) {                fw.write(s + '\n');            }                        fw.write(".CODE\n");            for (String s : assembler) {                fw.write(s + '\n');            }            fw.write("_main:\n");            fw.write("jmp near ptr @fmain\n");            fw.write("end _main\n");            fw.flush();        } catch (FileNotFoundException ex) {        } catch (IOException ex) {        }    }//加法操作    private void add(Four four) {        assembler.add("mov eax, " + findadr(four.first));        assembler.add("add eax, " + findadr(four.last));        assembler.add("mov " + findadr(four.result) + ", eax");    }//函数调用操作    private void call(Four four) {        assembler.add("call " + "@f" + four.first);        assembler.add("add esp, " + (pcount * 4));        pcount = 0;    }//比较操作    private void cmp(Four four) {        assembler.add("mov eax, " + findadr(four.first));        assembler.add("cmp eax, " + findadr(four.last));    }//把应满足的条件存入condition字段,使后面的跳转语句可以确定其条件    private void condition(Four four) {        condition = four.first;    }//除法操作    private void div(Four four) {        assembler.add("mov eax, " + findadr(four.first));        assembler.add("cdq");        assembler.add("mov ecx, " + findadr(four.last));        assembler.add("idiv ecx");        assembler.add("mov " + findadr(four.result) + ", eax");    }//无条件跳转操作    private void j(Four four) {        assembler.add("jmp near ptr @l" + four.first);    }//当不满足condition时跳转的操作    private void jfalse(Four four) {        switch (new Integer(condition).intValue()) {            case Lex.EE:                assembler.add("jne near ptr @l" + four.first);                break;            case Lex.NE:                assembler.add("je near ptr @l" + four.first);                break;            case Lex.G:                assembler.add("jle near ptr @l" + four.first);                break;            case Lex.L:                assembler.add("jge near ptr @l" + four.first);                break;            case Lex.GE:                assembler.add("jl near ptr @l" + four.first);                break;            case Lex.LE:                assembler.add("jg near ptr @l" + four.first);                break;        }        condition = null;    }//赋值操作    private void mov(Four four) {        assembler.add("mov eax, " + findadr(four.first));        assembler.add("mov " + findadr(four.result) + ", eax");    }//乘法操作    private void mul(Four four) {        assembler.add("mov eax, " + findadr(four.first));        assembler.add("mov ecx, " + findadr(four.last));        assembler.add("imul ecx");        assembler.add("mov " + findadr(four.result) + ", eax");    }//打印操作    private void print(Four four) {        String strname = "@str" + stc;        switch (new Integer(four.result)) {            case 0:                // string                st.add(strname + " byte " + four.first + ",0");                stc++;                assembler.add("lea eax, " + strname);                assembler.add("push eax");                assembler.add("call puts");                assembler.add("add esp, 4");                break;            case 1:                // integer                assembler.add("mov eax," + findadr(four.last));                assembler.add("push eax");                assembler.add("lea eax, @_IO_STR");                assembler.add("push eax");                assembler.add("call printf");                assembler.add("add esp, 8");                break;            case 2:                // both                /*                st.add(strname + " BYTE " + four.first + ",0");                stc++;                assembler.add("mov eax," + findadr(four.last));                assembler.add("push eax");                assembler.add("lea eax, " + strname);                assembler.add("push eax");                assembler.add("call printf");                assembler.add("add esp, 8");                 */                st.add(strname + " BYTE " + four.first + ",0");                stc++;                assembler.add("lea eax, " + strname);                assembler.add("push eax");                assembler.add("call puts");                assembler.add("add esp, 4");                assembler.add("mov eax, " + findadr(four.last));                assembler.add("push eax");                assembler.add("lea eax, @_IO_STR");                assembler.add("push eax");                assembler.add("call printf");                assembler.add("add esp, 8");                break;        }        assembler.add("lea eax,@_NEWLINE");        assembler.add("push eax");        assembler.add("call printf");        assembler.add("add esp, 4");    }//推参数操作    private void pushpara(Four four) {        assembler.add("push " + findadr(four.first));        pcount++;    }//返回操作    private void ret(Four four) {        if (four.first != null) {            assembler.add("mov eax, " + findadr(four.first));        }        assembler.add("mov esp,ebp");        assembler.add("pop ebp");        assembler.add("ret");    }//读取操作    private void scan(Four four) {        assembler.add("lea eax, @_IO_DATA");        assembler.add("push eax");        assembler.add("lea eax, @_IO_STR");        assembler.add("push eax");        assembler.add("call scanf");        assembler.add("add esp, 8");        assembler.add("mov eax, @_IO_DATA");        assembler.add("mov " + findadr(four.first) + ", eax");    }//标签    private void stamp(Four four) {        assembler.add("@l" + four.first + " :");    }//减法操作    private void sub(Four four) {        assembler.add("mov eax, " + findadr(four.first));        assembler.add("sub eax, " + findadr(four.last));        assembler.add("mov " + findadr(four.result) + ", eax");    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -