예제 #1
0
pfs::error_code ubjson_ostream<OStreamType, JsonType>::write_string (string_type const & s, bool with_prefix)
{
    if (with_prefix) {
        // Using size is safe here (no matter the string encoding)
        if (s.size() == 1 && *s.cbegin() <= numeric_limits<int8_t>::max()) {
            _os << static_cast<int8_t>('C');
            _os << static_cast<int8_t>(*s.cbegin());
        } else {
            _os << static_cast<int8_t>('S');
            write_integer(static_cast<typename json_type::integer_type>(s.size()), true);
            _os << s.utf8();
        }
    } else {
        write_integer(static_cast<typename json_type::integer_type>(s.size()), true);
        _os << s;
    }

    return pfs::error_code();
}
/** Tokenize the expression.
	@return a TokenList containing the tokens from 'expression'. 
	@param expression [in] The expression to tokenize.
	@note Tokenizer dictionary may be updated if expression contains variables.
	@note Will throws 'BadCharacter' if the expression contains an un-tokenizable character.
	*/
TokenList Tokenizer::tokenize( string_type const& expression ) {
	TokenList tokenizedExpression;
	auto currentChar = expression.cbegin();

	for(;;) 
	{
		// strip whitespace
		while( currentChar != end(expression) && isspace(*currentChar) )
			++currentChar;

		// check of end of expression
		if( currentChar == end(expression) ) break;

		// check for a number
		if( isdigit( *currentChar ) ) {
			tokenizedExpression.push_back( _get_number( currentChar, expression ) );
			continue;
		}
		//check if left parenthesis
		if (*currentChar == '(') {
			tokenizedExpression.push_back(make<LeftParenthesis>());
			++currentChar;
			continue;
		}
		//check if right parenthesis
		if (*currentChar == ')') {
			tokenizedExpression.push_back(make<RightParenthesis>());
			++currentChar;
			continue;
		}
		//check if multiplication 
		if (*currentChar == '*') {
			tokenizedExpression.push_back(make<Multiplication>());
			++currentChar;
			continue;
		}
		//check if division
		if (*currentChar == '/') {
			tokenizedExpression.push_back(make<Division>());
			++currentChar;
			continue;
		}
		//chck if argument seperator
		if (*currentChar == ',') {
			tokenizedExpression.push_back(make<ArgumentSeparator>());
			++currentChar;
			continue;
		}
		//check for factorial or inequality operator
		if (*currentChar == '!') {
			if (next(currentChar) != end(expression)) {
				if (*next(currentChar) == '=') { //if next character is =, make inequality operator
					tokenizedExpression.push_back(make<Inequality>());
					currentChar++;
					currentChar++;
					continue;
				}
			}
			//if is not inequality operator, must be factorial operator
			tokenizedExpression.push_back(make<Factorial>());
			currentChar++;
			continue;
		}
		//check for addition or identity operator
		if (*currentChar == '+') {
			++currentChar;
			if (!tokenizedExpression.empty()) {
				if (is<RightParenthesis>(tokenizedExpression.back()) || is<Operand>(tokenizedExpression.back()) || is<Factorial>(tokenizedExpression.back())) {
					//if + relates to another token, must be an addition operator
					tokenizedExpression.push_back(make<Addition>()); 
				}
				else { //is an identity operator
					tokenizedExpression.push_back(make<Identity>());
				}
			}
			else { //in an empty expression must be identity operator
				tokenizedExpression.push_back(make<Identity>());
			}
			continue;
		}
		//check for subtraction or negatino operator
		if (*currentChar == '-') {
			++currentChar;
			if (!tokenizedExpression.empty()) {
				if (is<RightParenthesis>(tokenizedExpression.back()) || is<Operand>(tokenizedExpression.back()) || is<Factorial>(tokenizedExpression.back())) {
					tokenizedExpression.push_back(make<Subtraction>()); // same as addition, if related to operand, is subtraction
				}
				else {
					tokenizedExpression.push_back(make<Negation>()); //must be negation
				}
			}
			else {//empty expression, must be negation operator
				tokenizedExpression.push_back(make<Negation>());
			}
			continue;
		}
		//check if power operator
		if (*currentChar == '#') {
			tokenizedExpression.push_back(make<Power>());
			currentChar++;
			continue;
		}
		//Check if modulus division operator
		if (*currentChar == '%') {
			tokenizedExpression.push_back(make<Modulus>());
			currentChar++;
			continue;
		}
		//check for equality or assignment operator
		if (*currentChar == '=') {
			if (next(currentChar) != end(expression)) {
				//if next character is another =, must be equality operator
				if (*next(currentChar) == '=') {
					tokenizedExpression.push_back(make<Equality>());
					currentChar++;
					currentChar++;
					continue;
				}
			}
			//if single =, is assignment operator
			tokenizedExpression.push_back(make<Assignment>());
			currentChar++;
			continue;
		}
		//check less than or less equal operator 
		if (*currentChar == '<') {
			if (next(currentChar) != end(expression)) {
				//if next character is =, make LessEqual operator
				if (*next(currentChar) == '=') {
					tokenizedExpression.push_back(make<LessEqual>());
					currentChar++;
					currentChar++;
					continue;
				}
			}
			//if no =, is less equal operator
			tokenizedExpression.push_back(make<Less>());
			currentChar++;
			continue;
		}
		
		//check for greater than or greater equals operator
		if (*currentChar == '>') {
			if (next(currentChar) != end(expression)) {
				//if next character is =, is greater equals operator
				if (*next(currentChar) == '=') {
					tokenizedExpression.push_back(make<GreaterEqual>());
					currentChar++;
					currentChar++;
					continue;
				}
			}
			//if lone >, mkae greater than operator
			tokenizedExpression.push_back(make<Greater>());
			currentChar++;
			continue;
		}

		//is an identifier or variable
		if (isalpha(*currentChar)) {
			tokenizedExpression.push_back(_get_identifier(currentChar, expression));
			continue;
		}

		// not a recognized token
		throw XBadCharacter( expression, currentChar - begin(expression) );
	}

	return tokenizedExpression;
}