├── README.md ├── MiniGo.g4 └── MiniGoPrintListener.java /README.md: -------------------------------------------------------------------------------- 1 | 컴파일러개론 질의응답을 위한 repository 입니다 2 | -------------------------------------------------------------------------------- /MiniGo.g4: -------------------------------------------------------------------------------- 1 | /** 2 | * Define a grammar called Hello 3 | */ 4 | grammar MiniGo; 5 | @header {package generated;} 6 | 7 | program : decl+ {}; 8 | decl : var_decl 9 | | fun_decl ; 10 | var_decl : dec_spec IDENT type_spec 11 | | dec_spec IDENT type_spec '=' LITERAL 12 | | dec_spec IDENT '[' LITERAL ']' type_spec ; 13 | 14 | dec_spec : VAR ; 15 | type_spec : 16 | | INT 17 | | '[' LITERAL ']' INT ; 18 | fun_decl : FUNC IDENT '(' params ')' type_spec compound_stmt ; 19 | params : 20 | |param (',' param)* ; 21 | param : IDENT 22 | | IDENT type_spec ; 23 | stmt : expr_stmt 24 | | compound_stmt 25 | | if_stmt 26 | | for_stmt 27 | | return_stmt ; 28 | expr_stmt : expr ; 29 | for_stmt : FOR expr stmt ; 30 | compound_stmt: '{' local_decl* stmt* '}' ; 31 | local_decl : var_decl ; 32 | if_stmt : IF expr stmt 33 | | IF expr stmt ELSE stmt ; 34 | return_stmt : RETURN expr 35 | | RETURN expr ',' expr 36 | | RETURN ; 37 | expr : '(' expr ')' 38 | | IDENT '(' args ')' 39 | | IDENT '[' expr ']' 40 | | op=('-'|'+'|'--'|'++'|'!') expr 41 | | left=expr op=('*'|'/'|'%'|'+'|'-') right=expr 42 | | left=expr op=(EQ|NE|LE|'<'|GE|'>'|AND|OR) right=expr 43 | | IDENT '=' expr 44 | | IDENT '[' expr ']' '=' expr 45 | | (LITERAL|IDENT) 46 | ; 47 | 48 | args : expr (',' expr)* 49 | | ; 50 | 51 | VAR: 'var'; 52 | FUNC: 'func'; 53 | INT: 'int'; 54 | 55 | FOR: 'for'; 56 | IF: 'if'; 57 | ELSE: 'else'; 58 | RETURN: 'return'; 59 | OR: 'or'; 60 | AND: 'and'; 61 | LE: '<='; 62 | GE: '>='; 63 | EQ: '=='; 64 | NE: '!='; 65 | 66 | IDENT : [a-zA-Z_] 67 | ( [a-zA-Z_] 68 | | [0-9] 69 | )*; 70 | 71 | 72 | LITERAL: DecimalConstant | OctalConstant | HexadecimalConstant | NilConstant | WildCardConstant ; 73 | 74 | 75 | DecimalConstant 76 | : '0' 77 | | [1-9] [0-9]* 78 | ; 79 | 80 | OctalConstant 81 | : '0'[0-7]* 82 | ; 83 | 84 | HexadecimalConstant 85 | : '0' [xX] [0-9a-fA-F] + 86 | ; 87 | 88 | NilConstant 89 | : 'NIL' 90 | | 'nil' 91 | ; 92 | 93 | WildCardConstant 94 | : '_' 95 | ; 96 | 97 | WS : ( ' ' 98 | | '\t' 99 | | '\r' 100 | | '\n' 101 | )+ 102 | -> channel(HIDDEN) 103 | ; 104 | -------------------------------------------------------------------------------- /MiniGoPrintListener.java: -------------------------------------------------------------------------------- 1 | public class MiniGoPrintListener extends MiniGoBaseListener { 2 | ParseTreeProperty newTexts = new ParseTreeProperty(); 3 | 4 | static class Util { 5 | static boolean isBinaryOperation(MiniGoParser.ExprContext ctx) { 6 | return ctx.getChildCount() == 3 && 7 | ctx.getChild(1) != ctx.expr() && ! ctx.getChild(1).getText().equals("="); 8 | } 9 | 10 | static boolean isIfStmt(ParseTree ctx) { 11 | return ctx.getChildCount() > 0 && 12 | ctx.getChild(0).getText().equals("if"); 13 | } 14 | 15 | static boolean isForStmt(ParseTree ctx) { 16 | return ctx.getChildCount() > 0 && 17 | ctx.getChild(0).getText().equals("for"); 18 | } 19 | 20 | static boolean isCompoundStmt(ParseTree ctx) { 21 | return ctx.getChildCount() > 0 && 22 | ctx.getChild(0).getChildCount() > 0 && 23 | ctx.getChild(0).getChild(0).getText().equals("{"); 24 | } 25 | 26 | } 27 | 28 | ParseTreeProperty nesting = new ParseTreeProperty(); 29 | 30 | String tabs(ParseTree ctx) { 31 | String ts = ""; 32 | for (int i=0; i < nesting.get(ctx); i++) { 33 | ts+= "...."; 34 | } 35 | return ts; 36 | } 37 | 38 | /***********************************************************************************/ 39 | @Override 40 | public void exitExpr(MiniGoParser.ExprContext ctx) { 41 | if (ctx.getChildCount() == 1) { 42 | if (ctx.getChild(0) == ctx.LITERAL()) 43 | newTexts.put(ctx, ctx.getChild(0).getText()); 44 | else if (ctx.getChild(0) == ctx.IDENT()) 45 | newTexts.put(ctx, ctx.getChild(0).getText()); 46 | } 47 | 48 | else if (ctx.getChildCount() == 2) // unary 49 | newTexts.put(ctx, ctx.getChild(0).getText() + newTexts.get(ctx.getChild(1))); 50 | 51 | else if (ctx.getChildCount() == 3) { 52 | if (ctx.getChild(0).getText().equals("(") ) 53 | newTexts.put(ctx, "(" + ctx.getChild(1).getText() + ")"); 54 | 55 | else if (Util.isBinaryOperation(ctx)) { 56 | // 예: expr '+' expr 57 | String s1 = null, s2 = null, op = null; 58 | s1 = newTexts.get(ctx.expr(0)); 59 | s2 = newTexts.get(ctx.expr(1)); 60 | op = ctx.getChild(1).getText(); 61 | newTexts.put(ctx, s1 + " " + op + " " + s2); 62 | } 63 | else if (ctx.getChild(0) == ctx.IDENT()) { 64 | newTexts.put(ctx, ctx.getChild(0).getText() + " = " + newTexts.get(ctx.getChild(2))); 65 | } 66 | return; 67 | } 68 | 69 | else if (ctx.getChildCount() == 4) { 70 | if (ctx.getChild(0) == ctx.IDENT()) { 71 | String s = ctx.IDENT().getText() + ctx.getChild(1).getText() 72 | + newTexts.get(ctx.getChild(2)) 73 | + ctx.getChild(3).getText() ; 74 | newTexts.put(ctx, s); 75 | } 76 | } 77 | else if (ctx.getChildCount() == 6) { 78 | String s = ctx.IDENT().getText() + "[" 79 | + newTexts.get(ctx.getChild(2)) + "] = " 80 | + newTexts.get(ctx.getChild(6)); 81 | newTexts.put(ctx, s); 82 | } 83 | } 84 | 85 | @Override public void exitProgram(MiniGoParser.ProgramContext ctx) { 86 | String s = ""; 87 | for (int i=0; ctx.getChild(i) != null ; i++) { 88 | s += newTexts.get(ctx.getChild(i)); } 89 | newTexts.put(ctx, s); 90 | System.out.println(s); 91 | } 92 | } 93 | --------------------------------------------------------------------------------