示例#1
0
uint64
ExpressionParser::_ParseProduct()
{
	uint64 value = _ParseUnary();

	while (true) {
		Token token = fTokenizer.NextToken();
		switch (token.type) {
			case TOKEN_STAR:
				value = value * _ParseUnary();
				break;
			case TOKEN_SLASH: {
				uint64 rhs = _ParseUnary();
				if (rhs == 0)
					parse_exception("division by zero", token.position);
				value = value / rhs;
				break;
			}
			case TOKEN_MODULO: {
				uint64 rhs = _ParseUnary();
				if (rhs == 0)
					parse_exception("modulo by zero", token.position);
				value = value % rhs;
				break;
			}

			default:
				fTokenizer.RewindToken();
				return value;
		}
	}
}
示例#2
0
uint64
ExpressionParser::_ParseDereference(void** _address, uint32* _size)
{
	int32 starPosition = fTokenizer.CurrentToken().position;

	// optional "{ ... }" specifying the size to read
	uint64 size = 4;
	if (fTokenizer.NextToken().type == TOKEN_OPENING_BRACE) {
		int32 position = fTokenizer.CurrentToken().position;
		size = _ParseExpression();

		if (size != 1 && size != 2 && size != 4 && size != 8) {
			snprintf(sTempBuffer, sizeof(sTempBuffer),
				"invalid size (%" B_PRIu64 ") for unary * operator", size);
			parse_exception(sTempBuffer, position);
		}

		_EatToken(TOKEN_CLOSING_BRACE);
	} else
		fTokenizer.RewindToken();

	const void* address = (const void*)(addr_t)_ParseUnary();

	// read bytes from address into a tempory buffer
	uint64 buffer;
	if (debug_memcpy(B_CURRENT_TEAM, &buffer, address, size) != B_OK) {
		snprintf(sTempBuffer, sizeof(sTempBuffer),
			"failed to dereference address %p", address);
		parse_exception(sTempBuffer, starPosition);
	}

	// convert the value to uint64
	uint64 value = 0;
	switch (size) {
		case 1:
			value = *(uint8*)&buffer;
			break;
		case 2:
			value = *(uint16*)&buffer;
			break;
		case 4:
			value = *(uint32*)&buffer;
			break;
		case 8:
			value = buffer;
			break;
	}

	if (_address != NULL)
		*_address = (void*)address;
	if (_size != NULL)
		*_size = size;

	return value;
}
示例#3
0
void
ExpressionParser::_ParseCommand(debugger_command_pipe_segment& segment)
{
	fTokenizer.SetCommandMode(false);
	const Token& token = _EatToken(TOKEN_IDENTIFIER);
	fTokenizer.SetCommandMode(true);

	bool ambiguous;
	debugger_command* command = find_debugger_command(token.string, true,
		ambiguous);

	if (command == NULL) {
		if (ambiguous) {
			snprintf(sTempBuffer, sizeof(sTempBuffer),
				"Ambiguous command \"%s\". Use tab completion or enter "
				"\"help %s\" get a list of matching commands.\n", token.string,
				token.string);
		} else {
			snprintf(sTempBuffer, sizeof(sTempBuffer),
				"Unknown command \"%s\". Enter \"help\" to get a list of "
				"all supported commands.\n", token.string);
		}

		parse_exception(sTempBuffer, -1);
	}

	// allocate temporary buffer for the argument vector
	char** argv = (char**)checked_malloc(kMaxArgumentCount * sizeof(char*));
	int argc = 0;
	argv[argc++] = (char*)command->name;

	// get the arguments
	if ((command->flags & B_KDEBUG_DONT_PARSE_ARGUMENTS) != 0) {
		_GetUnparsedArgument(argc, argv);
	} else {
		while (fTokenizer.NextToken().type != TOKEN_END_OF_LINE) {
			fTokenizer.RewindToken();
			if (!_ParseArgument(argc, argv))
				break;
		}
	}

	if (segment.index > 0) {
		if (argc >= kMaxArgumentCount)
			parse_exception("too many arguments for command", 0);
		else
			argc++;
	}

	segment.command = command;
	segment.argc = argc;
	segment.argv = argv;
	segment.invocations = 0;
}
示例#4
0
uint64
ExpressionParser::EvaluateCommand(const char* expressionString, int& returnCode)
{
	fTokenizer.SetTo(expressionString);

	// Allowed are command or assignment. A command always starts with an
	// identifier, an assignment either with an identifier (variable name) or
	// a dereferenced address.
	const Token& token = fTokenizer.NextToken();
	uint64 value = 0;

	while (true) {
		int32 startPosition = token.position;

		if (token.type == TOKEN_IDENTIFIER) {
			fTokenizer.NextToken();

			if (token.type & TOKEN_ASSIGN_FLAG) {
				// an assignment
				fTokenizer.SetPosition(startPosition);
				value =  _ParseExpression(true);
				returnCode = 0;
			} else {
				// no assignment, so let's assume it's a command
				fTokenizer.SetPosition(startPosition);
				fTokenizer.SetCommandMode(true);
				value = _ParseCommandPipe(returnCode);
			}
		} else if (token.type == TOKEN_STAR) {
			// dereferenced address -- assignment
			fTokenizer.SetPosition(startPosition);
			value =  _ParseExpression(true);
			returnCode = 0;
		} else
			parse_exception("expected command or assignment", token.position);

		// might be chained with ";"
		if (fTokenizer.NextToken().type != TOKEN_SEMICOLON)
			break;

		fTokenizer.SetCommandMode(false);
		fTokenizer.NextToken();
	}

	if (token.type != TOKEN_END_OF_LINE)
		parse_exception("parse error", token.position);

	return value;
}
示例#5
0
//string
big_integer::big_integer(std::string const& str) {
    if (str == "" || str == "0") {
        *this = big_integer();
    }
    else {
        std::string temp = str;
        int cut = 0;
        if (temp.at(0) == '-')
            cut = 1;
        while (temp.at(cut) == '0' && cut < temp.size() - 1)
            temp.erase(cut, cut);
        if (temp == "0" || temp == "-0" || temp == "") {
            *this = big_integer();
            return;
        }
        std::reverse(temp.begin(), temp.end());
        for (int i = 0; i < temp.size() - 1; ++i) {
            if (!isdigit(temp[i])) {
                throw parse_exception("Illegal character");
            }
            this->digits.push_back(temp[i] - 48);
        }
        if (temp[temp.size() - 1] == '-') {
            sign = -1;
        }
        else {
            sign = 1;
            this->digits.push_back(temp[temp.size() - 1] - 48);
        }
    }
};
示例#6
0
 T read(const std::string& source, size_t& pos) {
   T result = readOptional<T>(source, pos);
   if(result == T::none)
     throw parse_exception(string("Expected token of type: ").append(typeid(T).name()), pos);
   else
     return result;
 }
