Пример #1
0
  /**
   * Parse an expression
   *
   * @param token the initial token.
   * @return the root of the generated parse subtree.
   * @throws Exception if an error occurred.
   */
  private ICodeNode parseExpression(Token token) throws Exception {
    // Parse a simple expression and make the root of its tree
    // the root node.
    ICodeNode rootNode = parseSimpleExpression(token);
    TypeSpec resultType = rootNode != null ? rootNode.getTypeSpec() : Predefined.undefinedType;

    token = currentToken();
    TokenType tokenType = token.getType();

    // Look for a relational operator.
    if (REL_OPS.contains(tokenType)) {
      // Create a new operator node and adopt the current tree as its first child
      ICodeNodeType nodeType = REL_OPS_MAP.get(tokenType);
      ICodeNode opNode = ICodeFactory.createICodeNode(nodeType);
      opNode.addChild(rootNode);

      token = nextToken(); // consume the operator

      // Parse the second simple expression.
      // The operator node adopts the simple expression's tree as its second child.
      ICodeNode simExprNode = parseSimpleExpression(token);
      opNode.addChild(simExprNode);

      // The operator node becomes the new root node.
      rootNode = opNode;

      // Type check: The operands must be comparison compatible.
      TypeSpec simExprType =
          simExprNode != null ? simExprNode.getTypeSpec() : Predefined.undefinedType;
      if (TypeChecker.areComparisionCompatible(resultType, simExprType))
        resultType = Predefined.booleanType;
      else {
        errorHandler.flag(token, INCOMPATIBLE_TYPES, this);
        resultType = Predefined.undefinedType;
      }
    }

    if (rootNode != null) rootNode.setTypeSpec(resultType);
    return rootNode;
  }