private ICodeNode parseConstant(Token token, TypeSpec expressionType,
                                    HashSet<Object> constantSet)
        throws Exception
    {
        TokenType sign = null;
        ICodeNode constantNode = null;
        TypeSpec constantType = null;

        // Synchronize at the start of a constant.
        token = synchronize(CONSTANT_START_SET);
        TokenType tokenType = token.getType();

        // Plus or minus sign?
        if ((tokenType == PLUS) || (tokenType == MINUS)) {
            sign = tokenType;
            token = nextToken();  // consume sign
        }

        // Parse the constant.
        switch ((PascalTokenType) token.getType()) {

            case IDENTIFIER: {
                constantNode = parseIdentifierConstant(token, sign);
                if (constantNode != null) {
                    constantType = constantNode.getTypeSpec();
                }

                break;
            }

            case INTEGER: {
                constantNode = parseIntegerConstant(token.getText(), sign);
                constantType = Predefined.integerType;
                break;
            }

            case STRING: {
                constantNode =
                    parseCharacterConstant(token, (String) token.getValue(),
                                           sign);
                constantType = Predefined.charType;
                break;
            }

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

        // Check for reused constants.
        if (constantNode != null) {
            Object value = constantNode.getAttribute(VALUE);

            if (constantSet.contains(value)) {
                errorHandler.flag(token, CASE_CONSTANT_REUSED, this);
            }
            else {
                constantSet.add(value);
            }
        }

        // Type check: The constant type must be comparison compatible
        //             with the CASE expression type.
        if (!TypeChecker.areComparisonCompatible(expressionType,
                                                 constantType)) {
            errorHandler.flag(token, INCOMPATIBLE_TYPES, this);
        }

        token = nextToken();  // consume the constant

        constantNode.setTypeSpec(constantType);
        return constantNode;
    }