生成字节码
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"CurrentProjectSetting": null
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"ExpandedNodes": [
|
||||
""
|
||||
],
|
||||
"PreviewInSolutionExplorer": false
|
||||
}
|
||||
Binary file not shown.
+2
-2
@@ -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>
|
||||
+3
-4
@@ -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();
|
||||
}*/
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user