示例#7
0
void RecordParser::parse(const unsigned char * content, int content_size, RecordParseListener &listener) {
    ContentBuffer reader(content, content_size);
    reader.prepare(1);
    if (reader.content[reader.cursor] != 0)
        throw parse_exception("unsupported version");
    readDocument(reader, listener);
}
示例#8
0
size_t reader<size_t>::read(Serializer& s) {
    size_t val = 0;
    size_t offs = 0;
    if (s.offset >= s.buffer->size())
        throw parse_exception("buffer underrun");
    while ((*s.buffer)[s.offset] & 0x80) {
        val |= ((size_t)(*s.buffer)[s.offset] & 0x7F) << offs;
        offs += 7;
        s.offset++;
        if (s.offset >= s.buffer->size())
            throw parse_exception("buffer underrun");
    }
    val |= (*s.buffer)[s.offset] << offs;
    s.offset++;
    return val;
}
示例#9
0
uint64
ExpressionParser::_ParseCommandPipe(int& returnCode)
{
	debugger_command_pipe* pipe = (debugger_command_pipe*)checked_malloc(
		sizeof(debugger_command_pipe));

	pipe->segment_count = 0;
	pipe->broken = false;

	do {
		if (pipe->segment_count >= MAX_DEBUGGER_COMMAND_PIPE_LENGTH)
			parse_exception("Pipe too long", fTokenizer.NextToken().position);

		debugger_command_pipe_segment& segment
			= pipe->segments[pipe->segment_count];
		segment.index = pipe->segment_count++;

		_ParseCommand(segment);

	} while (fTokenizer.NextToken().type == TOKEN_PIPE);

	fTokenizer.RewindToken();

	// invoke the pipe
	returnCode = invoke_debugger_command_pipe(pipe);

	debug_free(pipe);

	return get_debug_variable("_", 0);
}
示例#10
0
std::string reader<std::string>::read(Serializer& s) {
    size_t length = reader<size_t>::read(s);
    size_t offs = s.offset;
    s.offset += length;
    if (s.offset > s.buffer->size())
        throw parse_exception("buffer underrun");
    return std::string((const char *)s.buffer->data()+offs, length);
}
示例#11
0
long
parse_long_str(const std::string& s) {
    const char* s2(s.c_str());
    const long val(parse_long(s2));
    if ((s2-s.c_str())!=static_cast<int>(s.length())) {
        parse_exception("long int",s.c_str());
    }
    return val;
}
示例#12
0
unsigned
parse_unsigned_str(const std::string& s) {
    const char* s2(s.c_str());
    const unsigned val(parse_unsigned(s2));
    if ((s2-s.c_str())!=static_cast<int>(s.length())) {
        parse_exception("unsigned",s.c_str());
    }
    return val;
}
示例#13
0
size_t Defines::match(const std::string& define, const std::string& source, size_t pos) {
  regex r(define);
  smatch mres;
  if (regex_search(source.begin()+pos, source.end(), mres, r, regex_constants::match_continuous)) {
    return mres.length();
  } else {
    throw parse_exception("pattern /" + define + "/ didn't match", pos);
  }
}
示例#14
0
int
parse_int_str(const std::string& s) {
    const char* s2(s.c_str());
    const int val(parse_int(s2));
    if ((s2-s.c_str())!=static_cast<int>(s.length())) {
        parse_exception("int",s.c_str());
    }
    return val;
}
示例#15
0
unique_ptr<Grammar> Parser::parse(std::istream& source) {
  std::string content((istreambuf_iterator<char>(source)), istreambuf_iterator<char>());
  size_t pos = 0;
  try {
    auto result = Parser::consume<Grammar>(content, pos);
    if(pos < content.length())
      throw parse_exception("Grammar couldn't parse complete input. Some characters are left.", pos);

    return result;
  } catch (parse_exception& e) {
    auto start = content.cbegin() + e.pos;
    auto snippetLength = std::min(std::distance(start, content.cend()), 200);
    string context = "Grammar parse failed near:\n";
    context.append(start, start + snippetLength);
    throw parse_exception(e, context);    
  }
  
}
示例#16
0
double
parse_double_str(const std::string& s) {
    const char* s2(s.c_str());
    const double val(parse_double(s2));
    if ((s2-s.c_str())!=static_cast<int>(s.length())) {
        parse_exception("double",s.c_str());
    }
    return val;
}
示例#17
0
unique_ptr<T> Parser::consume(const std::string& source, size_t& pos) {
  size_t localPos = pos;
  try {
    auto result = T::build(source, localPos); //if this throws an exception, pos doesn't get changed and the exception propagates upwards
    pos = localPos; //No exception, so update position
    return result;
  } catch (parse_exception& e) {
    throw parse_exception(e, string("when trying to consume ").append(typeid(T).name()));
  }
}
示例#18
0
uint64
ExpressionParser::_ParseAtom()
{
	const Token& token = fTokenizer.NextToken();
	if (token.type == TOKEN_END_OF_LINE)
		parse_exception("unexpected end of expression", token.position);

	if (token.type == TOKEN_CONSTANT)
		return token.value;

	if (token.type == TOKEN_IDENTIFIER) {
		if (!is_debug_variable_defined(token.string)) {
			snprintf(sTempBuffer, sizeof(sTempBuffer),
				"variable '%s' undefined", token.string);
			parse_exception(sTempBuffer, token.position);
		}

		return get_debug_variable(token.string, 0);
	}

	if (token.type == TOKEN_OPENING_PARENTHESIS) {
		uint64 value = _ParseExpression();

		_EatToken(TOKEN_CLOSING_PARENTHESIS);

		return value;
	}

	// it can only be a "[ command ]" expression now
	fTokenizer.RewindToken();

	_EatToken(TOKEN_OPENING_BRACKET);

	fTokenizer.SetCommandMode(true);
	int returnValue;
	uint64 value = _ParseCommandPipe(returnValue);
	fTokenizer.SetCommandMode(false);

	_EatToken(TOKEN_CLOSING_BRACKET);

	return value;
}
示例#19
0
static void*
checked_malloc(size_t size)
{
	void* address = debug_malloc(size);
	if (address == NULL) {
		parse_exception("out of memory for command execution", -1);
		return NULL;
	}

	return address;
}
示例#20
0
double
parse_double_str(
    const std::string& s)
{
    const char* s2(s.c_str());
    const char* const s2_end(s2+s.size());
    const double val(parse_double(s2,s2_end));
    if (s2 != s2_end) {
        parse_exception("double",s.c_str());
    }
    return val;
}
示例#21
0
uint64
ExpressionParser::EvaluateExpression(const char* expressionString)
{
	fTokenizer.SetTo(expressionString);

	uint64 value = _ParseExpression();
	const Token& token = fTokenizer.NextToken();
	if (token.type != TOKEN_END_OF_LINE)
		parse_exception("parse error", token.position);

	return value;
}
示例#22
0
const Token&
ExpressionParser::_EatToken(int32 type)
{
	const Token& token = fTokenizer.NextToken();
	if (token.type != type) {
		snprintf(sTempBuffer, sizeof(sTempBuffer), "expected token type '%c', "
			"got token '%s'", char(type & ~TOKEN_FLAGS), token.string);
		parse_exception(sTempBuffer, token.position);
	}

	return token;
}
示例#23
0
	const Token& _QuotedString()
	{
		const char* begin = fCurrentChar++;
		int32 length = 0;

		while (*fCurrentChar != '\0' && *fCurrentChar != '"') {
			char c = *fCurrentChar;
			fCurrentChar++;

			if (c == '\\') {
				// an escaped char
				c = *fCurrentChar;
				fCurrentChar++;

				if (c == '\0')
					break;
			}

			if ((size_t)length
					>= sizeof(fCurrentToken.string) - 1) {
				parse_exception("quoted string too long", begin - fString);
			}

			fCurrentToken.string[length++] = c;
		}

		if (*fCurrentChar == '\0') {
			parse_exception("unexpected end of line while "
				"parsing quoted string", begin - fString);
		}

		fCurrentChar++;

		fCurrentToken.string[length] = '\0';
		fCurrentToken.value = 0;
		fCurrentToken.type = TOKEN_STRING;
		fCurrentToken.position = begin - fString;

		return fCurrentToken;
	}
