示例#1
0
static int pushDefaultOperator(StateObj *pStObj) {
	if(pStObj->nextTurn == TURN_BINARY_OPERATOR){
		DEBUG(" nextTurn == TURN_BINARY_OPERATOR");
	}
	if(pStObj->posWithinPhrase == FALSE){
		DEBUG( " posWithinPhrase == FALSE");
	}
	
	if (pStObj->nextTurn == TURN_BINARY_OPERATOR && 
		pStObj->posWithinPhrase == FALSE)
			return pushOperator(pStObj,&m_defaultOperatorNode);
	return SUCCESS;
}
示例#2
0
void ExprEvaluator::E() {
  P();

  tokenizer.nextToken();

  while(tokenizer.isBinary()) {
    pushOperator(binary(tokenizer.nextToken()));
    tokenizer.consumeToken();

    P();
    tokenizer.nextToken();
  }
  while(operators.back() != oper::SANTINEL)
    popOperator();  
}
示例#3
0
void ExprEvaluator::P() {
  tokenizer.nextToken();
  if(tokenizer.isNumber()){
    operands.push_back(tokenizer.value());
    tokenizer.consumeToken();
  }else if(tokenizer.isOpenBrace()){
    tokenizer.consumeToken();
    operators.push_back(oper::SANTINEL);
    E();
    expect(ExprTokenizer::token_type::CLOSE_BRACE);
    pop(operators);
  } else if(tokenizer.isUnary()){
    pushOperator(unary(tokenizer.nextToken()));
    tokenizer.consumeToken();
    P();
  } else
    throw new Error(tokenizer.getExpr(), tokenizer.getTokPos(), ":Arithmetic expression missmatch."); 
}
void convertToPostfix(char *str){
	/* o1: Holds the precedence of the new operator
	 * o2: Holds the precendence of the topmost operator on the stack
	 * ptoken: The pointer to the start of each string delimited by commas
	 * stringToAdd:  Houses a single character so strcat() can add singular characters
	 * aCopy: A copy of the given string used to read from as we are modifying the original string
	 */
	int o1, o2;
	char *ptoken, stringToAdd[] = "0", aCopy[100];

	/* Copy the given string to a second string to be read from */
	strcpy(aCopy, str);

	/* Set the first element of the given string to NULL, effectively erasing the string from the point of view of strcat() */
	*str = '\0';

	/* Cycle through each group of characters delimited by a whitespace */
	for(ptoken = strtok(aCopy," "); ptoken != NULL; ptoken = strtok(NULL, " ")){



		/* If the character is a bracket or operator, then run this code */
		if(isOperator(*ptoken) && strlen(ptoken) == 1){

			/* Code to figure out precedences of operators */
			if(*ptoken == '*' || *ptoken == '/') o1 = 3;
			else if(*ptoken == '^') o1 = 4;
			else if(*ptoken == '+' || *ptoken == '-' ) o1 = 2;

			if(seeOperator() == '*' || seeOperator() == '/') o2 = 3;
			else if(seeOperator() == '^') o2 = 4;
			else if(seeOperator() == '+' || seeOperator() == '-' ) o2 = 2;
			else o2 = 0;

			/* If the operator stack isn't empty, and the precedence of the new operator is less than or equal to the top operator
			 * in the stack, then pop the top operator in to the post-fix string, and push the new operator in to the stack.
			 */
			if(emptyOperator() != 1 && o1 <= o2){
				*stringToAdd = popOperator();
				strcat(str," ");
				strcat(str,stringToAdd);
				pushOperator(*ptoken);
			}
			/* Otherwise, if it's empty or the new operator has greater precedence, push to the operator stack */
			else{
				pushOperator(*ptoken);
			}
		}



		/* If the character is a left bracket, push it into the operator stack */
		else if(*ptoken == '('){
			pushOperator(*ptoken);
		}

		/* If the character is a right bracket, pop operators off until you reach a left bracket, then pop off the left bracket without
		 * adding it to the string
		 */
		else if(*ptoken == ')'){
			while(seeOperator() != '('){
				*stringToAdd = popOperator();
				strcat(str," ");
				strcat(str, stringToAdd);
			}
			popOperator();
		}

		/* Otherwise(i.e. the string is a operand), just catenate the operand to the end of the string */
		else{
			strcat(str, " ");
			strcat(str, ptoken);
		}
	}



	/* Check if the operator stack is empty, if it isn't, add the top most operator to the end of the string, repeat until
	 * stack is empty.
	 * If the character is a bracket, then just pop it and don't add to the string.
	 */
	while(emptyOperator() == FALSE){
		if(seeOperator() == '(' || seeOperator() == ')') popOperator();
		else{
			*stringToAdd = popOperator();
			strcat(str," ");
			strcat(str, stringToAdd);
		}

	}

}
示例#5
0
/*
 * This function is used for morph parsing.
 *
 * The value is passed to parsetext which will call the right dictionary to
 * lexize the word. If it turns out to be a stopword, we push a QI_VALSTOP
 * to the stack.
 *
 * All words belonging to the same variant are pushed as an ANDed list,
 * and different variants are ORred together.
 */
