function fromSymbolic( mask, expr ) {
	var digits;
	var parts;
	var perm;
	var who;
	var tmp;
	var idx;
	var op;
	var w;
	var o;
	var i;
	var j;
	var k;

	// Split the mask into octal digits (e.g., [ '0', '0', '7', '7' ]):
	digits = lpad( mask.toString( 8 ), 4, '0' ).split( '' );

	// Convert each octal digit to an integer value:
	for ( i = 0; i < digits.length; i++ ) {
		digits[ i ] = parseInt( digits[ i ], 10 );
	}

	// See if we can easily split the mask into separate mask expressions (e.g., `u+x,g=rw,o=` => [ 'u+x', 'g=rw', 'o=' ] ):
	parts = expr.split( ',' );

	// For each expression, split into "class", "operator", and "symbols" and update the mask octal digits:
	for ( i = 0; i < parts.length; i++ ) {
		tmp = parts[ i ].match( RE_MASK_EXPRESSION );
		if ( tmp === null ) {
			return new Error( format( 'invalid argument. Unable to parse mask expression. Ensure the expression is properly formatted, only uses the class letters "u", "g", "o", and "a", only uses the operators "+", "-", and "=", and only uses the permission symbols "r", "w", and "x". Value: `%s`.', expr ) );
		}
		// Extract the expression parts:
		who = tmp[ 1 ];
		if ( who === '' ) {
			// If a user class is not specified (e.g., `+x`), "ugo" (user, group, other) is implied...
			who = 'ugo';
		} else {
			// Replace `a` (all) user class letter with "ugo" (user, group, other) equivalent...
			w = '';
			for ( k = 0; k < who.length; k++ ) {
				if ( who[ k ] === 'a' ) {
					w += 'ugo';
				} else {
					w += who[ k ];
				}
			}
			who = w;
		}
		op = tmp[ 2 ];
		perm = tmp[ 3 ];

		// NOTE: the algorithm below is from the perspective of the mask. If implemented for, say, `chmod`, the "disabling"/"enabling" logic would be reversed. Recall that a "1" in the mask, serves to **disable** a permission setting, not enable.

		// Disable permissions...
		if ( op === '-' ) {
			if ( perm === '' ) {
				// The `-` operation by itself does not change any bits...
				continue;
			}
			for ( j = 0; j < perm.length; j++ ) {
				o = PERMS[ perm[j] ];
				for ( k = 0; k < who.length; k++ ) {
					idx = WHO[ who[k] ];
					digits[ idx ] = setBit( digits[ idx ], o ); // to disable, we flip on mask bits
				}
			}
		}
		// Enable permissions...
		else if ( op === '+' ) {
			if ( perm === '' ) {
				// The `+` operation by itself does not change any bits...
				continue;
			}
			for ( j = 0; j < perm.length; j++ ) {
				o = PERMS[ perm[j] ];
				for ( k = 0; k < who.length; k++ ) {
					idx = WHO[ who[k] ];
					digits[ idx ] = clearBit( digits[ idx ], o ); // to enable, we clear mask bits
				}
			}
		}
		// Disable all permissions by flipping on all permission mask bits...
		else if ( perm === '' ) { // op === '='
			for ( k = 0; k < who.length; k++ ) {
				idx = WHO[ who[k] ];
				digits[ idx ] = 7;
			}
		}
		// Explicitly set permissions...
		else { // op === '='
			// First, disable all permissions by flipping on all permission mask bits...
			for ( k = 0; k < who.length; k++ ) {
				idx = WHO[ who[k] ];
				digits[ idx ] = 7;
			}
			// Then, explicitly enable permissions by clearing mask bits...
			for ( j = 0; j < perm.length; j++ ) {
				o = PERMS[ perm[j] ];
				for ( k = 0; k < who.length; k++ ) {
					idx = WHO[ who[k] ];
					digits[ idx ] = clearBit( digits[ idx ], o );
				}
			}
		}
	}
	// Convert the digits to an integer value...
	for ( i = 0; i < digits.length; i++ ) {
		digits[ i ] = digits[ i ].toString();
	}
	return parseInt( digits.join( '' ), 8 );
}
Converts a mask expression in symbolic notation to an integer.

@private
@param {NonNegativeInteger} mask - current mask
@param {string} expr - mask expression
@returns {(NonNegativeInteger|Error)} integer mask or parse error