Beispiel #1
0
/**
 * @param 0: string
 * @param 1: position of a character to be used as starting character for the substring.
 * @param 2: length of the substring
 * @return substr
 */
Token str_substr(TokenStack& args)
{
	args.check(3);
	int size =        args.pop_int();
	int from =        args.pop_int();
	std::string str = args.pop_string();
	return Token::create_string(str.substr(from, size));
}
Beispiel #2
0
/**
 * Convert to lowercase
 * @param 0: string
 * @return lowercase string
 */
Token str_lower(TokenStack& args)
{
	args.check(1);
	std::string str = args.pop_string();
	for (size_t i = 0; i < str.length(); ++i)
	{
		str[i] = tolower(str[i]);
	}
	return Token::create_string(str);
}
Beispiel #3
0
/**
 * Returns a sub-stack of elements from the given stack, starting
 * at the current position of the stack until the end of statement.
 */
TokenStack* CodeParser::getStackToEndOfStatement( TokenStack* stack ) {
	Token* t;

	// gather the arguments up to the end of the statement
	TokenStack* substack = new TokenStack();
	while( ( t = stack->next() ) && ( t->getType() != tok::END_OF_STATEMENT ) ) {
		substack->pushFront( t );
	}
	return substack;
}
Beispiel #4
0
Token *Parser::parse(bool *ok, QString *err, Token *token) const
{
    if (mtokens.isEmpty())
        return bRet(ok, true, err, QString(), token, Token(), new Token(Token::Program_Token));
    TokenStack stack;
    int i = 0;
    while (true) {
        if (mtokens.size() == i) {
            stack.freeAll();
            return bRet(ok, false, err, tr("Unexpected end of token list", "error"), token, Token(), (Token *) 0);
        }
        const Token &t = mtokens.at(i);
        int x = 0;
        ShiftReduceChoice choice = chooseShiftReduce(stack.state(), t.type(), &x);
        switch (choice) {
        case StateChangeChoice: {
            stack.append(new Token(t), x);
            ++i;
            break;
        }
        case ReduceChoice: {
            bool b = false;
            Token *nt = reduce(stack, x, &b, err);
            if (!b) {
                delete nt;
                stack.freeAll();
                return bRet(ok, b, token, t, (Token *) 0);
            }
            if (nt->type() == Token::Program_Token && stack.isEmpty()) {
                if (i < mtokens.size() - 1)
                    return bRet(ok, false, err, tr("Unexpected error", "error"), token, t, (Token *) 0);
                return bRet(ok, true, err, QString(), token, Token(), nt);
            }
            choice = chooseShiftReduce(stack.state(), nt->type(), &x);
            if (ShiftChoice != choice)
                return bRet(ok, false, err, tr("Failed to find shift rule", "error"), token, t, (Token *) 0);
            stack.append(nt, x);
            break;
        }
        case ShiftChoice: {
            stack.freeAll();
            return bRet(ok, false, err, tr("Unexpected shift rule", "error"), token, t, (Token *) 0);
        }
        case ErrorChoice:
        default: {
            stack.freeAll();
            return bRet(ok, false, err, tr("Failed to find shift or reduce rule", "error"), token, t, (Token *) 0);
        }
        }
    }
    return bRet(ok, false, err, tr("Failed to finish parsing", "error"), token, Token(), (Token *) 0);
}
Beispiel #5
0
/**
 * Remove leading and trailing whitespaces
 * @param 0: string
 * @return trimmed string
 */
Token str_trim(TokenStack& args)
{
	args.check(1);
	std::string str = args.pop_string();
	const char* WHITESPACES = " \t\n\r\0xb";
	std::string::size_type first = str.find_first_not_of(WHITESPACES);
	if (first != std::string::npos)
	{
		std::string::size_type last = str.find_last_not_of(WHITESPACES);
		return Token::create_string(str.substr(first, last - first + 1));
	}
	return Token::create_string(str);
}
Beispiel #6
0
/**
 * Count occurences in a string
 * @param 0: string
 * @param 1: occurrence
 * @return occurrence count
 */
