From 76b4660a046381774a5f7018ec7c663ce3db808d Mon Sep 17 00:00:00 2001 From: c-my Date: Sun, 23 Dec 2018 10:15:24 +0800 Subject: [PATCH] add struct type --- res/SimpleGrammar.txt | 5 +++- src/com/compiler/parser/LLParser.java | 25 ++++++++++++++++---- src/com/compiler/parser/ParserGenerator.java | 8 +++++-- src/com/compiler/parser/Symbol.java | 2 +- src/com/compiler/parser/SymbolTableItem.java | 10 ++++++++ 5 files changed, 41 insertions(+), 9 deletions(-) diff --git a/res/SimpleGrammar.txt b/res/SimpleGrammar.txt index 42a0a75..38c6ec1 100644 --- a/res/SimpleGrammar.txt +++ b/res/SimpleGrammar.txt @@ -1,4 +1,4 @@ -program->declear program|calculation ; program|condition program|cycle program|array_declear program|print_func ; program|break_keyword ; program|$ +program->struct_declear program|declear program|calculation ; program|condition program|cycle program|array_declear program|print_func ; program|break_keyword ; program|$ print_func->PRINT calculation GEQ_PRINT @@ -7,6 +7,9 @@ declear->type_name PUSH IDENTIFIER PUSH declear1 declear1->; FILL|= declear2 declear2->CONSTANT PUSH FILL_I ;|IDENTIFIER PUSH FILL_I ; +struct_declear->STRUCT IDENTIFIER BEGIN_STRUCT { struct_declear1 } END_STRUCT +struct_declear1->declear struct_declear1|$ + array_declear->[ CONSTANT PUSH_CAPACITY ] type_name PUSH IDENTIFIER PUSH array_declear1 array_declear1->; FILL_EMPTY_ARRAY|= array_declear2 array_declear2->{ constant_list } FILL_ARRAY ; diff --git a/src/com/compiler/parser/LLParser.java b/src/com/compiler/parser/LLParser.java index a82c677..ea6174e 100644 --- a/src/com/compiler/parser/LLParser.java +++ b/src/com/compiler/parser/LLParser.java @@ -54,6 +54,10 @@ abstract class LLParser { Stack symStack = new Stack<>(); Stack semStack = new Stack<>(); Stack capacityStack = new Stack<>(); + Stack structStack = new Stack<>(); + + boolean isStruct = false; + String currentStruct = ""; str.add(endSym); symStack.push(endSym); @@ -85,7 +89,7 @@ abstract class LLParser { tokenType = Token.tokenType.CHAR; break; } - Tables.SymbolTable.add(new SymbolTableItem(name.getValue(), tokenType, SymbolTableItem.cat_enum.VARIABLE, "")); + Tables.SymbolTable.add(new SymbolTableItem(name.getValue(), tokenType, SymbolTableItem.cat_enum.VARIABLE, "", currentStruct)); break; case FILL_I: Symbol i_initVal = semStack.pop(); @@ -107,26 +111,28 @@ abstract class LLParser { break; } if (i_initVal.getId().equals("CONSTANT")) - Tables.SymbolTable.add(new SymbolTableItem(i_name.getValue(), i_tokenType, SymbolTableItem.cat_enum.VARIABLE, i_initVal.getValue())); + Tables.SymbolTable.add(new SymbolTableItem(i_name.getValue(), i_tokenType, SymbolTableItem.cat_enum.VARIABLE, i_initVal.getValue(), currentStruct)); else if (i_initVal.getId().equals("IDENTIFIER")) { //在符号表中找到这个标识符的值 switch (Tables.getType(i_initVal.getValue())) { case INTEGER: - Tables.SymbolTable.add(new SymbolTableItem(i_name.getValue(), i_tokenType, SymbolTableItem.cat_enum.VARIABLE, Integer.toString(Tables.getIntValue(i_initVal.getValue())))); + Tables.SymbolTable.add(new SymbolTableItem(i_name.getValue(), i_tokenType, SymbolTableItem.cat_enum.VARIABLE, Integer.toString(Tables.getIntValue(i_initVal.getValue())), currentStruct)); break; case FLOAT: - Tables.SymbolTable.add(new SymbolTableItem(i_name.getValue(), i_tokenType, SymbolTableItem.cat_enum.VARIABLE, Double.toString(Tables.getDoubleValue(i_initVal.getValue())))); + Tables.SymbolTable.add(new SymbolTableItem(i_name.getValue(), i_tokenType, SymbolTableItem.cat_enum.VARIABLE, Double.toString(Tables.getDoubleValue(i_initVal.getValue())), currentStruct)); break; case CHAR: - Tables.SymbolTable.add(new SymbolTableItem(i_name.getValue(), i_tokenType, SymbolTableItem.cat_enum.VARIABLE, Character.toString(Tables.getCharValue(i_initVal.getValue())))); + Tables.SymbolTable.add(new SymbolTableItem(i_name.getValue(), i_tokenType, SymbolTableItem.cat_enum.VARIABLE, Character.toString(Tables.getCharValue(i_initVal.getValue())), currentStruct)); break; case NULL: break; } } + break; case PUSH: semStack.push(lastTopSym); + break; case GEQ: Symbol opd2 = semStack.pop(); @@ -212,6 +218,15 @@ abstract class LLParser { System.out.print(semStack.pop().getValue() + " "); System.out.println(); break; + case BEGIN_STRUCT: + + currentStruct = lastTopSym.getValue(); + Tables.SymbolTable.add(new SymbolTableItem(currentStruct, Token.tokenType.NONE, SymbolTableItem.cat_enum.TYPE, "")); + break; + case END_STRUCUT: + currentStruct = ""; + isStruct = false; + break; } continue; case Terminal: diff --git a/src/com/compiler/parser/ParserGenerator.java b/src/com/compiler/parser/ParserGenerator.java index 60c309b..58f657b 100644 --- a/src/com/compiler/parser/ParserGenerator.java +++ b/src/com/compiler/parser/ParserGenerator.java @@ -59,12 +59,16 @@ public class ParserGenerator { 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(sym.equals("GEQ_BREAK")) + else if (sym.equals("GEQ_BREAK")) symbolString.add(new Symbol(sym, Symbol.ActionType.GEQ_BREAK)); - else if(sym.equals("GEQ_CONTINUE")) + else if (sym.equals("GEQ_CONTINUE")) symbolString.add(new Symbol(sym, Symbol.ActionType.GEQ_CONTINUE)); else if (sym.equals("GEQ_PRINT")) symbolString.add(new Symbol(sym, Symbol.ActionType.GEQ_PRINT)); + else if (sym.equals("BEGIN_STRUCT")) + symbolString.add(new Symbol(sym, Symbol.ActionType.BEGIN_STRUCT)); + else if (sym.equals("END_STRUCT")) + symbolString.add(new Symbol(sym, Symbol.ActionType.END_STRUCUT)); else if (ParserTest.isTerminal(sym)) symbolString.add(new Symbol(sym, Symbol.SymbolType.Terminal)); else diff --git a/src/com/compiler/parser/Symbol.java b/src/com/compiler/parser/Symbol.java index fdc2fa2..6b6161a 100644 --- a/src/com/compiler/parser/Symbol.java +++ b/src/com/compiler/parser/Symbol.java @@ -40,7 +40,7 @@ public class Symbol { , FILL_EMPTY_ARRAY //填空数组 , PUSH_CAPACITY //将数组容量压栈 , GEQ //生成运算四元式 - , GEQ_IF, END_IF, BEGIN_ELSE, GEQ_WHILE, END_WHILE, GEQ_PRINT, GEQ_BREAK, GEQ_CONTINUE + , GEQ_IF, END_IF, BEGIN_ELSE, GEQ_WHILE, END_WHILE, GEQ_PRINT, GEQ_BREAK, GEQ_CONTINUE, BEGIN_STRUCT, END_STRUCUT } public String getId() { diff --git a/src/com/compiler/parser/SymbolTableItem.java b/src/com/compiler/parser/SymbolTableItem.java index 5f8e965..27b86d9 100644 --- a/src/com/compiler/parser/SymbolTableItem.java +++ b/src/com/compiler/parser/SymbolTableItem.java @@ -54,12 +54,18 @@ public class SymbolTableItem { } } + public SymbolTableItem(String name, Token.tokenType tokenType, cat_enum cat, String initVal, String belong) { + this(name, tokenType, cat, initVal); + this.belongTo = belong; + } + public enum cat_enum {FUNC, CONSTANT, VARIABLE, TYPE} private String name; // 符号名 private int typ; // 符号类型(在类型表中的索引) private int addr; // 符号地址 private cat_enum cat; // 符号种类 + private String belongTo; public cat_enum getCat() { return cat; @@ -96,6 +102,10 @@ public class SymbolTableItem { sb.append(Tables.charList.get(addr)); break; } +// if(!belongTo.isEmpty()){ + sb.append(" belongsTo: "); + sb.append(belongTo); +// } return sb.toString(); } }