临时备份
This commit is contained in:
1 parent
1f0940eaaf
commit
f8a1eefc21
17 files changed
+202
-59
No files matched your search
+21
-4
@@ -1,14 +1,30 @@
|
||||
program->declear program|calculation ; program|$
|
||||
program->declear program|calculation ; program|condition program|cycle program|array_declear program|$
|
||||
|
||||
|
||||
declear->type_name PUSH IDENTIFIER PUSH declear1
|
||||
declear1->; FILL|= declear2
|
||||
declear2->CONSTANT PUSH FILL_I ;|IDENTIFIER PUSH FILL_I ;
|
||||
|
||||
array_declear->[ CONSTANT PUSH_CAPACITY ] type_name PUSH IDENTIFIER array_declear1
|
||||
array_declear1->; FILL_EMPTY_ARRAY|= array_declear2
|
||||
array_declear2->{ constant_list } FILL_ARRAY ;
|
||||
|
||||
constant_list->CONSTANT PUSH constant_list1|$
|
||||
constant_list1->$|, constant_list
|
||||
|
||||
assignment->IDENTIFIER = CONSTANT
|
||||
|
||||
calculation->fourth calculation1
|
||||
calculation1->fourth_operator PUSH fourth GEQ calculation1|$
|
||||
condition->IF ( calculation ) GEQ_IF { program } condition_else END_IF
|
||||
condition_else->BEGIN_ELSE ELSE { program }|$
|
||||
|
||||
cycle->WHILE ( calculation ) GEQ_WHILE { program } END_WHILE
|
||||
|
||||
|
||||
|
||||
calculation->fifth calculation1
|
||||
calculation1->fifth_operator PUSH fifth GEQ calculation1 |$
|
||||
fifth->fourth fifth1
|
||||
fifth1->fourth_operator PUSH fourth GEQ fifth1|$
|
||||
fourth->third fourth1
|
||||
fourth1->third_operator PUSH third GEQ fourth1|$
|
||||
third->second third1
|
||||
@@ -23,4 +39,5 @@ binary_operator->*|+|-|/|%|&|~|^||
|
||||
first_operator->!|~
|
||||
second_operator->*|/|%
|
||||
third_operator->+|-|<<|>>
|
||||
fourth_operator->&|^||
|
||||
fourth_operator->&|^||
|
||||
fifth_operator->=|EQ_OP|NE_OP
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
int a = 13;
|
||||
int b = 16;
|
||||
int b = 100;
|
||||
int c;
|
||||
c = a + b;
|
||||
@@ -1,14 +1,14 @@
|
||||
package com.compiler.IntermediateCodeGeneration;
|
||||
|
||||
import com.compiler.parser.Quaternary;
|
||||
import com.compiler.parser.Tables;
|
||||
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 {
|
||||
public byte[] generateBytecode() throws Exception {
|
||||
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||
MethodVisitor mv;
|
||||
//版本 ,类型, 名字, signature,父类, 接口
|
||||
@@ -18,9 +18,11 @@ public class BytecodeGenerator implements Opcodes {
|
||||
//声明 static void main
|
||||
mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
|
||||
//遍历四元式
|
||||
for (Quaternary quaternary : array) {
|
||||
System.out.println(Tables.quaternaryList + "!!!");
|
||||
for (Quaternary quaternary : Tables.quaternaryList) {
|
||||
ComputClass c = new ComputClass(new Quaternary());
|
||||
c.comput(mv);
|
||||
c.comput(mv,quaternary);
|
||||
System.out.println("循环四元式完成");
|
||||
}
|
||||
mv.visitInsn(RETURN); //add return instruction
|
||||
mv.visitEnd();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.compiler.IntermediateCodeGeneration;
|
||||
|
||||
import com.compiler.parser.Tables;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
@@ -10,17 +9,18 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class Compiler implements Opcodes {
|
||||
public void Compilermain(String[] args) throws Exception {
|
||||
/*public void Compilermain(String[] args) throws Exception {
|
||||
new Compiler().compile(args);
|
||||
}
|
||||
}*/
|
||||
|
||||
public void compile(String[] args) throws Exception {
|
||||
public void compile() throws Exception {
|
||||
|
||||
//System.out.println(Tables.quaternaryList + "!!!");
|
||||
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);
|
||||
final byte[] byteCode = new BytecodeGenerator().generateBytecode();
|
||||
saveBytecodeToClassFile(fileName, byteCode);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,15 +15,16 @@ public class ComputClass implements Opcodes {
|
||||
this.quaternary = quaternary;
|
||||
}
|
||||
|
||||
public void comput(MethodVisitor mv){
|
||||
final String opt = quaternary.getOpt();//判断运算符
|
||||
if (opt == "=") {
|
||||
public void comput(MethodVisitor mv , Quaternary quaternary){
|
||||
final String opt = new String(quaternary.getOpt());//判断运算符
|
||||
if (opt.equals("=")) {
|
||||
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);
|
||||
System.out.println("等于完成");
|
||||
break;
|
||||
case FLOAT:
|
||||
int dou0 = Tables.getSymbolCount(quaternary.getOpds().get(0), TypeLabelItem.type.FLOAT);
|
||||
@@ -34,7 +35,7 @@ public class ComputClass implements Opcodes {
|
||||
}
|
||||
|
||||
}
|
||||
else if(opt == "+"){
|
||||
else if(opt.equals("+")){
|
||||
switch (Tables.getType(quaternary.getOpds().get(0))){
|
||||
case INTEGER:
|
||||
int val0 = Tables.getSymbolCount(quaternary.getOpds().get(0), TypeLabelItem.type.INTEGER);
|
||||
@@ -44,6 +45,7 @@ public class ComputClass implements Opcodes {
|
||||
mv.visitVarInsn(ILOAD, val1);
|
||||
mv.visitInsn(IADD);
|
||||
mv.visitVarInsn(ISTORE, val2);
|
||||
System.out.println("加法完成");
|
||||
break;
|
||||
case FLOAT:
|
||||
int dou0 = Tables.getSymbolCount(quaternary.getOpds().get(0), TypeLabelItem.type.FLOAT);
|
||||
|
||||
+12
-12
@@ -1,40 +1,40 @@
|
||||
package com.compiler;
|
||||
|
||||
import com.compiler.lexer.Lexer;
|
||||
import com.compiler.IntermediateCodeGeneration.Compiler;
|
||||
import com.compiler.lexer.LexerTester;
|
||||
import com.compiler.parser.ParserGenerator;
|
||||
import com.compiler.parser.ParserTest;
|
||||
import com.compiler.parser.Tables;
|
||||
import com.compiler.parser.Test;
|
||||
import com.compiler.utils.FileReader;
|
||||
import com.compiler.utils.Show;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
System.out.println("====================================");
|
||||
|
||||
|
||||
LexerTester lt = new LexerTester();
|
||||
var tokenList = lt.getTokenList();
|
||||
System.out.println(tokenList);
|
||||
|
||||
System.out.println("=========");
|
||||
System.out.println("====================================");
|
||||
|
||||
ParserTest pt = new ParserTest();
|
||||
var symbolString = ParserGenerator.ReadTokenlist(tokenList);
|
||||
System.out.println(symbolString);
|
||||
|
||||
|
||||
boolean result = pt.Check(symbolString);
|
||||
var compiler = new Compiler();
|
||||
try{compiler.compile();}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println(result);
|
||||
|
||||
System.out.println(Tables.SymbolTable);
|
||||
System.out.println(Tables.quaternaryList);
|
||||
|
||||
// List<String> lines = FileReader.getLines("res/SimpleGrammar.txt");
|
||||
////// lines.add("primary_expression->IDENTIFIER|CONSTANT|STRING_LITERAL|( expression )");
|
||||
////// lines.add("B->tc|ee");
|
||||
// Show.printRules(ParserGenerator.Read(lines));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.compiler.asm;
|
||||
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.Queue;
|
||||
|
||||
public class AsmTest {
|
||||
public static void compile(){
|
||||
class BytecodeGenerator implements Opcodes{
|
||||
public byte[] generateBytecode(Queue<Instruction> instructionQueue, String name) throws Exception {
|
||||
|
||||
ClassWriter cw = new ClassWriter(0);
|
||||
MethodVisitor mv;
|
||||
//version , acess, name, signature, base class, interfaes
|
||||
cw.visit(52, ACC_PUBLIC + ACC_SUPER, name, null, "java/lang/Object", null);
|
||||
{
|
||||
//declare static void main
|
||||
mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
|
||||
final long localVariablesCount = instructionQueue.stream()
|
||||
.filter(instruction -> instruction instanceof VariableDeclaration)
|
||||
.count();
|
||||
final int maxStack = 100; //TODO - do that properly
|
||||
|
||||
//apply instructions generated from traversing parse tree!
|
||||
for (Instruction instruction : instructionQueue) {
|
||||
instruction.apply(mv);
|
||||
}
|
||||
mv.visitInsn(RETURN); //add return instruction
|
||||
|
||||
mv.visitMaxs(maxStack, (int) localVariablesCount); //set max stack and max local variables
|
||||
mv.visitEnd();
|
||||
}
|
||||
cw.visitEnd();
|
||||
|
||||
return cw.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.compiler.asm;
|
||||
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
public interface Instruction {
|
||||
void apply(MethodVisitor methodVisitor);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.compiler.asm;
|
||||
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
public class VariableDeclaration implements Instruction, Opcodes {
|
||||
// Variable variable;
|
||||
|
||||
@Override
|
||||
public void apply(MethodVisitor methodVisitor) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -79,8 +79,8 @@ public class LexerTester {
|
||||
}
|
||||
|
||||
private boolean isKeywordSuffix(Character ch) {
|
||||
return ch == ')' || ch == ' ' || ch == '\t'
|
||||
|| ch == '[' || ch == '*';
|
||||
return ch=='(' || ch == ')' || ch == ' ' || ch == '\t'
|
||||
|| ch == '[' || ch == '*' || ch=='{';
|
||||
}
|
||||
|
||||
private boolean isNumSuffix(Character ch) {
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.compiler.parser;
|
||||
|
||||
import com.compiler.lexer.Token;
|
||||
|
||||
import javax.lang.model.util.ElementScanner6;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -36,13 +35,29 @@ public class ParserGenerator {
|
||||
if (sym.equals("$"))
|
||||
symbolString.add(new Symbol(sym, Symbol.SymbolType.Empty));
|
||||
else if (sym.equals("PUSH"))
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionTYpe.PUSH));
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionType.PUSH));
|
||||
else if (sym.equals("PUSH_CAPACITY"))
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionType.PUSH_CAPACITY));
|
||||
else if (sym.equals("FILL"))
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionTYpe.FILL));
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionType.FILL));
|
||||
else if (sym.equals("FILL_I"))
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionTYpe.FILL_I));
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionType.FILL_I));
|
||||
else if (sym.equals("FILL_ARRAY"))
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionType.FILL_ARRAY));
|
||||
else if (sym.equals("FILL_EMPTY_ARRAY"))
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionType.FILL_EMPTY_ARRAY));
|
||||
else if (sym.equals("GEQ"))
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionTYpe.GEQ));
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionType.GEQ));
|
||||
else if (sym.equals("GEQ_IF"))
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionType.GEQ_IF));
|
||||
else if (sym.equals("END_IF"))
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionType.END_IF));
|
||||
else if (sym.equals("BEGIN_ELSE"))
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionType.BEGIN_ELSE));
|
||||
else if (sym.equals("GEQ_WHILE"))
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionType.GEQ_WHILE));
|
||||
else if (sym.equals("END_WHILE"))
|
||||
symbolString.add(new Symbol(sym, Symbol.ActionType.END_WHILE));
|
||||
else if (ParserTest.isTerminal(sym))
|
||||
symbolString.add(new Symbol(sym, Symbol.SymbolType.Terminal));
|
||||
else
|
||||
@@ -70,9 +85,6 @@ public class ParserGenerator {
|
||||
break;
|
||||
case DELIMITER:
|
||||
switch (token.getStr()) {
|
||||
case "=":
|
||||
symbolList.add(new Symbol("=", Symbol.SymbolType.Terminal));
|
||||
break;
|
||||
case "*=":
|
||||
symbolList.add(new Symbol("MUL_ASSIGN", Symbol.SymbolType.Terminal));
|
||||
break;
|
||||
|
||||
@@ -26,16 +26,16 @@ public class ParserTest extends LLParser {
|
||||
// System.out.print("\t");
|
||||
// System.out.println(form.get(k));
|
||||
// }
|
||||
var rules = getProductionRules();
|
||||
for (var ru : rules.keySet()) {
|
||||
var strs = rules.get(ru);
|
||||
for (var st : strs) {
|
||||
var select = getSelect(st);
|
||||
System.out.print(st);
|
||||
System.out.print(": ");
|
||||
System.out.println(select);
|
||||
}
|
||||
}
|
||||
// var rules = getProductionRules();
|
||||
// for (var ru : rules.keySet()) {
|
||||
// var strs = rules.get(ru);
|
||||
// for (var st : strs) {
|
||||
// var select = getSelect(st);
|
||||
// System.out.print(st);
|
||||
// System.out.print(": ");
|
||||
// System.out.println(select);
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -26,4 +26,19 @@ public class Quaternary {
|
||||
public ArrayList<String> getOpds() {
|
||||
return new ArrayList<String>(Arrays.asList(opd1, opd2, opd3));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("(");
|
||||
sb.append(opt);
|
||||
sb.append(", ");
|
||||
sb.append(opd1);
|
||||
sb.append(", ");
|
||||
sb.append(opd2);
|
||||
sb.append(", ");
|
||||
sb.append(opd3);
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ public class Symbol {
|
||||
this.valueType = type;
|
||||
}
|
||||
|
||||
Symbol(final String name, ActionTYpe at) {
|
||||
Symbol(final String name, ActionType at) {
|
||||
id = name;
|
||||
aType = at;
|
||||
sType = SymbolType.Action;
|
||||
@@ -34,10 +34,13 @@ public class Symbol {
|
||||
Terminal, Nonterminal, Empty, End, Action
|
||||
}
|
||||
|
||||
enum ActionTYpe {
|
||||
PUSH, FILL
|
||||
, FILL_I //有初值的填表
|
||||
enum ActionType {
|
||||
PUSH, FILL, FILL_I //有初值的填表
|
||||
, FILL_ARRAY //填数组表
|
||||
, FILL_EMPTY_ARRAY //填空数组
|
||||
, PUSH_CAPACITY //将数组容量压栈
|
||||
, GEQ //生成运算四元式
|
||||
, GEQ_IF, END_IF, BEGIN_ELSE, GEQ_WHILE, END_WHILE
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
@@ -48,7 +51,7 @@ public class Symbol {
|
||||
return sType;
|
||||
}
|
||||
|
||||
public ActionTYpe getaType() {
|
||||
public ActionType getaType() {
|
||||
return aType;
|
||||
}
|
||||
|
||||
@@ -62,7 +65,7 @@ public class Symbol {
|
||||
|
||||
private String id;
|
||||
private SymbolType sType;
|
||||
private ActionTYpe aType;
|
||||
private ActionType aType;
|
||||
private String value;
|
||||
private Token.tokenType valueType = Token.tokenType.NONE;
|
||||
|
||||
@@ -71,6 +74,8 @@ public class Symbol {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (sType == SymbolType.Nonterminal)
|
||||
sb.append("[N]");
|
||||
else if (sType == SymbolType.Action)
|
||||
sb.append("[AC]");
|
||||
sb.append(id);
|
||||
if (valueType != Token.tokenType.NONE) {
|
||||
sb.append("(");
|
||||
|
||||
@@ -78,7 +78,17 @@ public class SymbolString implements Iterable {
|
||||
|
||||
boolean isEmpty() {
|
||||
return symString.isEmpty() ||
|
||||
(symString.get(0).getType().equals(Symbol.SymbolType.Empty));
|
||||
(symString.get(0).getType().equals(Symbol.SymbolType.Empty)) ||
|
||||
isAllAction();
|
||||
|
||||
}
|
||||
|
||||
private boolean isAllAction() {
|
||||
for (var sym : symString) {
|
||||
if (sym.getType() != Symbol.SymbolType.Action)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
@@ -111,4 +121,12 @@ public class SymbolString implements Iterable {
|
||||
|
||||
private ArrayList<Symbol> symString;
|
||||
private int id;
|
||||
|
||||
public Symbol getFirstSymbol() {
|
||||
for (var sym : symString) {
|
||||
if (sym.getType() != Symbol.SymbolType.Action)
|
||||
return sym;
|
||||
}
|
||||
return new Symbol();
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,9 @@ public class Tables {
|
||||
public static ArrayList<Double> doubleList = new ArrayList<>();
|
||||
public static ArrayList<Character> charList = new ArrayList<>();
|
||||
|
||||
//数组表
|
||||
public static ArrayList<ArrayTableItem> arrayTable = new ArrayList<>();
|
||||
|
||||
//四元式表
|
||||
public static ArrayList<Quaternary> quaternaryList = new ArrayList<>();
|
||||
|
||||
@@ -63,6 +66,7 @@ public class Tables {
|
||||
return ' ';
|
||||
}
|
||||
|
||||
// 在符号表中查找名为name的符号并返回其类型,若符号表中不存在该符号则返回NULL类型
|
||||
public static TypeLabelItem.type getType(String name) {
|
||||
var first = SymbolTable.stream().filter(item -> item.getName().equals(name)).findFirst();
|
||||
if (first.isPresent()) {
|
||||
@@ -72,6 +76,7 @@ public class Tables {
|
||||
return TypeLabelItem.type.NULL;
|
||||
}
|
||||
|
||||
//返回 名为name的符号 是 符号表中第几个 类型为type的 符号
|
||||
public static int getSymbolCount(String name, TypeLabelItem.type type) {
|
||||
int index = 0;
|
||||
for (SymbolTableItem item : SymbolTable) {
|
||||
@@ -152,6 +157,10 @@ class SymbolTableItem {
|
||||
Tables.integerList.add(Integer.parseInt(initVal));
|
||||
addr = Tables.integerList.size() - 1;
|
||||
break;
|
||||
case NONE://其他类型(数组)
|
||||
typ = Tables.typeTabel.size();
|
||||
Tables.typeTabel.add(new TypeLabelItem(TypeLabelItem.type.ARRAY));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +212,7 @@ class SymbolTableItem {
|
||||
|
||||
//数组表
|
||||
class ArrayTableItem {
|
||||
public ArrayTableItem(int up) {
|
||||
public ArrayTableItem(int up, Token.tokenType type) {
|
||||
this.up = up;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user