/** * Compile or interpret a Pascal source program. * * @param operation either "compile" or "execute". * @param filePath the source file path. * @param flags the command line flags. */ public Pascal(String operation, String sourcePath, String inputPath, String flags) { try { intermediate = flags.indexOf('i') > -1; xref = flags.indexOf('x') > -1; source = new Source(new BufferedReader(new FileReader(sourcePath))); source.addMessageListener(new SourceMessageListener()); parser = FrontendFactory.createParser("Pascal", "top-down", source); parser.addMessageListener(new ParserMessageListener()); backend = BackendFactory.createBackend(operation, inputPath); backend.addMessageListener(new BackendMessageListener()); parser.parse(); source.close(); if (parser.getErrorCount() == 0) { symTabStack = parser.getSymTabStack(); SymTabEntry programId = symTabStack.getProgramId(); iCode = (ICode) programId.getAttribute(ROUTINE_ICODE); if (xref) { CrossReferencer crossReferencer = new CrossReferencer(); crossReferencer.print(symTabStack); } if (intermediate) { ParseTreePrinter treePrinter = new ParseTreePrinter(System.out); treePrinter.print(symTabStack); } backend.process(iCode, symTabStack); } } catch (Exception ex) { System.out.println("***** Internal translator error. *****"); ex.printStackTrace(); } }
private ICodeNode parseIdentifier(Token token) throws Exception { ICodeNode rootNode = null; // Look up the identifier in the symbol table stack. // Flag the identifier as undefined if it's not found. String name = token.getText().toLowerCase(); SymTabEntry id = symTabStack.lookup(name); // Undefined. if (id == null) { errorHandler.flag(token, IDENTIFIER_UNDEFINED, this); id = symTabStack.enterLocal(name); id.setDefinition(UNDEFINED); id.setTypeSpec(Predefined.undefinedType); } Definition defnCode = id.getDefinition(); switch ((DefinitionImpl) defnCode) { case CONSTANT: { Object value = id.getAttribute(CONSTANT_VALUE); TypeSpec type = id.getTypeSpec(); if (value instanceof Integer) { rootNode = ICodeFactory.createICodeNode(INTEGER_CONSTANT); rootNode.setAttribute(VALUE, value); } else if (value instanceof Float) { rootNode = ICodeFactory.createICodeNode(REAL_CONSTANT); rootNode.setAttribute(VALUE, value); } else if (value instanceof String) { rootNode = ICodeFactory.createICodeNode(STRING_CONSTANT); rootNode.setAttribute(VALUE, value); } id.appendLineNumber(token.getLineNumber()); token = nextToken(); // consume the constant identifier if (rootNode != null) { rootNode.setTypeSpec(type); } break; } case ENUMERATION_CONSTANT: { Object value = id.getAttribute(CONSTANT_VALUE); TypeSpec type = id.getTypeSpec(); rootNode = ICodeFactory.createICodeNode(INTEGER_CONSTANT); rootNode.setAttribute(VALUE, value); id.appendLineNumber(token.getLineNumber()); token = nextToken(); // consume the enum constant identifier rootNode.setTypeSpec(type); break; } case FUNCTION: { CallParser callParser = new CallParser(this); rootNode = callParser.parse(token); break; } default: { VariableParser variableParser = new VariableParser(this); rootNode = variableParser.parse(token, id); break; } } return rootNode; }