Traductor e intérprete del lenguaje CL 1.23
CL.java
Go to the documentation of this file.
00001 
00186 import java.util.List;
00187 import org.antlr.runtime.*;
00188 import org.antlr.runtime.tree.*;
00189 import org.antlr.stringtemplate.*;
00190 import java.io.*;
00191 
00268 public class CL {
00269 
00273     private static final int DEFAULT_LAST_STEP = 8;
00274 
00278     public static void main(String[] args) throws Exception, RecognitionException {
00279         ANTLRStringStream input     = new ANTLRStringStream();
00280         int               last_step = DEFAULT_LAST_STEP;
00281 
00282         // En primer lugar se determina de donde se lee el
00283         // programa de entrada y en que; paso se detiene el
00284         // traductor/interprete.
00285         if (args.length == 0) {         // sin argumentos en args
00286             last_step = DEFAULT_LAST_STEP;
00287             input     = new ANTLRInputStream(System.in);
00288         } else if (args.length == 1) {  // un solo argumento en args
00289             if (args[0].startsWith("-")) {
00290                 last_step = Integer.parseInt(args[0].substring(1, args[0].length()));
00291                 input     = new ANTLRInputStream(System.in);
00292             } else {
00293                 last_step = DEFAULT_LAST_STEP;
00294                 input     = new ANTLRFileStream(args[0]);
00295             }
00296         } else if (args.length == 2) {  // dos argumentos en args
00297             last_step = Integer.parseInt(args[0].substring(1, args[0].length()));
00298             input     = new ANTLRFileStream(args[1]);
00299         } else {                        // numero incorrecto de argumentos en args
00300             System.out.println("Usage: java CL [-<step>] [<file>]");
00301             System.out.println("       with <step> in 1..11\t(default = " + DEFAULT_LAST_STEP + ")");
00302             System.exit(1);
00303         }
00304 
00305         // Se declara el lexer y otras las variables necesarias
00306         // para crear correctamente el parser, y se le especifica
00307         // como son los arboles que construira.
00308         CLLexer           lexer  = new CLLexer(input);
00309         CommonTokenStream tokens = new CommonTokenStream(lexer);
00310         CLParser          parser = new CLParser(tokens);
00311 
00312         parser.setTreeAdaptor(new CL_AST_Adaptor());
00313 
00314         List<RecognitionException> recognitionExceptions;
00315 
00316         // Se llama al parser y se obtiene el AST construido.
00317         CLParser.program_return ret = parser.program();
00318 
00319         CL_AST ast = (CL_AST) ret.getTree();
00320 
00321         // Se comprueban los errores lexicos.
00322         recognitionExceptions = lexer.getExceptions();
00323         if (recognitionExceptions.size() > 0) {
00324             System.out.println("Lexer threw exceptions -- see output");
00325             System.exit(1);
00326         }
00327 
00328         // Se comprueban los errores sintacticos.
00329         recognitionExceptions = parser.getExceptions();
00330         if (recognitionExceptions.size() > 0) {
00331             System.out.println("Parser threw exceptions -- see output");
00332             System.exit(1);
00333         }
00334 
00335         if (last_step == 1 || last_step == 2) {
00336             System.exit(0);
00337         }
00338 
00339         // Se escribe el AST tanto en formato multilinea
00340         // con tabulacion como en formato DOT para que mas tarde
00341         // pueda verse como un grafico.
00342         // // System.out.println(ast.toStringTree());
00343         if (last_step == 3) {
00344             System.out.print(CL_AST.toIndentedTreeString(ast));
00345             DOTTreeGenerator gen    = new DOTTreeGenerator();
00346             StringTemplate st       = gen.toDOT(ast);
00347             FileWriter outputStream = new FileWriter("ast.dot");
00348             outputStream.write(st.toString());
00349             outputStream.close();
00350             System.exit(0);
00351         }
00352 
00353         // Se declaran las variables necesarias para crear
00354         // correctamente el typeCheck especificandole
00355         // la tabla de simbolos que usara (inicialmente vacia).
00356         CommonTreeNodeStream nodes     = new CommonTreeNodeStream(ast);
00357         SymTab               symtab    = new SymTab();
00358         TypeCheck            typeCheck = new TypeCheck(nodes, symtab);
00359 
00360         // Se llama al analisis semantico typeCheck.
00361         typeCheck.program();
00362 
00363         // Se comprueban los errores de no reconocimiento del AST.
00364         recognitionExceptions = typeCheck.getExceptions();
00365         if (recognitionExceptions.size() > 0) {
00366             System.out.println("Tree parser 'TypeCheck' threw exceptions -- see output");
00367             System.exit(1);
00368         }
00369 
00370         if (last_step == 4) {
00371             System.exit(0);
00372         }
00373 
00374         // Se vuelve a escribir el AST en formato multilinea con
00375         // tabulacion. Ahora se visualizara tambien su decoracion.
00376         if (last_step == 5) {
00377             System.out.print(CL_AST.toIndentedTreeString(ast));
00378             System.exit(0);
00379         }
00380 
00381         // Se obtienen y, si existen, se escriben los errores semanticos.
00382         SemanticErrors errors = typeCheck.getSemanticErrors();
00383 
00384         if (typeCheck.getNumberOfSemanticErrors() > 0 && last_step == 6) {
00385             System.out.print(errors.toString());
00386             System.exit(0);
00387         }
00388 
00389         if (last_step == 6) {
00390             System.exit(0);
00391         }
00392 
00393         // Si existen errores semanticos se detiene la compilacion
00394         // aunque se haya pedido llegar hasta un paso posterior.
00395         if (typeCheck.getNumberOfSemanticErrors() > 0) {
00396             System.out.print(errors.toString());
00397             System.out.println("Type checking: " + typeCheck.getNumberOfSemanticErrors() + " semantic errors has been found.");
00398             System.exit(0);
00399         }
00400 
00401         // Se declaran las variables necesarias para crear
00402         // correctamente el codeGen especificandole
00403         // la tabla de simbolos y la biblioteca
00404         // de templates que usara. Se usa el mismo NodeStream
00405         // que en el typeCheck pero se hace un reset para
00406         // situarse otra vez en la raiz del AST.
00407 
00408         // load the group file CodeGen.stg, put in templates var
00409         FileReader groupFileR         = new FileReader("CodeGen.stg");
00410         StringTemplateGroup templates = new StringTemplateGroup(groupFileR);
00411         groupFileR.close();
00412 
00413         nodes.reset();  // NodeStream will be revisited
00414         CodeGen codeGen = new CodeGen(nodes, symtab);
00415 
00416         codeGen.setTemplateLib(templates);  // where to find templates
00417 
00418         // Se llama al generador de codigo codeGen y se obtiene
00419         // el template con el t-codigo generado.
00420         CodeGen.program_return ret2 = codeGen.program();
00421 
00422         StringTemplate output       = (StringTemplate) ret2.getTemplate();
00423 
00424         // Se comprueban los errores de no reconocimiento del AST.
00425         recognitionExceptions = codeGen.getExceptions();
00426         if (recognitionExceptions.size() > 0) {
00427             System.out.println("Tree parser 'CodeGen' threw exceptions -- see output");
00428             System.exit(1);
00429         }
00430 
00431         if (last_step == 7) {
00432             System.exit(0);
00433         }
00434 
00435         // Se transforma el template en texto, y se hacen algunos
00436         // cambios para que quede visualmente mejor.
00437         String         myTCode       = output.toString();  // render full template
00438         String myTCodeWoutBlankLines = myTCode.replaceAll("\n[\n]+","\n").replaceAll("\nsubroutine","\n\nsubroutine");
00439 
00440         // Se escribe el t-codigo generado.
00441         if (last_step == 8) {
00442             // Emit Codegen
00443             // get template from return values struct
00444             System.out.print(myTCodeWoutBlankLines);
00445             System.exit(0);
00446         }
00447 
00448         // Comienza el interprete que tiene dos partes
00449         //    (1) analisis lexico y sintactico del t-codigo
00450         //    (2) analisis semantico del t-codigo
00451         //    (3) ejecucion del t-codigo
00452         // Se declaran las variables necesarias para crear
00453         // correctamente el lexer y el parser del t-codigo.
00454         ANTLRStringStream tcodeInput  = new ANTLRStringStream(myTCodeWoutBlankLines);
00455         TCodeLexer        tcodeLexer  = new TCodeLexer(tcodeInput);
00456         CommonTokenStream tcodeTokens = new CommonTokenStream(tcodeLexer);
00457         TCodeParser       tcodeParser = new TCodeParser(tcodeTokens);
00458 
00459         // Se llama al parser de t-codigo.
00460         tcodeParser.program();
00461 
00462         // Se comprueban los errores lexico/sintacticos del t-codigo.
00463         recognitionExceptions = tcodeParser.getExceptions();
00464         if (recognitionExceptions.size() > 0) {
00465             System.out.println("Parser 'TCodeParser' threw exceptions -- see output");
00466             System.exit(1);
00467         }
00468 
00469         if (last_step == 9) {
00470             System.exit(0);
00471         }
00472 
00473         // Se obtiene la representacion del t-codigo generada
00474         // por el parser.
00475         TCode  tcode   = tcodeParser.getTCode();
00476 
00477         // Se obtienen y, si existen, se escriben los errores semanticos.
00478         TCodeSemanticErrors tcErrors = tcode.getSemanticErrors();
00479 
00480         if (tcErrors.getNumberOfSemanticErrors() > 0 && last_step == 10) {
00481             System.out.print(tcErrors.toString());
00482             System.exit(0);
00483         }
00484 
00485         if (last_step == 10) {
00486             System.exit(0);
00487         }
00488 
00489         // Si existen errores semanticos se detiene la compilacion
00490         // aunque se haya pedido llegar hasta un paso posterior.
00491         if (tcErrors.getNumberOfSemanticErrors() > 0) {
00492             System.out.println("The TCode generated has " + tcErrors.getNumberOfSemanticErrors() + " semantic errors:");
00493             System.out.print(tcErrors.toString());
00494             System.exit(0);
00495         }
00496 
00497         // A continuacion se ejecuta usando el metodo run() que
00498         // devuelve un string con los resultados, y finalmente
00499         // estos se escriben.
00500         String results = tcode.run();
00501         System.out.print(results);
00502     }
00503 
00504 }
 All Classes Files Functions Variables Enumerations