生成字节码
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>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="asm-7.0" level="project" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
+3
-4
@@ -1,5 +1,4 @@
|
|||||||
int a = 13;
|
int a = 13;
|
||||||
double c;
|
int b = 16;
|
||||||
int b = a;
|
int c;
|
||||||
|
c = a + b;
|
||||||
a<<23-1;
|
|
||||||
@@ -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 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) {
|
public static int getIntValue(String name) {
|
||||||
var first = SymbolTable.stream().filter(item -> item.getName().equals(name)).findFirst();
|
var first = SymbolTable.stream().filter(item -> item.getName().equals(name)).findFirst();
|
||||||
@@ -80,39 +87,42 @@ public class Tables {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 类型表中的表项
|
//// 类型表中的表项
|
||||||
class TypeLabelItem {
|
//class TypeLabelItem {
|
||||||
public TypeLabelItem(type t) {
|
// public TypeLabelItem(type t) {
|
||||||
this.t = t;
|
// this.t = t;
|
||||||
switch (t) {
|
// switch (t) {
|
||||||
case CHAR:
|
// case CHAR:
|
||||||
case INTEGER:
|
// case INTEGER:
|
||||||
case FLOAT:
|
// case FLOAT:
|
||||||
this.tpoint = -1; //基本类型为null
|
// this.tpoint = -1; //基本类型为null
|
||||||
break;
|
// break;
|
||||||
case ARRAY:
|
// case ARRAY:
|
||||||
break;
|
// break;
|
||||||
case STRUCT:
|
// case STRUCT:
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public enum type {INTEGER, FLOAT, CHAR, ARRAY, STRUCT, NULL}
|
// public enum type {INTEGER, FLOAT, CHAR, ARRAY, STRUCT, NULL}
|
||||||
|
//
|
||||||
private type t;
|
// private type t;
|
||||||
private int tpoint;
|
// private int tpoint;
|
||||||
|
//
|
||||||
public int getTpoint() {
|
// public int getTpoint() {
|
||||||
return tpoint;
|
// return tpoint;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public type getType() {
|
// public type getType() {
|
||||||
return t;
|
// return t;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
// 符号总表中的表项
|
// 符号总表中的表项
|
||||||
class SymbolTableItem {
|
class SymbolTableItem {
|
||||||
|
public SymbolTableItem(){
|
||||||
|
|
||||||
|
}
|
||||||
public SymbolTableItem(String name, Token.tokenType tokenType, cat_enum cat, String initVal) {
|
public SymbolTableItem(String name, Token.tokenType tokenType, cat_enum cat, String initVal) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.cat = cat;
|
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