Token str_count(TokenStack& args)
{
	args.check(2);
	std::string look_for = args.pop_string();
	std::string str =      args.pop_string();

	size_t pos = str.find(look_for);
	int count = 0;
	while (pos != std::string::npos)
	{
		pos = str.find(look_for, pos + 1);
		++count;
	}
	return Token::create_int(count);
}
Beispiel #7
0
/**
 * @param 0: target string
 * @param 1: sous-chaîne rechercher
 * @param 2: sous-chaîne à caser
 * @return chaîne remplacée
 */
Token str_replace(TokenStack& args)
{
	args.check(3);
	std::string replace_by = args.pop_string();
	std::string look_for =   args.pop_string();
	std::string target =     args.pop_string();

	size_t step = replace_by.size();
	size_t offset = look_for.size();
	size_t pos = target.find(look_for);
	while (pos != std::string::npos)
	{
		target.replace(pos, offset, replace_by);
		pos = target.find(look_for, pos + step);
	}
	return Token::create_string(target);
}
void
gen_aux (const Grammar &g, const std::string &start, std::vector<std::string> &result)
{
  TokenStack lifo;
  expand_aux (g, start, lifo);

  while (!lifo.empty())
  {
    const std::string curr_word = lifo.top();
    lifo.pop();
    if (!bracketed (curr_word))
    {
      result.push_back (curr_word);
    }
    else
    {
      expand_aux (g, curr_word, lifo);
    }
  }
}
Beispiel #9
0
/**
 * Parses method call parameters
 */
int CodeParser::parseMethodParameters( Scope* scope, TokenStack* stack, list<Parameter*> params ) {
	Token* t;

	// the next token must be a parenthesis block (e.g. "( .. )")
	if( !( t = stack->next() ) || ( t->getType() != tok::PARENTHESIS_BLOCK ) ) {
		SYNTAX_ERROR( "Symbol '(' expected", stack->last() );
		return -1;
	}

	// get the sub-stack
	TokenStack* substack = ((ComplexToken*)t)->getChildren();

	// gather the parameters
	while( ( t = substack->next() ) ) {
		printf( "CodeParser::parseMethodParameters token: %s\n", t->getText() );
		// TODO add method parameter parsing logic here

	}

	return 0;
}
void
expand_aux (const Grammar &g, const std::string &word, TokenStack &result)
{
  Grammar::const_iterator it = g.find (word);
  if (g.end() != it)
    {
      const RuleCollection &rc = it->second;
      const Rule &r = rc[nrand(rc.size())];
      for (int i = r.size() - 1; i > -1; --i)
      {
        result.push(r[i]);
      }
    }
}
Beispiel #11
0
/**
 * Parses the expression from the given token stack
 */
