Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
TreeFromStringLexer.cpp 2.39 KiB
/*
 * TreeFromStringLexer.cpp
 *
 *  Created on: Nov 23, 2013
 *      Author: Jan Travnicek
 */

#include "TreeFromStringLexer.h"

namespace tree {

TreeFromStringLexer::Token TreeFromStringLexer::next ( std::istream & in ) const {
	TreeFromStringLexer::Token token;

	token.type = TokenType::ERROR;
	token.value = "";
	token.raw = "";
	char character;

L0:	character = in.get ( );

	if ( in.eof ( ) ) {
		token.type = TokenType::TEOF;
		return token;
	} else if ( ( character == ' ' ) || ( character == '\n' ) || ( character == '\t' ) ) {
		token.raw += character;
		goto L0;
	} else if ( character == '#' ) {
		token.value += character;
		token.raw += character;
		goto L1;
	} else if ( character == '$' ) {
		token.raw += character;
		goto L3;
	} else if ( character == '|' ) {
		token.type = TokenType::BAR;
		token.value += character;
		token.raw += character;
		return token;
	} else if ( ( character >= '0' ) && ( character <= '9' ) ) {
		token.type = TokenType::RANK;
		token.value += character;
		token.raw += character;
		goto L2;
	} else {
		in.putback ( character );
		putback ( in, std::move ( token ) );
		in.clear ( );
		token.type = TokenType::ERROR;
		return token;
	}

L1:	character = in.get ( );

	if ( in.eof ( ) ) {
		token.type = TokenType::TEOF;
		return token;
	} else if ( character == 'S' ) {
		token.type = TokenType::SUBTREE_WILDCARD;
		token.value += character;
		token.raw += character;
		return token;
	} else {
		in.putback ( character );
		putback ( in, std::move ( token ) );
		token.type = TokenType::ERROR;
		return token;
	}

L2:	character = in.get ( );

	if ( in.eof ( ) ) {
		return token;
	} else if ( ( character >= '0' ) && ( character <= '9' ) ) {
		token.value += character;
		token.raw += character;
		goto L1;
	} else {
		in.unget ( );
		return token;
	}

L3:	character = in.get ( );

	if ( in.eof ( ) ) {
		token.type = TokenType::TEOF;
		return token;
	} else if ( ( character >= 'A' ) && ( character <= 'Z' ) ) {
		token.type = TokenType::NONLINEAR_VARIABLE;
		token.value += character;
		token.raw += character;
		return token;
	} else {
		in.putback ( character );
		putback ( in, std::move ( token ) );
		token.type = TokenType::ERROR;
		return token;
	}
}

void TreeFromStringLexer::putback ( std::istream & in, TreeFromStringLexer::Token token ) const {
	while ( !token.raw.empty ( ) ) {
		in.putback ( token.raw.back ( ) );
		token.raw.pop_back ( );
	}

	in.clear ( );
}

} /* namespace tree */