static void
pushval_morph(Datum opaque, TSQueryParserState state, char *strval, int lenval, int2 weight, bool prefix)
{
	int4		count = 0;
	ParsedText	prs;
	uint32		variant,
				pos,
				cntvar = 0,
				cntpos = 0,
				cnt = 0;
	Oid			cfg_id = DatumGetObjectId(opaque);		/* the input is actually
														 * an Oid, not a pointer */

	prs.lenwords = 4;
	prs.curwords = 0;
	prs.pos = 0;
	prs.words = (ParsedWord *) palloc(sizeof(ParsedWord) * prs.lenwords);

	parsetext(cfg_id, &prs, strval, lenval);

	if (prs.curwords > 0)
	{

		while (count < prs.curwords)
		{
			pos = prs.words[count].pos.pos;
			cntvar = 0;
			while (count < prs.curwords && pos == prs.words[count].pos.pos)
			{
				variant = prs.words[count].nvariant;

				cnt = 0;
				while (count < prs.curwords && pos == prs.words[count].pos.pos && variant == prs.words[count].nvariant)
				{

					pushValue(state, prs.words[count].word, prs.words[count].len, weight,
							  ((prs.words[count].flags & TSL_PREFIX) || prefix) ? true : false);
					pfree(prs.words[count].word);
					if (cnt)
						pushOperator(state, OP_AND);
					cnt++;
					count++;
				}

				if (cntvar)
					pushOperator(state, OP_OR);
				cntvar++;
			}

			if (cntpos)
				pushOperator(state, OP_AND);

			cntpos++;
		}

		pfree(prs.words);

	}
	else
		pushStop(state);
}
示例#6
0
static int 
QPP_parse(void* word_db, char infix[], int max_infix_size, QueryNode postfix[], int maxNode)
{
	QueryNode quNode;
	char tmpQueryStr[STRING_SIZE];
	int nRet = 0;
	TokenObj tkObj;
	StateObj stObj;

	DEBUG("infix query: [%s]",infix);

	strncpy(tmpQueryStr,infix,STRING_SIZE-1);
	tmpQueryStr[STRING_SIZE-1] = '\0';

	DEBUG("before tokenizer set string");
	tk_setString(&tkObj,tmpQueryStr);

	stk_init(&(stObj.postfixStack));
	stk_init(&(stObj.operatorStack));
	stObj.searchField = -1;		// search all field
	stObj.nextTurn = TURN_OPERAND;
	stObj.posWithinPhrase = FALSE;
	stObj.numPhraseOperand = 0;
	stObj.truncated = 0;
	stObj.virtualfield = 0;
	stObj.virtualfield_morpid = 20;
	stObj.natural_search = 0;

	quNode.original_word[0] = '\0'; // 초기화

	DEBUG("before entering while loop");
	while (1) {
		nRet = tk_getNextToken(&tkObj,&quNode,MAX_ORIGINAL_WORD_LEN);
		DEBUG("got next token nRet [%d], token_string[%s]",nRet, quNode.original_word);
		
		// error
		if (nRet == END_OF_STRING)
			break;
		else if (nRet == TOKEN_OVERFLOW)
			continue;		// FIXME warn and push the token to stack..
		else if (nRet == 0) 
			continue;

		// right token
		switch (nRet) {
			case TOKEN_STAR:
					nRet = pushStarredWord(word_db, &stObj,&quNode);
					break;
			case TOKEN_NUMERIC:
					nRet = pushNumeric(&stObj,&quNode);
					break;
			case TOKEN_OPERATOR:
					nRet = pushOperator(&stObj,&quNode);				
					break;
			default:	// case nRet < 0
					nRet = pushExtendedOperand(word_db, &stObj,&quNode);
					break;
		}
		
		if (nRet < 0)
			break;
	}

	DEBUG("stack postfix index is [%d]",stObj.postfixStack.index);
	
	// parse된 데이터가 있고, 
	// operator로 끝나서 다음이 operand차례이면
	// fake operand를 집어넣는다.
	if (stObj.postfixStack.index > 0 && stObj.nextTurn ==TURN_OPERAND) {
		DEBUG("pushing fake operand because stack ended with operator");
		pushFakeOperand(&stObj);
	}

	nRet = stk_moveTillBottom(&(stObj.operatorStack),&(stObj.postfixStack));
	DEBUG("stk_moveTillBottom nRet is (%d)",nRet);

	nRet = stk_copyQueryNodes(&(stObj.postfixStack),maxNode,postfix);
	DEBUG("stk_copyQueryNodes nRet is (%d)",nRet);

	if (nRet == QPP_QUERY_NODE_OVERFLOW) {
		error("query node overflow. maxNode:%d", maxNode);
		return QPP_QUERY_NODE_OVERFLOW;
	}	

	/*
	if (nRet == QPP_QUERY_NODE_OVERFLOW) {
		DEBUG("OVERFLOW handling");
		return handle_query_overflow(maxNode, postfix);
	}*/

	return stObj.postfixStack.index;
}
void OperatorsStack::pushBack(char myOperator)
{
	pushOperator(myOperator, pointer);
}
示例#8
0
/*
 * This function is used for morph parsing.
 *
 * The value is passed to parsetext which will call the right dictionary to
 * lexize the word. If it turns out to be a stopword, we push a QI_VALSTOP
 * to the stack.
 *
 * All words belonging to the same variant are pushed as an ANDed list,
 * and different variants are ORed together.
 */