int CodeParser::parseExpression( Scope* scope, TokenStack* stack ) {
	int errorCode = 0;
	Token* t;

	// gather the arguments up to the end of the statement
	TokenStack* substack = getStackToEndOfStatement( stack );

	// get the argument list
	while( !errorCode && substack->hasNext() && ( t = substack->next() ) ) {
		printf( "CodeParser::parseExpression: '%s' [%s]\n", t->getText(), t->getTypeName() );

		// handle the token by type
		switch( t->getType() ) {
			case tok::ALPHA_NUMERIC:
				// is the argument a field?
				if( scope->lookupField( t->getText() ) ) {
					printf( "CodeParser::parseExpression: Field - [%s]\n", t->getText() );
				}

				// is it a method call?
				else if( substack->hasNext() && substack->peek()->getType() == tok::PARENTHESIS_BLOCK ) {
					errorCode = parseExpression_MethodCall( t->getText(), scope, substack );
				}
				break;

			case tok::DECIMAL:
			case tok::INTEGER:
				break;

			case tok::DQUOTE_TEXT:
				break;

			case tok::SQUOTE_TEXT:
				break;

			case tok::OPERATOR:
				break;

			case tok::PARENTHESIS_BLOCK:
				break;

			default:
				errorCode = -1;
				SYNTAX_ERROR( "unexpected token", substack->last() );
		}
	}

	// delete the stack
	delete substack;

	// return the error code
	return errorCode;
}
Beispiel #12
0
// LET command translate function
TokenStatus letTranslate(Translator &translator, Token *commandToken,
	Token *&token)
{
	TokenStatus status;
	int column;
	bool hidden;
	DataType dataType;
	bool done;
	TokenStack letStack;
	bool haveSubStr = false;

	if (commandToken == NULL)
	{
		column = token->column();
		hidden = true;
	}
	else  // delete unneeded command token and get another token
	{
		column = commandToken->column();
		delete commandToken;
		hidden = false;
	}
	dataType = Any_DataType;
	do
	{
		if ((status = translator.getOperand(token, dataType,
			Translator::All_Reference)) != Good_TokenStatus)
		{
			if (token->column() > column)
			{
				return status;
			}
			// next token determines error
			Token *nextToken;
			if ((status = translator.getToken(nextToken)) != Good_TokenStatus)
			{
				status = ExpCmd_TokenStatus;
			}
			if (nextToken->isCode(Comma_Code) || nextToken->isCode(Eq_Code))
			{
				status = ExpAssignItem_TokenStatus;
			}
			else
			{
				status = ExpCmd_TokenStatus;
			}
			delete nextToken;
			return status;
		}

		// get and check next token for comma or equal
		status = translator.getToken(token);
		if (token->isCode(Comma_Code))
		{
			done = false;
		}
		else if (token->isCode(Eq_Code))
		{
			done = true;
		}
		else  // invalid token or parser error
		{
			if (translator.table().hasFlag(translator.doneStackTopToken(),
				SubStr_Flag))
			{
				delete translator.doneStackPop();
			}
			return ExpEqualOrComma_TokenStatus;
		}

		// check if this is a sub-string assignment
		if (translator.table().hasFlag(translator.doneStackTopToken(),
			SubStr_Flag))
		{
			// delete comma/equal token, use sub-string function token
			delete token;

			// get sub-string function token from rpn item on top of stack
			// (delete rpn item since it was not appended to output)
			RpnItem *rpnItem = translator.doneStackPop();
			token = rpnItem->token();
			rpnItem->setToken(NULL);  // prevent delete of token
			delete rpnItem;

			// change to assign sub-string code (first associated code)
			translator.table().setToken(token,
				translator.table().associatedCode(token->code()));

			haveSubStr = true;
		}
		else  // use comma/equal token
		{
			// change token to appropriate assign code
			translator.table().setToken(token, Assign_Code);
			status = translator.processDoneStackTop(token);
			if (status != Good_TokenStatus)
			{
				return status;
			}
		}
		letStack.push(token);  // save token

		// get data type for assignment
		if (dataType == Any_DataType)
		{
			dataType = token->dataType();
		}

		token = NULL;
	}
	while (!done);

	// get expression for value to assign
	if ((status = translator.getExpression(token,
		translator.equivalentDataType(dataType))) != Done_TokenStatus)
	{
		if (status == Parser_TokenStatus && token->isDataType(None_DataType))
		{
			status = ExpOpOrEnd_TokenStatus;
		}
		return status;
	}

	Token *letToken = letStack.pop();
	if (!letStack.isEmpty())
	{
		if (haveSubStr)
		{
			// add each token saved in let stack except the last
			do
			{
				// change to keep code (second associated code)
				translator.table().setToken(letToken,
					translator.table().associatedCode(letToken->code()));

				// append to output and pop next token from let stack
				translator.outputAppend(letToken);
				letToken = letStack.pop();
			}
			while (!letStack.isEmpty());  // continue until last token
		}
		else  // have a multiple assignment, change to list code
		{
			translator.table().setToken(letToken,
				translator.table().secondAssociatedCode(letToken->code()));
		}
	}

	// drop expresion result from done stack, append last assignment token
	translator.doneStackDrop();
	translator.outputAppend(letToken);

	// set hidden LET flag if needed
	if (!hidden)
	{
		letToken->addSubCode(Option_SubCode);
	}

	// check terminating token for end-of-statement
	if (!translator.table().hasFlag(token, EndStmt_Flag))
	{
		return ExpOpOrEnd_TokenStatus;
	}

	return Done_TokenStatus;
}
Beispiel #13
0
// Process declaration statements.
void Parser::procDeclaration()
{
  Token declToken; // Actual token of the declared entity
  TokenStack varNames; // Names of declared variables
  bool haveFunction; // Have a function declaration
  bool insideParams; // Inside  parameter list of a function
  int parenCount; // Count of unmatched parentheses
  int consParenCount; // Count of consecutive open parantheses

  declToken = _currToken;
  if (_buffer.lastLookahead().getType() == Token::openparen) {
    haveFunction = true;
    insideParams = true;
    parenCount = 1;
    // Burn the paranthese, so not confused with argument declarations
    _buffer.nextToken();
  }
  else {
    haveFunction = false;
    insideParams = false;
    parenCount = 0;
  }

  // Process the rest of the declaration.
  consParenCount = 0;
  while (_statementType == declaration) {
    _currToken = _buffer.nextToken();
    // Check for defined symbols
    if (_currToken.getType() == Token::identifier)
      _symbolTable.checkForSymbol(_currToken);
    // Process combined types
    if (_currToken.getType() == Token::compound)
      procCombType();
    switch (_currToken.getType()) {
    case Token::identifier:
      // Burn parenthases around the identifier
      while ((_buffer.nextLookahead().getType() == Token::closeparen) &&
             (consParenCount > 0)) {
        _buffer.nextToken();
        consParenCount--;
      }
      if (_buffer.lastLookahead().getType() == Token::openparen)
        /* Function call. This terminates a function declaration, and marks
           the start of the initial value for a variable declaration */
        _statementType = expression;
      else {
        /* Variable name. For functions, this is a parameter name; for
           variable declarations, assume multiple vars are being declared in
           one declaration statement. Note: due to K+R style parameter
           declarations, function parameter declarations do not need to be
           whithin parentheses */
        _currToken.setType(Token::varname);
        if (haveFunction || (_braceCount > 0))
            _currToken.setScope(Token::localscope);
        else
            _currToken.setScope(Token::filescope);
        varNames.push(_currToken); // Add to variable list
        /* K+R variable declarations have a trailing semicolon, which must
           be burned also */
        if (haveFunction && (!insideParams) && // K+R style declaration
            (_buffer.lastLookahead().getType() == Token::semicolon))
            _buffer.nextToken();
      }
      break;

    case Token::openparen:
      parenCount++;
      break;

    case Token::closeparen:
      parenCount--;
      if (insideParams && (parenCount <= 0))
        insideParams = false;
      break;

    case Token::typedeftoken:
    case Token::statictoken:
      if (!insideParams) // Modifier on the entire declaration
        _parseStack.push(_currToken);
      break;

    case Token::ampersand:
    case Token::othersymbol:
      /* Have reached the initializer list for var declarations; this is an
         error for function declarations */
      if (haveFunction)
        _statementType = undet;
      else
        _statementType = expression;
      break;

    case Token::typetoken:
    case Token::declsymbol:
      // Ignore it
      break;

    case Token::fieldaccess:
      /* If inside params and have a dot, assume this is part of varags symbol
         (It is not common enough to have a seperate token for it) */
      if ((!insideParams) || (_currToken.getLexeme() != "."))
        _statementType = undet;
      // else part of varargs indicator, so ignore it
      break;

    default:
      // token is not allowed in declarations
      _statementType = undet;
    }
    // Update or clear consecutive parenthese count, as needed
    if (_currToken.getType() == Token::openparen)
      consParenCount++;
    else
      consParenCount = 0;
  }

  // Process the just read declaration
  if (haveFunction)
    procFunctDeclaration(declToken, _currToken, insideParams);
  else { // variable or type declaration
    // Set token type
    if (_parseStack.hasType(Token::typedeftoken))
      declToken.setType(Token::typetoken);
    else
      declToken.setType(Token::varname);

    // Set its scope
    if (_braceCount > 0)
      declToken.setScope(Token::localscope);
    else
      declToken.setScope(Token::filescope);
    _symbolTable.updateNameSpace(declToken);
  }

  /* add new variables to the namespace. Ignore the vars in a function
     declaration unless it is followed by an openbrace, as it is actually
     a prototype, not a declaration */
  if ((declToken.getType() == Token::varname) || (declToken.getType() == Token::functdecl))
    while (!varNames.empty())
      _symbolTable.updateNameSpace(varNames.pop());
  _readNextToken = false; // Need to process token that ended declaration
}
Beispiel #14
0
// 把解析好的表达式转换成逆波兰式
bool ConvertExpr(const TokenVector & input, TokenVector & output)
{
	TokenStack stack;
	output.clear();

	TokenVector::const_iterator it = input.begin();
	for (; it != input.end(); ++it)
	{
		if (it->type == OP)
		{
			// 左括号,直接压进操作符栈
			if (it->value.op == LEFT)
			{
				stack.push(*it);
			}
			// 右括号,从栈里弹出操作符,直到碰到右括号
			else if (it->value.op == RIGHT)
			{
				bool find_left = false;
				while (!stack.empty())
				{
					if (stack.top().value.op == LEFT)
					{
						find_left = true;
						stack.pop();
						break;
					}
					else
					{
						output.push_back(stack.top());
						stack.pop();
					}
				}
				if (!find_left) return false;
			}
			// 其它操作符,和栈顶操作符比较优先级
			else
			{
				while (!stack.empty() && stack.top().value.op != LEFT &&
					OPPriority(stack.top().value.op) >= OPPriority(it->value.op))
				{
					output.push_back(stack.top());
					stack.pop();
				}

				stack.push(*it);
			}
		}
		// 非操作符直接输出
		else
		{
			output.push_back(*it);
		}
	}

	while (!stack.empty())
	{
		output.push_back(stack.top());
		stack.pop();
	}

	return true;
}
Beispiel #15
0
/**
 * Compute number of characters
 * @param 0: target string
 * @return string length
 */
