生成字节码

This commit is contained in:
D-j001
2018-12-20 21:42:17 +08:00
parent d1a23d7ddb
commit f0c1a8984b
15 changed files with 358 additions and 36 deletions
Binary file not shown.
+3
View File
@@ -0,0 +1,3 @@
{
"CurrentProjectSetting": null
}
+6
View File
@@ -0,0 +1,6 @@
{
"ExpandedNodes": [
""
],
"PreviewInSolutionExplorer": false
}
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -7,6 +7,6 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="asm-7.0" level="project" />
</component>
</module>
</module>
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+3 -4
View File
@@ -1,5 +1,4 @@
int a = 13;
double c;
int b = a;
a<<23-1;
int b = 16;
int c;
c = a + b;
@@ -0,0 +1,31 @@
package com.compiler.IntermediateCodeGeneration;
import com.compiler.parser.Quaternary;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.ArrayList;
public class BytecodeGenerator implements Opcodes {
public byte[] generateBytecode(ArrayList<Quaternary> array) throws Exception {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
MethodVisitor mv;
//版本 ,类型, 名字, signature,父类, 接口
//创建一个共有类MyClass
cw.visit(52, ACC_PUBLIC + ACC_SUPER, "lexer", null, "java/lang/Object", null);
{
//声明 static void main
mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
//遍历四元式
for (Quaternary quaternary : array) {
ComputClass c = new ComputClass(new Quaternary());
c.comput(mv);
}
mv.visitInsn(RETURN); //add return instruction
mv.visitEnd();
}
cw.visitEnd();
return cw.toByteArray();
}
}
@@ -0,0 +1,38 @@
package com.compiler.IntermediateCodeGeneration;
import com.compiler.parser.Tables;
import org.apache.commons.lang3.StringUtils;
import org.objectweb.asm.Opcodes;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Compiler implements Opcodes {
public void Compilermain(String[] args) throws Exception {
new Compiler().compile(args);
}
public void compile(String[] args) throws Exception {
final File enkelFile = new File("res/lexer.c");
String fileName = enkelFile.getName();
//String fileAbsolutePath = enkelFile.getAbsolutePath();
//String className = StringUtils.remove(fileName, ".enk");
final byte[] byteCode = new BytecodeGenerator().generateBytecode(Tables.quaternaryList);
saveBytecodeToClassFile(fileName, byteCode);
}
private static void saveBytecodeToClassFile(String fileName, byte[] byteCode) throws IOException {
final String classFile = StringUtils.replace(fileName, ".c", ".class");
OutputStream os = new FileOutputStream(classFile);
System.out.println(".class文件生成");
os.write(byteCode);
System.out.println(".class文件写入");
os.close();
System.out.println(".class文件关闭");
}
}
@@ -0,0 +1,62 @@
package com.compiler.IntermediateCodeGeneration;
import com.compiler.parser.Quaternary;
import com.compiler.parser.Tables;
import com.compiler.parser.TypeLabelItem;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class ComputClass implements Opcodes {
Quaternary quaternary;
public ComputClass(Quaternary quaternary) {
this.quaternary = quaternary;
}
public void comput(MethodVisitor mv){
final String opt = quaternary.getOpt();//判断运算符
if (opt == "=") {
switch (Tables.getType(quaternary.getOpds().get(0))){
case INTEGER:
int val0 = Tables.getSymbolCount(quaternary.getOpds().get(0), TypeLabelItem.type.INTEGER);
int val2 = Tables.getSymbolCount(quaternary.getOpds().get(2), TypeLabelItem.type.INTEGER);
mv.visitIntInsn(BIPUSH, val0);
mv.visitVarInsn(ISTORE, val2);
break;
case FLOAT:
int dou0 = Tables.getSymbolCount(quaternary.getOpds().get(0), TypeLabelItem.type.FLOAT);
int dou2 = Tables.getSymbolCount(quaternary.getOpds().get(2), TypeLabelItem.type.FLOAT);
mv.visitVarInsn(FLOAD, dou0);
mv.visitVarInsn(FSTORE,dou2);
break;
}
}
else if(opt == "+"){
switch (Tables.getType(quaternary.getOpds().get(0))){
case INTEGER:
int val0 = Tables.getSymbolCount(quaternary.getOpds().get(0), TypeLabelItem.type.INTEGER);
int val1 = Tables.getSymbolCount(quaternary.getOpds().get(1), TypeLabelItem.type.INTEGER);
int val2 = Tables.getSymbolCount(quaternary.getOpds().get(2), TypeLabelItem.type.INTEGER);
mv.visitVarInsn(ILOAD, val0);
mv.visitVarInsn(ILOAD, val1);
mv.visitInsn(IADD);
mv.visitVarInsn(ISTORE, val2);
break;
case FLOAT:
int dou0 = Tables.getSymbolCount(quaternary.getOpds().get(0), TypeLabelItem.type.FLOAT);
int dou1 = Tables.getSymbolCount(quaternary.getOpds().get(1), TypeLabelItem.type.FLOAT);
int dou2 = Tables.getSymbolCount(quaternary.getOpds().get(2), TypeLabelItem.type.FLOAT);
mv.visitVarInsn(DLOAD, dou0);
mv.visitVarInsn(DLOAD, dou1);
mv.visitInsn(FADD);
mv.visitVarInsn(FSTORE,dou2);
break;
}
}
}
}
@@ -0,0 +1,89 @@
package com.compiler.IntermediateCodeGeneration;
import com.compiler.parser.Quaternary;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import java.io.*;
public class JvmCode extends PreJvmCode{
Quaternary quaternary = new Quaternary();
public void GetJvmCode(){
}
public static void addContainsToFile(long position,String contents) throws IOException {
//1、参数校验
File file = new File("C:\\Users\\代进\\Desktop\\111.txt");
System.out.println(file);
//判断文件是否存在
if(!(file.exists() && file.isFile())){
System.out.println("文件不存在 ~ ");
return;
}
//判断position是否合法
if((position < 0) || (position > file.length())){
System.out.println("position不合法 ~ ");
return;
}
//2、创建临时文件
File tempFile =File.createTempFile("sss", ".temp",new File("d:/"));
//3、用文件输入流、文件输出流对文件进行操作
FileOutputStream outputStream = new FileOutputStream(tempFile);
FileInputStream inputStream = new FileInputStream(tempFile);
//在退出JVM退出时自动删除
tempFile.deleteOnExit();
//4、创建RandomAccessFile流
RandomAccessFile rw = new RandomAccessFile(file,"rw");
//文件指定位置到 position
rw.seek(position);
int tmp;
//5、将position位置后的内容写入临时文件
while((tmp = rw.read())!=-1){
outputStream.write(tmp);
}
//6、将追加内容 contents 写入 position 位置
rw.seek(position);
rw.write(contents.getBytes());
//7、将临时文件写回文件,并将创建的流关闭
while((tmp = inputStream.read())!=-1){
rw.write(tmp);
}
rw.close();
outputStream.close();
inputStream.close();
}
private void EqualJvm(){//四元式运算符为等于号(=)生成字节码
//<=,1,,a >
System.out.println("0: iconst_1");
System.out.println("1: istore_1");
String contents = new String("0: iconst_1" + "\n" + "1: istore_1");
try {
addContainsToFile(file.length()-1,contents);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void GetBite(){
ClassWriter cw = new ClassWriter(0);
MethodVisitor mv;
//cw.visit(52, ACC_PUBLUC + ACC_SUPER, name, null, "java/lang/Object",null);
}
public static void main(String[] args){
JvmCode c = new JvmCode();
c.printHead();
c.EqualJvm();
}
}
@@ -0,0 +1,54 @@
package com.compiler.IntermediateCodeGeneration;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class PreJvmCode {
File file = null;
public void printHead(){
//main函数JVM头
FileWriter fw = null;
file = new File("C:\\Users\\代进\\Desktop\\111.txt");
try{
if(!file.exists()){
//文件不存在,创建文件
file.createNewFile();
}
fw = new FileWriter(file);
fw.write("Compiled from \"main.java\"\n" +
"public class main {\n" +
" public main();\n" +
" Code:\n" +
" 0: aload_0\n" +
" 1: invokespecial #1 // Method java/lang/Object.\"<init>\":()V\n" +
" 4: return\n" +
"\n" +
" public static void main(java.lang.String[]);\n" +
" Code:" +
"" +
"}");
}catch (IOException e){
e.printStackTrace();
}finally {
if(fw != null){
try{
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//添加文件其余部分
/*String contents = new String("abcd");
try {
test.addContainsToFile(file.length()-1,contents);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
+40 -30
View File
@@ -24,6 +24,13 @@ public class Tables {
//四元式表
public static ArrayList<Quaternary> quaternaryList = new ArrayList<>();
public static SymbolTableItem findSymbol(String name){
var res = SymbolTable.stream().filter(item -> item.getName().equals(name)).findFirst();
if(res.isPresent())
return res.get();
return new SymbolTableItem();
}
public static int getIntValue(String name) {
var first = SymbolTable.stream().filter(item -> item.getName().equals(name)).findFirst();
@@ -80,39 +87,42 @@ public class Tables {
}
// 类型表中的表项
class TypeLabelItem {
public TypeLabelItem(type t) {
this.t = t;
switch (t) {
case CHAR:
case INTEGER:
case FLOAT:
this.tpoint = -1; //基本类型为null
break;
case ARRAY:
break;
case STRUCT:
break;
}
}
public enum type {INTEGER, FLOAT, CHAR, ARRAY, STRUCT, NULL}
private type t;
private int tpoint;
public int getTpoint() {
return tpoint;
}
public type getType() {
return t;
}
}
//// 类型表中的表项
//class TypeLabelItem {
// public TypeLabelItem(type t) {
// this.t = t;
// switch (t) {
// case CHAR:
// case INTEGER:
// case FLOAT:
// this.tpoint = -1; //基本类型为null
// break;
// case ARRAY:
// break;
// case STRUCT:
// break;
// }
// }
//
// public enum type {INTEGER, FLOAT, CHAR, ARRAY, STRUCT, NULL}
//
// private type t;
// private int tpoint;
//
// public int getTpoint() {
// return tpoint;
// }
//
// public type getType() {
// return t;
// }
//}
// 符号总表中的表项
class SymbolTableItem {
public SymbolTableItem(){
}
public SymbolTableItem(String name, Token.tokenType tokenType, cat_enum cat, String initVal) {
this.name = name;
this.cat = cat;
@@ -0,0 +1,30 @@
package com.compiler.parser;
public class TypeLabelItem { public TypeLabelItem(type t) {
this.t = t;
switch (t) {
case CHAR:
case INTEGER:
case FLOAT:
this.tpoint = -1; //基本类型为null
break;
case ARRAY:
break;
case STRUCT:
break;
}
}
public enum type {INTEGER, FLOAT, CHAR, ARRAY, STRUCT, NULL}
private type t;
private int tpoint;
public int getTpoint() {
return tpoint;
}
public type getType() {
return t;
}
}