예제 #1
0
  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;
  }
예제 #2
0
  /**
   * Parse a factor.
   *
   * @param token the initial token.
   * @return the root of the generated parse subtree.
   * @throws Exception if an error occurred.
   */
  private ICodeNode parseFactor(Token token) throws Exception {
    TokenType tokenType = token.getType();
    ICodeNode rootNode = null;

    switch ((PascalTokenType) tokenType) {
      case IDENTIFIER:
        {
          return parseIdentifier(token);
        }

      case INTEGER:
        {
          // Create an INTEGER_CONSTANT node as the root node
          rootNode = ICodeFactory.createICodeNode(INTEGER_CONSTANT);
          rootNode.setAttribute(VALUE, token.getValue());

          token = nextToken(); // consume the number
          rootNode.setTypeSpec(Predefined.integerType);
          break;
        }

      case REAL:
        {
          // Create an REAL_CONSTANT node as the root node.
          rootNode = ICodeFactory.createICodeNode(REAL_CONSTANT);
          rootNode.setAttribute(VALUE, token.getValue());

          token = nextToken(); // consume the number

          rootNode.setTypeSpec(Predefined.realType);
          break;
        }

      case STRING:
        {
          String value = (String) token.getValue();

          // Create a STRING_CONSTANT node as the root node.
          rootNode = ICodeFactory.createICodeNode(STRING_CONSTANT);
          rootNode.setAttribute(VALUE, value);

          TypeSpec resultType =
              value.length() == 1 ? Predefined.charType : TypeFactory.createStringType(value);

          token = nextToken(); // consume the string
          rootNode.setTypeSpec(resultType);
          break;
        }

      case NOT:
        {
          token = nextToken(); // consume the NOT

          // Create a NOT node as the root node.
          rootNode = ICodeFactory.createICodeNode(ICodeNodeTypeImpl.NOT);

          // Parse the factor. The NOT node adopts the factor node as its child.
          ICodeNode factorNode = parseFactor(token);
          rootNode.addChild(factorNode);

          // Type check: the factor must be boolean.
          TypeSpec factorType =
              factorNode != null ? factorNode.getTypeSpec() : Predefined.undefinedType;
          if (!TypeChecker.isBoolean(factorType))
            errorHandler.flag(token, INCOMPATIBLE_TYPES, this);
          rootNode.setTypeSpec(Predefined.booleanType);
          break;
        }

      case LEFT_PAREN:
        {
          token = nextToken(); // consume the (

          // Parse an expression and make its node the root node.
          rootNode = parseExpression(token);
          TypeSpec resultType =
              rootNode != null ? rootNode.getTypeSpec() : Predefined.undefinedType;

          // Look for the matching ) token.
          token = currentToken();
          if (token.getType() == RIGHT_PAREN) token = nextToken(); // consume the )
          else errorHandler.flag(token, MISSING_RIGHT_PAREN, this);
          rootNode.setTypeSpec(resultType);
          break;
        }

      default:
        {
          errorHandler.flag(token, UNEXPECTED_TOKEN, this);
          break;
        }
    }
    return rootNode;
  }