SHARE
TWEET

Untitled

a guest May 24th, 2019 107 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //@author: herykgasparini
  2. grammar Sauro;
  3.  
  4. /*---------------- PARSER INTERNALS ----------------*/
  5.  
  6. @parser::header
  7. {
  8.     import java.util.ArrayList;
  9. }
  10.  
  11. @lexer::members
  12. {
  13.     private DenterHelper denter = new DenterHelper(NL, SauroParser.INDENT, SauroParser.DEDENT) {
  14.         @Override
  15.         public Token pullToken() {
  16.             return SauroLexer.super.nextToken();
  17.         }
  18.     };
  19.  
  20.     @Override
  21.     public Token nextToken() {
  22.         return denter.nextToken();
  23.     }
  24. }
  25.  
  26. @parser::members
  27. {
  28.     private static int stack_cur, stack_max, if_counter, while_counter, list_counter;
  29.  
  30.     private static void emit(String bytecode, int delta)
  31.     {
  32.         stack_cur += delta;
  33.         System.out.println("    " + bytecode + " ; " + delta);
  34.  
  35.         if (stack_cur > stack_max)
  36.         {
  37.             stack_max = stack_cur;
  38.         }
  39.     }
  40.  
  41.     private static ArrayList<String> symbol_table;
  42.     private static int errors;
  43.     private static ArrayList<String> symbol_table_use;
  44.     private static ArrayList<String> symbol_table_type;
  45.  
  46.     public static void main(String[] args) throws Exception
  47.     {
  48.         CharStream input = CharStreams.fromStream(System.in);
  49.         //recebe do terminal
  50.         SauroLexer lexer = new SauroLexer(input);
  51.         //Lexer lê a entrada e gera sequencia de Tokens
  52.         CommonTokenStream tokens = new CommonTokenStream(lexer);
  53.         SauroParser parser = new SauroParser(tokens);
  54.  
  55.         symbol_table = new ArrayList<String>();
  56.         symbol_table_type = new ArrayList<String>();
  57.         symbol_table_use = new ArrayList<String>();
  58.         symbol_table.add("args");
  59.         errors = 0;
  60.         symbol_table_type.add("-");
  61.  
  62.         parser.program(); //aqui começa nosso programa, ele é chamado
  63.  
  64.         System.out.println("; symbols: " + symbol_table);   // o ; é um comentário do .j
  65.         //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
  66.  
  67.         System.out.println("; symbols not used: " + symbol_table_use);
  68.  
  69.         if(errors > 0 )
  70.         {
  71.             System.err.println(errors + " error(s) occurred");
  72.             System.exit(1);
  73.         }
  74.     }
  75. }
  76.  
  77. /*---------------- LEXER RULES ----------------*/
  78.  
  79. tokens {INDENT, DEDENT}
  80.  
  81. PLUS       : '+'  ;
  82. MINUS      : '-'  ;
  83. TIMES      : '*'  ;
  84. OVER       : '/'  ;
  85. REMAINDER  : '%'  ;
  86. OP_PAR     : '('  ;
  87. CL_PAR     : ')'  ;
  88. ATTRIB     : '='  ;
  89. COMMA      : ','  ;
  90. OP_CUR     : '{'  ;
  91. CL_CUR     : '}'  ;
  92. EQ         : '==' ;
  93. NE         : '!=' ;
  94. GT         : '>'  ;
  95. GE         : '>=' ;
  96. LT         : '<'  ;
  97. LE         : '<=' ;
  98. DOT        : '.'  ;
  99. COLON      : ':'  ;
  100. OP_BRA     : '['  ;
  101. CL_BRA     : ']'  ;
  102.  
  103. PRINT    : 'print' ;
  104. READ_INT : 'read_int';
  105. READ_STR : 'read_str';
  106. WHILE    : 'while';
  107. IF       : 'if';
  108. APPEND   : 'append';
  109. LIST     : 'list';
  110. LEN      : 'len';
  111. STR      : 'str';
  112.  
  113. STRING : '"'~["]* '"';
  114. NUMBER : '0'..'9'+ ;
  115. VAR    : 'a'..'z'+ ;  
  116.  
  117. // SPACE   : (' '|'\t'|'\r'|'\n')+ { skip(); } ;
  118. NL: ('\r'? '\n' ' '*) ;
  119.  
  120. SPACE   : (' '|'\t')+ { skip(); } ;
  121.  
  122. COMMENT : '#' ~[\r\n]* { skip(); } ;  //tudo que não for quebra de linha: [\r\n]
  123.  
  124. /*---------------- PARSER RULES ----------------*/
  125. //vai pro program, tem que achar o main
  126. program
  127.     :   {
  128.             System.out.println(".source Test.j");
  129.             System.out.println(".class  public Test");
  130.             System.out.println(".super  java/lang/Object");
  131.             System.out.println(" ");
  132.             System.out.println(".method public <init>()V");
  133.             System.out.println("    aload_0");
  134.             System.out.println("    invokenonvirtual java/lang/Object/<init>()V");
  135.             System.out.println("    return");
  136.             System.out.println(".end method");
  137.             System.out.println(" ");  
  138.     } main
  139.     ;
  140. //vai pro main, tem que achar um statement
  141. main
  142.     :   {
  143.             System.out.println(".method public static main([Ljava/lang/String;)V");
  144.             System.out.println(" ");
  145.         }  
  146.         ( statement )+
  147.         {
  148.  
  149.             System.out.println(" ");
  150.             System.out.println("    return");
  151.             System.out.println(" ");
  152.             System.out.println(".limit locals " + symbol_table.size()); //declara que há uma variável local(2 pelo fator estatístico de correção)
  153.             System.out.println(".limit stack " + stack_max);
  154.             System.out.println(".end method");
  155.         }
  156.     ;
  157.  
  158. statement
  159.     : st_print | st_attrib | st_new_list | st_list_append | st_list_attrib | st_if | st_while | NL
  160.     ;
  161.  
  162. st_print
  163.     :   {
  164.             emit("getstatic java/lang/System/out Ljava/io/PrintStream;", 1);
  165.         }
  166.         PRINT OP_PAR expression
  167.         {
  168.             if($expression.type == 'i')
  169.             {
  170.                 emit("invokevirtual java/io/PrintStream/print(I)V\n", -2);
  171.             }
  172.             else if ($expression.type == 'a')
  173.             {
  174.                 emit("invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V\n", -2);
  175.             }
  176.  
  177.  
  178.         }
  179.         ( COMMA
  180.             {
  181.                 emit("getstatic java/lang/System/out Ljava/io/PrintStream;", 1);
  182.                 emit("ldc \" \"", 1);
  183.                 emit("invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V\n", -2);
  184.                 emit("getstatic java/lang/System/out Ljava/io/PrintStream;", 1);
  185.             }
  186.             expression
  187.             {
  188.                if($expression.type == 'i')
  189.                 {
  190.                     emit("invokevirtual java/io/PrintStream/print(I)V\n", -2);
  191.                 }
  192.                 else if ($expression.type == 'a')
  193.                 {
  194.                     emit("invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V\n", -2);
  195.                 }
  196.             }
  197.         )* CL_PAR
  198.         {
  199.             emit("getstatic java/lang/System/out Ljava/io/PrintStream;", 1);
  200.             emit("invokevirtual java/io/PrintStream/println()V\n", -1);
  201.         }
  202.     ;
  203.  
  204. //istore pega valor e salva no endereço de memória
  205. st_attrib
  206.     :   VAR ATTRIB expression
  207.         {
  208.             //$VAR.text é como sabemos o nome da variável
  209.             if(!symbol_table.contains($VAR.text))
  210.             {
  211.                 symbol_table.add($VAR.text);
  212.                 symbol_table_use.add($VAR.text);
  213.                 if($expression.type == 'i')
  214.                 {
  215.                     symbol_table_type.add("i");          
  216.                 } else
  217.                 {
  218.                     symbol_table_type.add("a");
  219.                 }
  220.             } else {
  221.                 if( ! symbol_table_type.get(symbol_table.indexOf($VAR.text)).equalsIgnoreCase($expression.type+"") ) {
  222.  
  223.                     String type = "";
  224.                     if($expression.type != 'a') {
  225.                         type = "string";
  226.                     }
  227.                     else
  228.                     {
  229.                         type = "integer";
  230.                     }
  231.                     System.err.println("#error line '" + $VAR.line + "': variable '" + $VAR.text + "' is "+ type);
  232.                     errors++;
  233.                 }
  234.             }
  235.            
  236.             emit( $expression.type + "store " + symbol_table.indexOf($VAR.text) + "\n", -1);
  237.         }
  238.     ;
  239.  
  240. st_new_list
  241.     :
  242.         VAR ATTRIB LIST OP_PAR CL_PAR
  243.         {
  244.             //$VAR.text é como sabemos o nome da variável
  245.             if(!symbol_table.contains($VAR.text))
  246.             {
  247.                 symbol_table.add($VAR.text);
  248.                 symbol_table_use.add($VAR.text);
  249.                 symbol_table_type.add("l");
  250.             }
  251.             else
  252.             {
  253.            
  254.             }
  255.             emit("new List",1);
  256.             emit("dup",1);
  257.             emit("invokespecial List/<init>()V",-1);
  258.             emit("astore " + symbol_table.indexOf($VAR.text) + "\n ", -1);
  259.         }
  260.     ;
  261.  
  262. st_list_append
  263.     :
  264.         VAR DOT APPEND OP_PAR    
  265.         {
  266.             emit("aload " + symbol_table.indexOf($VAR.text), 1);
  267.         }
  268.         expression    
  269.  
  270.         {
  271.             emit("invokevirtual List/append(I)V\n", -2);
  272.         }
  273.         CL_PAR
  274.     ;
  275.  
  276. st_list_attrib
  277.     :
  278.         VAR OP_BRA  
  279.        
  280.         { emit("aload " + symbol_table.indexOf($VAR.text), 1); }
  281.        
  282.         expression CL_BRA ATTRIB expression
  283.  
  284.         { emit("invokevirtual List/set(II)V\n", -3); }  
  285.     ;
  286.  
  287. st_if
  288.     :   { int if_local = ++if_counter; }
  289.         IF comparison  
  290.         { emit("NOT_IF_"+ if_counter, -2);}
  291.         COLON INDENT ( statement ) + DEDENT
  292.         { System.out.println("NOT_IF_" + if_local + ":"); }
  293.     ;
  294.  
  295. st_while
  296.     :
  297.         { int while_local = ++while_counter; }
  298.         { emit("BEGIN_WHILE_"+ while_local +" :",0); }
  299.         WHILE comparison
  300.         { emit("END_WHILE_"+while_counter, -2); }
  301.         COLON INDENT ( statement ) +
  302.         { emit("goto BEGIN_WHILE_" + while_local, 0); }
  303.         DEDENT
  304.         { System.out.println(";dedent"); }
  305.         { emit("END_WHILE_" + while_local + ":",0); }
  306.     ;
  307.  
  308. comparison
  309.     :   e = expression op = (EQ | NE | GT | GE | LT | LE ) e2 = expression
  310.         {
  311.             if($e.type != $e2.type)
  312.             {
  313.                 System.err.println("#error line '" + $op.line + "': cannot mix types:");
  314.                 errors++;
  315.             }
  316.            
  317.             if ($op.type == EQ) { System.out.print("if_"+$e.type+"cmpne "); }
  318.             else if ($op.type == NE) { System.out.print("if_"+$e.type+"cmpeq "); }
  319.             else if ($op.type == GT) { System.out.print("if_"+$e.type+"cmple "); }
  320.             else if ($op.type == GE) { System.out.print("if_"+$e.type+"cmplt "); }
  321.             else if ($op.type == LT) { System.out.print("if_"+$e.type+"cmpge "); }
  322.             else if ($op.type == LE) { System.out.print("if_"+$e.type+"cmpgt "); }
  323.         }
  324.     ;
  325.  
  326. //Token é maiúsculo e expression minúsculo
  327. //* quer dizer que ocorre 0 ou mais daquela parte, é opcional
  328. expression returns [char type]
  329.     :   t1 = term ( op = ( PLUS | MINUS ) t2 = term
  330.             {
  331.                 if($t1.type == 'a' || $t2.type == 'a')
  332.                 {
  333.                     System.err.println("#error line '" + $op.line + "': cannot mix types:");
  334.                     errors++;
  335.                 }
  336.  
  337.                 if ($op.type == PLUS) { emit("iadd", -1); }  else { emit("isub", -1); };
  338.             }
  339.         )*
  340.         {$type = $t1.type;}
  341.     ;
  342.  
  343. term returns [char type]
  344.     :   f1 = factor ( op = ( TIMES | OVER | REMAINDER ) f2 = factor
  345.             {
  346.  
  347.                 if($f1.type == 'a' || $f2.type == 'a')
  348.                 {
  349.                     System.err.println("#error line '" + $op.line + "': cannot mix types:");
  350.                     errors++;
  351.                 }
  352.  
  353.  
  354.                 if ($op.type == TIMES)      { emit("imul", -1); }
  355.                 else if ($op.type == OVER)  { emit("idiv", -1); }
  356.                 else                        { emit("irem", -1); }
  357.             }
  358.         )*
  359.         {$type = $f1.type;}
  360.     ;
  361.  
  362. factor returns [char type]
  363.     :   NUMBER
  364.             {
  365.                 $type = 'i' ;
  366.                 emit("ldc "+ $NUMBER.text, 1);
  367.             }
  368.     |   OP_PAR e = expression CL_PAR
  369.             {
  370.                 $type = $e.type ;
  371.             }
  372.     | VAR
  373.         OP_BRA
  374.  
  375.         { emit("aload " + symbol_table.indexOf($VAR.text) , 1); }
  376.  
  377.         e = expression
  378.  
  379.         CL_BRA
  380.         {
  381.             if(symbol_table.contains($VAR.text))
  382.             {
  383.                    
  384.                 int indexOf = symbol_table.indexOf($VAR.text);
  385.                
  386.                 if(symbol_table_type.get(indexOf).equalsIgnoreCase("l"))
  387.                 {
  388.                    
  389.                     $type = 'i';
  390.  
  391.                     emit("invokevirtual List/get(I)I",-1);
  392.                     symbol_table_use.remove($VAR.text);
  393.                 }
  394.             }
  395.             else
  396.             {
  397.                 System.err.println("#error line '" + $VAR.line + "': variable not declared :'" + $VAR.text + "'");
  398.                 errors++;
  399.             }
  400.         }
  401.  
  402.     |   VAR
  403.         {
  404.             if(symbol_table.contains($VAR.text))
  405.             {
  406.                    
  407.                 int indexOf = symbol_table.indexOf($VAR.text);
  408.  
  409.                     if(symbol_table_type.get(indexOf).equalsIgnoreCase("i"))
  410.                     {
  411.                         $type = 'i';
  412.                         emit("iload " + indexOf, 1);
  413.                         symbol_table_use.remove($VAR.text);
  414.                     }
  415.                     else
  416.                     {
  417.                         $type = 'a';
  418.                         emit("aload " + indexOf, 1);
  419.                         symbol_table_use.remove($VAR.text);
  420.                     }
  421.                 }
  422.                 else
  423.                 {
  424.                     System.err.println("#error line '" + $VAR.line + "': variable not declared :'" + $VAR.text + "'");
  425.                     errors++;
  426.                 }
  427.             }
  428.        
  429.  
  430.     |   READ_INT OP_PAR CL_PAR
  431.         {
  432.             $type = 'i' ;  
  433.             emit("invokestatic Runtime/readInt()I", 1);
  434.         }
  435.     | STRING
  436.         {
  437.             $type = 'a' ;
  438.             emit("ldc "+ $STRING.text, 1);
  439.         }
  440.     | READ_STR OP_PAR CL_PAR
  441.         {
  442.             $type = 'a' ;  
  443.             emit("invokestatic Runtime/readString()Ljava/lang/String;", 1);
  444.         }
  445.     | LEN OP_PAR VAR CL_PAR
  446.         {
  447.             $type = 'i';
  448.             emit("aload " + symbol_table.indexOf($VAR.text), 1);
  449.             emit("invokevirtual List/len()I", 0);
  450.         }
  451.  
  452.     | STR OP_PAR VAR CL_PAR
  453.         {
  454.             $type = 'a';
  455.             emit("aload " + symbol_table.indexOf($VAR.text), 1);
  456.             emit("invokevirtual List/str()Ljava/lang/String;", 0);
  457.         }
  458.     ;
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top