static void
pushval_morph(Datum opaque, TSQueryParserState state, char *strval, int lenval, int16 weight, bool prefix)
{
	int32		count = 0;
	ParsedText	prs;
	uint32		variant,
				pos = 0,
				cntvar = 0,
				cntpos = 0,
				cnt = 0;
	MorphOpaque *data = (MorphOpaque *) DatumGetPointer(opaque);

	prs.lenwords = 4;
	prs.curwords = 0;
	prs.pos = 0;
	prs.words = (ParsedWord *) palloc(sizeof(ParsedWord) * prs.lenwords);

	parsetext(data->cfg_id, &prs, strval, lenval);

	if (prs.curwords > 0)
	{
		while (count < prs.curwords)
		{
			/*
			 * Were any stop words removed? If so, fill empty positions with
			 * placeholders linked by an appropriate operator.
			 */
			if (pos > 0 && pos + 1 < prs.words[count].pos.pos)
			{
				while (pos + 1 < prs.words[count].pos.pos)
				{
					/* put placeholders for each missing stop word */
					pushStop(state);
					if (cntpos)
						pushOperator(state, data->qoperator, 1);
					cntpos++;
					pos++;
				}
			}

			/* save current word's position */
			pos = prs.words[count].pos.pos;

			/* Go through all variants obtained from this token */
			cntvar = 0;
			while (count < prs.curwords && pos == prs.words[count].pos.pos)
			{
				variant = prs.words[count].nvariant;

				/* Push all words belonging to the same variant */
				cnt = 0;
				while (count < prs.curwords &&
					   pos == prs.words[count].pos.pos &&
					   variant == prs.words[count].nvariant)
				{
					pushValue(state,
							  prs.words[count].word,
							  prs.words[count].len,
							  weight,
						  ((prs.words[count].flags & TSL_PREFIX) || prefix));
					pfree(prs.words[count].word);
					if (cnt)
						pushOperator(state, OP_AND, 0);
					cnt++;
					count++;
				}

				if (cntvar)
					pushOperator(state, OP_OR, 0);
				cntvar++;
			}

			if (cntpos)
			{
				/* distance may be useful */
				pushOperator(state, data->qoperator, 1);
			}

			cntpos++;
		}

		pfree(prs.words);

	}
	else
		pushStop(state);
}
示例#9
0
ParseStatus Parser::evalExpression() {
  ParseStatus error = PARSE_OK;
  while (error == PARSE_OK) {
    Token t = lex[0];

    // Check for terminators if we're not in a nested expression.
    if (t.isDelimiter()) {
      if (t.isTerminator() && delimiterDepth == 0) {
        break;
      }
      error = pushDelimiter(t);
    }

    if (t.isLiteral()) {
      error = pushSymbol(t);
    }
    
    if (t.isOperator()) {
      error = pushOperator(t);
    }
    

    if (!error) lex++;
    continue;
  }
  if (error) return error;

  return emitEval();

  /*
  Token base = lex[0];
  Token op = lex[1];

  if (op.isDelimiter(DL_SEMICOLON)) {
    // either "literal;" or "identifier;"
    return evalLiteral();
  }

  if (base.isKeyword(KW_FUNCTION)) {
    return parseFunction();
  }

  if (base.isDelimiter(DL_LPAREN)) {
    // Tuple
    return parseTuple();
  }

  if (base.isDelimiter(DL_LBRACE)) {
    return parseBlock();
  }

  switch(base.type) {
    case TT_EOF:
    case TT_INVALID:
      // Something's broken.
      assert(false);
      break;

    case TT_OPERATOR:
      // Unary operator
      assert(false);
      break;
    case TT_DELIMITER:
      // Tuple, array literal, block literal.
      assert(false);
      break;

    case TT_NATIVE:
      // Static cast to native type.
      assert(false);
      break;

    case TT_IDENTIFIER:
      // Function call or copy from variable.
      assert(false);

    case TT_INTEGER:
      // Expression starting with integer.
      assert(false);

    case TT_FLOAT:
      assert(false);
    case TT_RUNE:
      assert(false);
    case TT_STRING:
      assert(false);
    case TT_DIRECTIVE:
      assert(false);
    case TT_COMMENT:
      assert(false);
  }

  assert(false);
  return PARSE_ERROR;
  */
}