Пример #1
0
/**
  * Parse a subexpression and replace it with its result.
  */
void Calculator::parseSubexpression(QStringList & expressionParts)
{
  int operatorLine = 0;
  int prioLine = 0;
  int priority = 0;
  int parenthesisPos = 0;
  int functionLine = 0;
  for(parenthesisPos = 0; parenthesisPos < expressionParts.size(); parenthesisPos++)
      if((expressionParts[parenthesisPos]== "(") || (expressionParts[parenthesisPos]=="-("))
          parseParenthesis(expressionParts, parenthesisPos);
      else if(expressionParts[parenthesisPos]== ")"){
          throw ExExpressionError(tr("Parenthesis syntax error."));
      }
  if(expressionParts.size() < 2) //evaluation is complete, we had a (Expression)
      return;
  //now we have all function arguments directly behind the function name
  if(!(isNumber(expressionParts.last()) || isVariable(expressionParts.last())))
          throw ExExpressionError(tr("Last term of expression must be a number."));
  //evaluate function values from right to left
  for(functionLine = expressionParts.size() - 1; functionLine > -1; functionLine--)
      if(isFunction(expressionParts[functionLine]))
          evaluateFunction(expressionParts, functionLine);
  while(operatorLine < expressionParts.size() &&! isOperator(expressionParts[operatorLine]))
        operatorLine ++;
  if(operatorLine >= expressionParts.size() - 1) //no operator, invalid expression or nothing to be done
      throw ExExpressionError(tr("Missing operator."));

  //we found an operator, now search for the first operator with highest priority
  prioLine = operatorLine;
  priority = operatorPriority(expressionParts[operatorLine]);
  while( prioLine < expressionParts.size() - 1 )
  {
    prioLine ++;
    if(operatorPriority(expressionParts[prioLine]) > priority)
    {
        operatorLine = prioLine;
        priority = operatorPriority(expressionParts[prioLine]);
    }
  }
  //Now lets calculate
  if(operatorLine < 1) //we have a leading operator
  {
   if(expressionParts[operatorLine] == "-" | expressionParts[operatorLine] == "+") //we have a sign
   {
       if(expressionParts[operatorLine] == "-")
         expressionParts[0] = expressionParts[0] + expressionParts[1]; //make a negative number
       expressionParts.removeAt(1); //and delete the sign from list
       return;
   }
   else throw ExExpressionError(tr("No operator allowed in first position."));
  }
  calculateSubExpression(expressionParts, operatorLine);
}
Пример #2
0
	Expression* parseEntitySuffixes(TokenStream* tokens, FileContext* fileContext)
	{
		bool hasPrefix = false;
		bool hasSuffix = false;
		Token prefixToken;
		Token suffixToken;
		string next = tokens->safePeekValue();
		if (next == "++" || next == "--")
		{
			prefixToken = tokens->pop();
			hasPrefix = true;
		}

		Expression* expression = parseParenthesis(tokens, fileContext);
		next = tokens->safePeekValue();
		while (next == "." || next == "[" || next == "(")
		{
			if (next == ".")
			{
				Token dotToken = tokens->pop();
				Token fieldNameToken = tokens->pop();
				fieldNameToken.assertValidIdentifier();
				return new DotField(expression, dotToken, fieldNameToken, fileContext);
			}
			else if (next == "[")
			{
				Token openBracket = tokens->pop();
				vector<Expression*> indices = vector<Expression*>();
				bool nextAllowed = true;
				while (!tokens->popIfPresent("]"))
				{
					if (tokens->popIfPresent(":"))
					{
						nextAllowed = true;
						indices.push_back(NULL);
					}
					else
					{
						Expression* index = parseExpression(tokens, fileContext);
						nextAllowed = tokens->popIfPresent(":");
						indices.push_back(index);
					}
				}

				if (nextAllowed)
				{
					indices.push_back(NULL);
				}

				if (indices.size() > 3)
				{
					throw new ParserException(openBracket, 
						"Too many expressions in this slice expression.");
				}

				if (indices.size() == 1)
				{
					if (indices.at(0) == NULL)
					{
						throw new ParserException(openBracket, "Need an index expression here.");
					}
					expression = new BracketIndex(expression, openBracket, indices.at(0), fileContext);
				}
				else if (indices.size() == 2)
				{
					expression = new BracketSlice(
						expression, openBracket, indices.at(0), indices.at(1), NULL, fileContext);
				}
				else
				{
					expression = new BracketSlice(
						expression, openBracket, indices.at(0), indices.at(1), indices.at(2), fileContext);
				}
			}
			else if (next == "(")
			{
				vector<Expression*> args = vector<Expression*>();
				Token openParen = tokens->popExpected("(");
				while (!tokens->popIfPresent(")"))
				{
					if (args.size() > 0)
					{
						tokens->popExpected(",");
					}
					Expression* arg = parseExpression(tokens, fileContext);
					args.push_back(arg);
				}
				expression = new FunctionInvocation(expression, openParen, args, fileContext);
				next = tokens->safePeekValue();
			}
			next = tokens->safePeekValue();
		}

		if (next == "++" || next == "--")
		{
			suffixToken = tokens->pop();
			hasSuffix = true;
		}

		if (hasPrefix && hasSuffix)
		{
			throw new ParserException(suffixToken, "Expression has both suffix and prefix");
		}

		if (hasPrefix)
		{
			expression = new InlineIncrement(prefixToken, expression, prefixToken, true, fileContext);
		}

		if (hasSuffix)
		{
			expression = new InlineIncrement(
				expression->firstToken, expression, suffixToken, false, fileContext);
		}

		return expression;
	}