Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "ttokenizer.h"
Toshihiro Shimizu 890ddd
#include <qstring></qstring>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace TSyntax
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int Token::getIntValue() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return QString::fromStdString(getText()).toInt();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double Token::getDoubleValue() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return QString::fromStdString(getText()).toDouble();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Tokenizer::Tokenizer()
Toshihiro Shimizu 890ddd
	: m_buffer(), m_index(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Tokenizer::Tokenizer(string buffer)
Toshihiro Shimizu 890ddd
	: m_buffer(), m_index(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	setBuffer(buffer);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Tokenizer::~Tokenizer()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Tokenizer::setBuffer(string buffer)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_buffer = buffer + '\0';
Toshihiro Shimizu 890ddd
	m_index = 0;
Toshihiro Shimizu 890ddd
	m_tokens.clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool stringBlock = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int i = 0;
Toshihiro Shimizu 890ddd
	const char *s = &m_buffer[0];
Toshihiro Shimizu 890ddd
	for (;;) {
Toshihiro Shimizu 890ddd
		while (isascii(s[i]) && isspace(s[i]))
Toshihiro Shimizu 890ddd
			i++;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int j = i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (s[i] == '\0') {
Toshihiro Shimizu 890ddd
			m_tokens.push_back(Token("", Token::Eos, j));
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (s[i] == '"') {
Toshihiro Shimizu 890ddd
			stringBlock = !stringBlock;
Toshihiro Shimizu 890ddd
			m_tokens.push_back(Token("\"", Token::Punct, j));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			++i;
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		string token;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (stringBlock) {
Toshihiro Shimizu 890ddd
			// string block - read mercilessly until either another '"' or EOS
Toshihiro Shimizu 890ddd
			token = string(1, s[i++]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			while (s[i] != '"' && s[i] != '\0')
Toshihiro Shimizu 890ddd
				token.append(1, s[i++]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			m_tokens.push_back(Token(token, Token::Ident, j));
Toshihiro Shimizu 890ddd
		} else if (isascii(s[i]) && isalpha(s[i]) || s[i] == '_') {
Toshihiro Shimizu 890ddd
			// ident
Toshihiro Shimizu 890ddd
			token = string(1, s[i++]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			while (isascii(s[i]) && (isalpha(s[i]) || s[i] == '_' || isdigit(s[i])))
Toshihiro Shimizu 890ddd
				token.append(1, s[i++]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			m_tokens.push_back(Token(token, Token::Ident, j));
Toshihiro Shimizu 890ddd
		} else if (isascii(s[i]) && isdigit(s[i]) || s[i] == '.') {
Toshihiro Shimizu 890ddd
			// number
Toshihiro Shimizu 890ddd
			while (isascii(s[i]) && isdigit(s[i]))
Toshihiro Shimizu 890ddd
				token.append(1, s[i++]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (s[i] == '.') {
Toshihiro Shimizu 890ddd
				token.append(1, s[i++]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				while (isascii(s[i]) && isdigit(s[i]))
Toshihiro Shimizu 890ddd
					token.append(1, s[i++]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if ((s[i] == 'e' || s[i] == 'E') &&
Toshihiro Shimizu 890ddd
					(isascii(s[i + 1]) && isdigit(s[i + 1]) ||
Toshihiro Shimizu 890ddd
					 (s[i + 1] == '-' || s[i + 1] == '+') &&
Toshihiro Shimizu 890ddd
						 isascii(s[i + 2]) && isdigit(s[i + 2]))) {
Toshihiro Shimizu 890ddd
					token.append(1, s[i++]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					if (s[i] == '-' || s[i] == '+')
Toshihiro Shimizu 890ddd
						token.append(1, s[i++]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					while (isascii(s[i]) && isdigit(s[i]))
Toshihiro Shimizu 890ddd
						token.append(1, s[i++]);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			m_tokens.push_back(Token(token, Token::Number, j));
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			// punct.
Toshihiro Shimizu 890ddd
			if (s[i + 1] != '\0') {
Toshihiro Shimizu 890ddd
				token = string(s + i, 2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				const string ss[] = {
Toshihiro Shimizu 890ddd
					"==", "!=", ">=", "<=", "||", "&&"};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				const int m = tArrayCount(ss);
Toshihiro Shimizu 890ddd
				if (std::find(ss, ss + m, token) != ss + m)
Toshihiro Shimizu 890ddd
					i += 2;
Toshihiro Shimizu 890ddd
				else
Toshihiro Shimizu 890ddd
					token = string(1, s[i++]);
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				token = string(1, s[i++]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			m_tokens.push_back(Token(token, Token::Punct, j));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int Tokenizer::getTokenCount() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_tokens.size();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const Token &Tokenizer::getToken(int index) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(0 <= index && index < getTokenCount());
Toshihiro Shimizu 890ddd
	return m_tokens[index];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Tokenizer::reset()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_index = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const Token &Tokenizer::getToken()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return getToken(m_index);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Token Tokenizer::nextToken()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Token token = getToken();
Toshihiro Shimizu 890ddd
	if (m_index + 1 < getTokenCount())
Toshihiro Shimizu 890ddd
		m_index++;
Toshihiro Shimizu 890ddd
	return token;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool Tokenizer::eos() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_index + 1 == getTokenCount();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Token Tokenizer::getTokenFromPos(int pos) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int len = m_buffer.length();
Toshihiro Shimizu 890ddd
	if (pos < 0 || pos >= len)
Toshihiro Shimizu 890ddd
		return Token(pos);
Toshihiro Shimizu 890ddd
	int x = 0;
Toshihiro Shimizu 890ddd
	for (int i = 0; i < getTokenCount(); i++) {
Toshihiro Shimizu 890ddd
		const Token &token = getToken(i);
Toshihiro Shimizu 890ddd
		int y = token.getPos();
Toshihiro Shimizu 890ddd
		if (pos < y) {
Toshihiro Shimizu 890ddd
			assert(x < y);
Toshihiro Shimizu 890ddd
			return Token(x, y - 1);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		x = y + (int)token.getText().length();
Toshihiro Shimizu 890ddd
		if (pos < x)
Toshihiro Shimizu 890ddd
			return token;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	assert(x < len);
Toshihiro Shimizu 890ddd
	return Token(x, len - 1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // TSyntax