示例#24
0
bool
ExpressionParser::_ParseArgument(int& argc, char** argv)
{
	const Token& token = fTokenizer.NextToken();
	switch (token.type) {
		case TOKEN_OPENING_PARENTHESIS:
		{
			// this starts an expression
			fTokenizer.SetCommandMode(false);
			uint64 value = _ParseExpression();
			fTokenizer.SetCommandMode(true);
			_EatToken(TOKEN_CLOSING_PARENTHESIS);

			snprintf(sTempBuffer, sizeof(sTempBuffer), "%" B_PRIu64, value);
			_AddArgument(argc, argv, sTempBuffer);
			return true;
		}

		case TOKEN_OPENING_BRACKET:
		{
			// this starts a sub command
			int returnValue;
			uint64 value = _ParseCommandPipe(returnValue);
			_EatToken(TOKEN_CLOSING_BRACKET);

			snprintf(sTempBuffer, sizeof(sTempBuffer), "%" B_PRIu64, value);
			_AddArgument(argc, argv, sTempBuffer);
			return true;
		}

		case TOKEN_STRING:
		case TOKEN_UNKNOWN:
			_AddArgument(argc, argv, token.string);
			return true;

		case TOKEN_CLOSING_PARENTHESIS:
		case TOKEN_CLOSING_BRACKET:
		case TOKEN_PIPE:
		case TOKEN_SEMICOLON:
			// those don't belong to us
			fTokenizer.RewindToken();
			return false;

		default:
		{
			snprintf(sTempBuffer, sizeof(sTempBuffer), "unexpected token "
				"\"%s\"", token.string);
			parse_exception(sTempBuffer, token.position);
			return false;
		}
	}
}
示例#25
0
unsigned
parse_unsigned(const char*& s) {

    static const int base(10);

    errno = 0;

    char* endptr;
    const unsigned long val(strtoul(s, &endptr, base));
    if ((errno == ERANGE && (val == ULONG_MAX || val == 0))
        || (errno != 0 && val == 0) || (endptr == s)) {
        parse_exception("unsigned long",s);
    }

    if (val > std::numeric_limits<unsigned>::max()) {
        parse_exception("unsigned",s);
    }

    s = endptr;

    return static_cast<unsigned>(val);
}
示例#26
0
int
parse_int(const char*& s) {

    const char* endptr(s);
    const long val(parse_long(endptr));

    if (val > std::numeric_limits<int>::max()) {
        parse_exception("int",s);
    }

    s = endptr;

    return static_cast<int>(val);
}
示例#27
0
double
parse_double(const char*& s) {

    errno = 0;

    char* endptr;
    const double val(strtod(s, &endptr));
    if ((errno == ERANGE) || (endptr == s)) {
        parse_exception("double",s);
    }

    s = endptr;
    return val;
}
示例#28
0
void
ExpressionParser::_AddArgument(int& argc, char** argv, const char* argument,
	int32 length)
{
	if (argc == kMaxArgumentCount)
		parse_exception("too many arguments for command", 0);

	if (length < 0)
		length = strlen(argument);
	length++;
	char* buffer = (char*)checked_malloc(length);
	strlcpy(buffer, argument, length);

	argv[argc++] = buffer;
}
示例#29
0
long
parse_long(const char*& s) {

    static const int base(10);

    errno = 0;

    char* endptr;
    const long val(strtol(s, &endptr, base));
    if ((errno == ERANGE && (val == LONG_MIN || val == LONG_MAX))
        || (errno != 0 && val == 0) || (endptr == s)) {
        parse_exception("long int",s);
    }

    s = endptr;

    return val;
}
示例#30
0
double
parse_double(
        const char*& s,
        const char* s_end)
{
    double val;
    const char* s_start(s);
    if (s_end == NULL) s_end = s + strlen(s);
    bool isPass(boost::spirit::qi::parse(s, s_end, boost::spirit::double_, val));
    if (isPass)
    {
        isPass = (s_start != s);
    }
    if (!isPass)
    {
        parse_exception("double", s_start);
    }
    return val;
}