Token str_len(TokenStack& args)
{
	args.check(1);
	int length = args.pop_string().size();
	return Token::create_int(length);
}
Beispiel #16
0
// 逆波兰式计算求值
bool CalcExpr(const TokenVector & input, const TokenVector & expr, Token & result)
{
	TokenStack stack;

    
	TokenVector::const_iterator it = expr.begin();
	for (; it != expr.end(); ++it)
	{
		if (it->type == INT || it->type == FLOAT || it->type == BOOL)
		{
			stack.push(*it);
		}
		else if (it->type == ARG)
		{
			if (it->value.index >= input.size()) return false;
			const Token & a = input[it->value.index];
			if (a.type == INT || a.type == FLOAT || a.type == BOOL)
			{
				stack.push(a);
			}
			else
			{
				return false;
			}
		}
		else if (it->type == RAND)
		{
			Token a;
			a.type = INT;
			a.value.i = rand();
			stack.push(a);
		}
		else if (it->type == OP)
		{
			if (stack.size() < 2) return false;
			Token a = stack.top();
			stack.pop();
			Token b = stack.top();
			stack.pop();
			Token c;
			if (GetValue(it->value.op, b, a, c))
			{
				stack.push(c);
			}
			else
			{
				return false;
			}
		}
	}

	if (!stack.empty())
	{
		result = stack.top();
		return true;
	}
	else
	{
		return false;
	}
}
Beispiel #17
0
void IRCSession::calculate(string privmsg)
{
    sk = TokenStack();
    while(!q.empty())
    {
        Token t = q.get();
        if(t.tkntype == TKN_NUMBER || t.tkntype == TKN_NAME)
            sk.put(t);
        else if(t.tkntype == TKN_OPERATOR)
        {
            if(t.str == "+")
            {
                Token o1, o2;
                if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME))
                    o2 = getValue(sk.get());

                if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME))
                    o1 = getValue(sk.get());

                Token e = Token(TKN_NUMBER, o1.number+o2.number, "");
                sk.put(e);
            }
            else if(t.str == "-")
            {
                Token o1, o2;
                if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME))
                    o2 = getValue(sk.get());

                if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME))
                    o1 = getValue(sk.get());

                Token e = Token(TKN_NUMBER, o1.number-o2.number, "");
                sk.put(e);
            }
            else if(t.str == "*")
            {
                Token o1, o2;
                if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME))
                    o2 = getValue(sk.get());

                if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME))
                    o1 = getValue(sk.get());

                Token e = Token(TKN_NUMBER, o1.number*o2.number, "");
                sk.put(e);
            }
            else if(t.str == "/")
            {
                Token o1, o2;
                if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME))
                    o2 = getValue(sk.get());

                if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME))
                    o1 = getValue(sk.get());

                Token e = Token(TKN_NUMBER, o1.number/o2.number, "");
                sk.put(e);
            }
            else if(t.str == "%")
            {
                Token o1, o2;
                if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME))
                    o2 = getValue(sk.get());

                if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME))
                    o1 = getValue(sk.get());

                Token e = Token(TKN_NUMBER, cast_int(o1.number)%cast_int(o2.number), "");
                sk.put(e);
            }
            else if(t.str == "^" || t.str == "**")
            {
                Token o1, o2;
                if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME))
                    o2 = getValue(sk.get());

                if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME))
                    o1 = getValue(sk.get());

                Token e = Token(TKN_NUMBER, pow(o1.number, o2.number), "");
                sk.put(e);
            }
            /*else if(t.str == "sin")
            {
            	Token o1, o2;
            	if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME))
            		o2 = getValue(sk.get());

            	if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME))
            		o1 = getValue(sk.get());

            	Token e = Token(TKN_NUMBER, sin(12), "");
            	sk.put(e);
            }*/
        }
    }

    double d;

    if(!sk.empty())
        d = getValue(sk.get()).number;
    else
        d = 0.0f;

    if(d-cast_int(d) < 0.00000049)
        SendChatMessage(PRIVMSG, privmsg.c_str(), "%d", cast_int(d));
    else
        SendChatMessage(PRIVMSG, privmsg.c_str(), "%f", d);

    varv.clear();
}
Beispiel #18
0
void IRCSession::makepolishform(string szam)
{
    string s = szam;
    q = TokenQueue();
    sk = TokenStack();
    CalcLexer cl = CalcLexer(s);
    Token t;
    do
    {
        if(t.tkntype == TKN_NEXT_LINE)
            cl = CalcLexer(s);

        t = cl.getNextToken();
        if(t.tkntype == TKN_NUMBER || t.tkntype == TKN_NAME)
            q.put(t);
        else if(t.tkntype == TKN_OPEN_PAR)
            sk.put(t);
        else if(t.tkntype == TKN_CLOSE_PAR)
        {
            Token t1;
            while(!sk.empty() && sk.seek().tkntype != TKN_OPEN_PAR)
                q.put(sk.get());

            sk.get();
        }
        else if(t.tkntype == TKN_OPERATOR)
        {
            while(!sk.empty() && getpriority(sk.seek()) <= getpriority(t))
                q.put(sk.get());

            sk.put(t);
        }
    } while(t.tkntype != TKN_TERMINATION);

    while(!sk.empty())
        q.put(sk.get());
}