コード例 #1
0
  /**
   * Create a jump table for a SELECT node.
   *
   * @param node the SELECT node.
   * @return the jump table.
   */
  private HashMap<Object, ICodeNode> createJumpTable(ICodeNode node) {
    HashMap<Object, ICodeNode> jumpTable = new HashMap<Object, ICodeNode>();

    // Loop over children that are SELECT_BRANCH nodes.
    ArrayList<ICodeNode> selectChildren = node.getChildren();
    for (int i = 1; i < selectChildren.size(); ++i) {
      ICodeNode branchNode = selectChildren.get(i);
      ICodeNode constantsNode = branchNode.getChildren().get(0);
      ICodeNode statementNode = branchNode.getChildren().get(1);

      // Loop over the constants children of the branch's CONSTANTS_NODE.
      ArrayList<ICodeNode> constantsList = constantsNode.getChildren();
      for (ICodeNode constantNode : constantsList) {

        // Create a jump table entry.
        // Convert a single-character string constant to a character.
        Object value = constantNode.getAttribute(VALUE);
        if (constantNode.getType() == STRING_CONSTANT) {
          value = ((String) value).charAt(0);
        }
        jumpTable.put(value, statementNode);
      }
    }

    return jumpTable;
  }
コード例 #2
0
  /**
   * Parse a set.
   *
   * @param token the initial token.
   * @return the root of the generated parse subtree.
   * @throws Exception if an error occurred.
   */
  private ICodeNode parseSet(Token token) throws Exception {
    ICodeNode rootNode = ICodeFactory.createICodeNode(ICodeNodeTypeImpl.SET);
    HashSet<Integer> values = new HashSet<>();
    rootNode.setAttribute(VALUE, new HashSet<Integer>());
    boolean isFinished = false;

    while (token.getType() != RIGHT_BRACKET && token.getType() != ERROR && !isFinished) {
      ICodeNode leftNode = parseSimpleExpression(token);

      if (leftNode.getType() == INTEGER_CONSTANT
          && !values.add((Integer) leftNode.getAttribute(VALUE))) {
        errorHandler.flag(token, NON_UNIQUE_MEMBERS, this);
      }

      token = currentToken();

      switch ((PascalTokenType) token.getType()) {
        case RIGHT_BRACKET:
          rootNode.addChild(leftNode);
          break;
        case COMMA:
          rootNode.addChild(leftNode);
          token = nextToken(); // Consume the ,
          if (token.getType() == COMMA) {
            errorHandler.flag(token, EXTRA_COMMAS, this);
            token = nextToken(); // Consume the extra ,
          }
          break;
        case DOT_DOT:
          token = nextToken(); // Consume the ..
          if (token.getType() == COMMA) {
            errorHandler.flag(token, INVALID_SUBRANGE, this);
            token = nextToken(); // Consume the ,
            rootNode.addChild(leftNode);
          } else {
            ICodeNode rightNode = parseSimpleExpression(token);
            ICodeNode subrangeNode = ICodeFactory.createICodeNode(SUBRANGE);
            subrangeNode.addChild(leftNode);
            subrangeNode.addChild(rightNode);
            rootNode.addChild(subrangeNode);

            if (leftNode.getType() == INTEGER_CONSTANT && rightNode.getType() == INTEGER_CONSTANT) {
              boolean duplicateFound = false;
              Integer leftRange = (Integer) leftNode.getAttribute(VALUE) + 1;
              Integer rightRange = (Integer) rightNode.getAttribute(VALUE);

              while (leftRange <= rightRange) {
                if (!values.add(leftRange++) && !duplicateFound) {
                  errorHandler.flag(token, NON_UNIQUE_MEMBERS, this);
                  duplicateFound = true;
                }
              }
            }

            token = currentToken();
            if (token.getType() == COMMA) {
              token = nextToken(); // Consume the ,
            } else if (token.getType() != RIGHT_BRACKET) {
              errorHandler.flag(token, MISSING_COMMA, this);
            }
          }
          break;

        case INTEGER:
          errorHandler.flag(token, MISSING_COMMA, this);
          break;

        case SEMICOLON:
          isFinished = true;
          break;

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

    return rootNode;
  }