Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //@author: herykgasparini
- grammar Sauro;
- /*---------------- PARSER INTERNALS ----------------*/
- @parser::header
- {
- import java.util.ArrayList;
- }
- @lexer::members
- {
- private DenterHelper denter = new DenterHelper(NL, SauroParser.INDENT, SauroParser.DEDENT) {
- @Override
- public Token pullToken() {
- return SauroLexer.super.nextToken();
- }
- };
- @Override
- public Token nextToken() {
- return denter.nextToken();
- }
- }
- @parser::members
- {
- private static int stack_cur, stack_max, if_counter, while_counter, list_counter;
- private static void emit(String bytecode, int delta)
- {
- stack_cur += delta;
- System.out.println(" " + bytecode + " ; " + delta);
- if (stack_cur > stack_max)
- {
- stack_max = stack_cur;
- }
- }
- private static ArrayList<String> symbol_table;
- private static int errors;
- private static ArrayList<String> symbol_table_use;
- private static ArrayList<String> symbol_table_type;
- public static void main(String[] args) throws Exception
- {
- CharStream input = CharStreams.fromStream(System.in);
- //recebe do terminal
- SauroLexer lexer = new SauroLexer(input);
- //Lexer lê a entrada e gera sequencia de Tokens
- CommonTokenStream tokens = new CommonTokenStream(lexer);
- SauroParser parser = new SauroParser(tokens);
- symbol_table = new ArrayList<String>();
- symbol_table_type = new ArrayList<String>();
- symbol_table_use = new ArrayList<String>();
- symbol_table.add("args");
- errors = 0;
- symbol_table_type.add("-");
- parser.program(); //aqui começa nosso programa, ele é chamado
- System.out.println("; symbols: " + symbol_table); // o ; é um comentário do .j
- //symbol table é nossa tabela de índices X variáveis... args tem índice 0 já. índice é nosso endereço de memória, 0, 1, 2, ... Faz istore 1, 2, 3
- System.out.println("; symbols not used: " + symbol_table_use);
- if(errors > 0 )
- {
- System.err.println(errors + " error(s) occurred");
- System.exit(1);
- }
- }
- }
- /*---------------- LEXER RULES ----------------*/
- tokens {INDENT, DEDENT}
- PLUS : '+' ;
- MINUS : '-' ;
- TIMES : '*' ;
- OVER : '/' ;
- REMAINDER : '%' ;
- OP_PAR : '(' ;
- CL_PAR : ')' ;
- ATTRIB : '=' ;
- COMMA : ',' ;
- OP_CUR : '{' ;
- CL_CUR : '}' ;
- EQ : '==' ;
- NE : '!=' ;
- GT : '>' ;
- GE : '>=' ;
- LT : '<' ;
- LE : '<=' ;
- DOT : '.' ;
- COLON : ':' ;
- OP_BRA : '[' ;
- CL_BRA : ']' ;
- PRINT : 'print' ;
- READ_INT : 'read_int';
- READ_STR : 'read_str';
- WHILE : 'while';
- IF : 'if';
- APPEND : 'append';
- LIST : 'list';
- LEN : 'len';
- STR : 'str';
- STRING : '"'~["]* '"';
- NUMBER : '0'..'9'+ ;
- VAR : 'a'..'z'+ ;
- // SPACE : (' '|'\t'|'\r'|'\n')+ { skip(); } ;
- NL: ('\r'? '\n' ' '*) ;
- SPACE : (' '|'\t')+ { skip(); } ;
- COMMENT : '#' ~[\r\n]* { skip(); } ; //tudo que não for quebra de linha: [\r\n]
- /*---------------- PARSER RULES ----------------*/
- //vai pro program, tem que achar o main
- program
- : {
- System.out.println(".source Test.j");
- System.out.println(".class public Test");
- System.out.println(".super java/lang/Object");
- System.out.println(" ");
- System.out.println(".method public <init>()V");
- System.out.println(" aload_0");
- System.out.println(" invokenonvirtual java/lang/Object/<init>()V");
- System.out.println(" return");
- System.out.println(".end method");
- System.out.println(" ");
- } main
- ;
- //vai pro main, tem que achar um statement
- main
- : {
- System.out.println(".method public static main([Ljava/lang/String;)V");
- System.out.println(" ");
- }
- ( statement )+
- {
- System.out.println(" ");
- System.out.println(" return");
- System.out.println(" ");
- System.out.println(".limit locals " + symbol_table.size()); //declara que há uma variável local(2 pelo fator estatístico de correção)
- System.out.println(".limit stack " + stack_max);
- System.out.println(".end method");
- }
- ;
- statement
- : st_print | st_attrib | st_new_list | st_list_append | st_list_attrib | st_if | st_while | NL
- ;
- st_print
- : {
- emit("getstatic java/lang/System/out Ljava/io/PrintStream;", 1);
- }
- PRINT OP_PAR expression
- {
- if($expression.type == 'i')
- {
- emit("invokevirtual java/io/PrintStream/print(I)V\n", -2);
- }
- else if ($expression.type == 'a')
- {
- emit("invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V\n", -2);
- }
- }
- ( COMMA
- {
- emit("getstatic java/lang/System/out Ljava/io/PrintStream;", 1);
- emit("ldc \" \"", 1);
- emit("invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V\n", -2);
- emit("getstatic java/lang/System/out Ljava/io/PrintStream;", 1);
- }
- expression
- {
- if($expression.type == 'i')
- {
- emit("invokevirtual java/io/PrintStream/print(I)V\n", -2);
- }
- else if ($expression.type == 'a')
- {
- emit("invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V\n", -2);
- }
- }
- )* CL_PAR
- {
- emit("getstatic java/lang/System/out Ljava/io/PrintStream;", 1);
- emit("invokevirtual java/io/PrintStream/println()V\n", -1);
- }
- ;
- //istore pega valor e salva no endereço de memória
- st_attrib
- : VAR ATTRIB expression
- {
- //$VAR.text é como sabemos o nome da variável
- if(!symbol_table.contains($VAR.text))
- {
- symbol_table.add($VAR.text);
- symbol_table_use.add($VAR.text);
- if($expression.type == 'i')
- {
- symbol_table_type.add("i");
- } else
- {
- symbol_table_type.add("a");
- }
- } else {
- if( ! symbol_table_type.get(symbol_table.indexOf($VAR.text)).equalsIgnoreCase($expression.type+"") ) {
- String type = "";
- if($expression.type != 'a') {
- type = "string";
- }
- else
- {
- type = "integer";
- }
- System.err.println("#error line '" + $VAR.line + "': variable '" + $VAR.text + "' is "+ type);
- errors++;
- }
- }
- emit( $expression.type + "store " + symbol_table.indexOf($VAR.text) + "\n", -1);
- }
- ;
- st_new_list
- :
- VAR ATTRIB LIST OP_PAR CL_PAR
- {
- //$VAR.text é como sabemos o nome da variável
- if(!symbol_table.contains($VAR.text))
- {
- symbol_table.add($VAR.text);
- symbol_table_use.add($VAR.text);
- symbol_table_type.add("l");
- }
- else
- {
- }
- emit("new List",1);
- emit("dup",1);
- emit("invokespecial List/<init>()V",-1);
- emit("astore " + symbol_table.indexOf($VAR.text) + "\n ", -1);
- }
- ;
- st_list_append
- :
- VAR DOT APPEND OP_PAR
- {
- emit("aload " + symbol_table.indexOf($VAR.text), 1);
- }
- expression
- {
- emit("invokevirtual List/append(I)V\n", -2);
- }
- CL_PAR
- ;
- st_list_attrib
- :
- VAR OP_BRA
- { emit("aload " + symbol_table.indexOf($VAR.text), 1); }
- expression CL_BRA ATTRIB expression
- { emit("invokevirtual List/set(II)V\n", -3); }
- ;
- st_if
- : { int if_local = ++if_counter; }
- IF comparison
- { emit("NOT_IF_"+ if_counter, -2);}
- COLON INDENT ( statement ) + DEDENT
- { System.out.println("NOT_IF_" + if_local + ":"); }
- ;
- st_while
- :
- { int while_local = ++while_counter; }
- { emit("BEGIN_WHILE_"+ while_local +" :",0); }
- WHILE comparison
- { emit("END_WHILE_"+while_counter, -2); }
- COLON INDENT ( statement ) +
- { emit("goto BEGIN_WHILE_" + while_local, 0); }
- DEDENT
- { System.out.println(";dedent"); }
- { emit("END_WHILE_" + while_local + ":",0); }
- ;
- comparison
- : e = expression op = (EQ | NE | GT | GE | LT | LE ) e2 = expression
- {
- if($e.type != $e2.type)
- {
- System.err.println("#error line '" + $op.line + "': cannot mix types:");
- errors++;
- }
- if ($op.type == EQ) { System.out.print("if_"+$e.type+"cmpne "); }
- else if ($op.type == NE) { System.out.print("if_"+$e.type+"cmpeq "); }
- else if ($op.type == GT) { System.out.print("if_"+$e.type+"cmple "); }
- else if ($op.type == GE) { System.out.print("if_"+$e.type+"cmplt "); }
- else if ($op.type == LT) { System.out.print("if_"+$e.type+"cmpge "); }
- else if ($op.type == LE) { System.out.print("if_"+$e.type+"cmpgt "); }
- }
- ;
- //Token é maiúsculo e expression minúsculo
- //* quer dizer que ocorre 0 ou mais daquela parte, é opcional
- expression returns [char type]
- : t1 = term ( op = ( PLUS | MINUS ) t2 = term
- {
- if($t1.type == 'a' || $t2.type == 'a')
- {
- System.err.println("#error line '" + $op.line + "': cannot mix types:");
- errors++;
- }
- if ($op.type == PLUS) { emit("iadd", -1); } else { emit("isub", -1); };
- }
- )*
- {$type = $t1.type;}
- ;
- term returns [char type]
- : f1 = factor ( op = ( TIMES | OVER | REMAINDER ) f2 = factor
- {
- if($f1.type == 'a' || $f2.type == 'a')
- {
- System.err.println("#error line '" + $op.line + "': cannot mix types:");
- errors++;
- }
- if ($op.type == TIMES) { emit("imul", -1); }
- else if ($op.type == OVER) { emit("idiv", -1); }
- else { emit("irem", -1); }
- }
- )*
- {$type = $f1.type;}
- ;
- factor returns [char type]
- : NUMBER
- {
- $type = 'i' ;
- emit("ldc "+ $NUMBER.text, 1);
- }
- | OP_PAR e = expression CL_PAR
- {
- $type = $e.type ;
- }
- | VAR
- OP_BRA
- { emit("aload " + symbol_table.indexOf($VAR.text) , 1); }
- e = expression
- CL_BRA
- {
- if(symbol_table.contains($VAR.text))
- {
- int indexOf = symbol_table.indexOf($VAR.text);
- if(symbol_table_type.get(indexOf).equalsIgnoreCase("l"))
- {
- $type = 'i';
- emit("invokevirtual List/get(I)I",-1);
- symbol_table_use.remove($VAR.text);
- }
- }
- else
- {
- System.err.println("#error line '" + $VAR.line + "': variable not declared :'" + $VAR.text + "'");
- errors++;
- }
- }
- | VAR
- {
- if(symbol_table.contains($VAR.text))
- {
- int indexOf = symbol_table.indexOf($VAR.text);
- if(symbol_table_type.get(indexOf).equalsIgnoreCase("i"))
- {
- $type = 'i';
- emit("iload " + indexOf, 1);
- symbol_table_use.remove($VAR.text);
- }
- else
- {
- $type = 'a';
- emit("aload " + indexOf, 1);
- symbol_table_use.remove($VAR.text);
- }
- }
- else
- {
- System.err.println("#error line '" + $VAR.line + "': variable not declared :'" + $VAR.text + "'");
- errors++;
- }
- }
- | READ_INT OP_PAR CL_PAR
- {
- $type = 'i' ;
- emit("invokestatic Runtime/readInt()I", 1);
- }
- | STRING
- {
- $type = 'a' ;
- emit("ldc "+ $STRING.text, 1);
- }
- | READ_STR OP_PAR CL_PAR
- {
- $type = 'a' ;
- emit("invokestatic Runtime/readString()Ljava/lang/String;", 1);
- }
- | LEN OP_PAR VAR CL_PAR
- {
- $type = 'i';
- emit("aload " + symbol_table.indexOf($VAR.text), 1);
- emit("invokevirtual List/len()I", 0);
- }
- | STR OP_PAR VAR CL_PAR
- {
- $type = 'a';
- emit("aload " + symbol_table.indexOf($VAR.text), 1);
- emit("invokevirtual List/str()Ljava/lang/String;", 0);
- }
- ;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement