Beispiel #1
0
int parse(void **progTree, int uGrammar) {
	SYMB_INFO *stack[200],
				 **spt = stack,
				 *curSymb,
				 mainSymb = {0, INIT_SYMB, 0, {}, NULL};
	TOKEN curToken;
	int ruleNo, i;

	if(uGrammar >= 0)
		mainSymb.type = uGrammar;

	//insert main symbol in stack and read first token
	*spt++ = &mainSymb;
	if(getToken(&curToken) != PAR_OK)
		return PAR_ERROR;

	while(spt != stack) {
		curSymb = *--spt;

		if(curSymb->isTerminal) {
			//termatiko symbolo
			if(curSymb->type == curToken.type) {
				//tairiazei me to symbolo sthn eisodo.
				curSymb->value = curToken.value;					//Apo8hkeysh timhs
				if(getToken(&curToken) != PAR_OK)				//pairnoyme neo symbolo
					return PAR_ERROR;

			} else
				return PAR_ERROR;
		} else {
			//mh termatiko symbolo
			ruleNo = LL1[curSymb->type - TRMNO][curToken.type];		//eyresh kanona
			if(ruleNo == -1) return PAR_ERROR;								//syntaktiko la8os

			//pros8hkh olwn twn symbolwn toy de3iou merous tou kanona sth stoiba me
			//anapodh seira. Kratame ta symbola ayta ston pinaka chl
			curSymb->ruleNo = ruleNo;
			for(i = grammar[ruleNo].rsNo - 1; i >= 0; i--) {
				SYMB_INFO *tmpSymb = malloc(sizeof(SYMB_INFO));
				curSymb->chl[i] = tmpSymb;
	
				tmpSymb->type = grammar[ruleNo].rs[i];
				tmpSymb->isTerminal = (tmpSymb->type < TRMNO);
				tmpSymb->value = NULL;
				*spt++ = tmpSymb;
			}
		}
	}

	//dhmioyrgia syntantikou dentrou
	buildParseTree(&mainSymb);

	//epityxia
	if(progTree) *progTree = mainSymb.value;
	return PAR_OK;
}
Beispiel #2
0
void buildParseTree(SYMB_INFO *symb) {
	int i;

	//ean to symbolo einai termatiko tote den xreiazetai epe3ergasia
	if(symb->isTerminal)
		return;

	//prwta epe3ergazomaste ola ta paidia
	for(i = 0; i < grammar[symb->ruleNo].rsNo; i++)
		buildParseTree(symb->chl[i]);

	//epe3ergasia toy kanona
	grammar[symb->ruleNo].func(symb);

	//apeley8erwsh mnhmhs
	for(i = 0; i < grammar[symb->ruleNo].rsNo; i++) {
		if(symb->chl[i]->isTerminal)
			free(symb->chl[i]->value);
		free(symb->chl[i]);
	}
}
execplan::ParseTree* ScalarSub::transform()
{
    if (!fFunc)
        return NULL;

    // @todo need to handle scalar IN and BETWEEN specially
    // this blocks handles only one subselect scalar
    // arg[0]: column | arg[1]: subselect
    //idbassert(fGwip.rcWorkStack.size() >= 2);
    if (fFunc->functype() == Item_func::BETWEEN)
        return transform_between();

    if (fFunc->functype() == Item_func::IN_FUNC)
        return transform_in();

    ReturnedColumn* rhs = NULL;
    ReturnedColumn* lhs = NULL;

    if (!fGwip.rcWorkStack.empty())
    {
        rhs = fGwip.rcWorkStack.top();
        fGwip.rcWorkStack.pop();
    }

    if (!fGwip.rcWorkStack.empty())
    {
        lhs = fGwip.rcWorkStack.top();
        fGwip.rcWorkStack.pop();
    }

    PredicateOperator* op = new PredicateOperator(fFunc->func_name());

    if (!lhs && (fFunc->functype() == Item_func::ISNULL_FUNC ||
                 fFunc->functype() == Item_func::ISNOTNULL_FUNC))
    {
        fSub = (Item_subselect*)(fFunc->arguments()[0]);
        fColumn.reset(new ConstantColumn("", ConstantColumn::NULLDATA));
        delete rhs;
        return buildParseTree(op);
    }

    bool reverseOp = false;
    SubSelect* sub = dynamic_cast<SubSelect*>(rhs);

    if (!sub)
    {
        reverseOp = true;
        delete lhs;
        lhs = rhs;
        fSub = (Item_subselect*)(fFunc->arguments()[0]);
    }
    else
    {
        delete rhs;
        fSub = (Item_subselect*)(fFunc->arguments()[1]);
    }

    fColumn.reset(lhs); // column should be in the stack already. in, between may be different

    //PredicateOperator *op = new PredicateOperator(fFunc->func_name());
    if (reverseOp)
        op->reverseOp();

    return buildParseTree(op);
}
execplan::ParseTree* ScalarSub::transform_between()
{
    //idbassert(fGwip.rcWorkStack.size() >= 3);
    if (fGwip.rcWorkStack.size() < 3)
    {
        fGwip.fatalParseError = true;
        fGwip.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_SCALAR);
        return NULL;
    }

    ReturnedColumn* op3 = fGwip.rcWorkStack.top();
    fGwip.rcWorkStack.pop();
    ReturnedColumn* op2 = fGwip.rcWorkStack.top();
    fGwip.rcWorkStack.pop();
    ReturnedColumn* op1 = fGwip.rcWorkStack.top();
    fGwip.rcWorkStack.pop();
    fColumn.reset(op1);

    ParseTree* lhs = NULL;
    ParseTree* rhs = NULL;
    PredicateOperator* op_LE = new PredicateOperator("<=");
    PredicateOperator* op_GE = new PredicateOperator(">=");

    SubSelect* sub2 = dynamic_cast<SubSelect*>(op3);
    fSub = (Item_subselect*)(fFunc->arguments()[2]);

    if (sub2)
    {
        rhs = buildParseTree(op_LE);
        delete sub2;
    }
    else
    {
        SOP sop;
        sop.reset(op_LE);
        rhs = new ParseTree(new SimpleFilter(sop, fColumn.get(), op3));
    }

    SubSelect* sub1 = dynamic_cast<SubSelect*>(op2);
    fSub = (Item_subselect*)(fFunc->arguments()[1]);

    if (sub1)
    {
        lhs = buildParseTree(op_GE);
        delete sub1;
    }
    else
    {
        SOP sop;
        sop.reset(op_GE);
        lhs = new ParseTree(new SimpleFilter(sop, fColumn.get(), op2));
    }

    if (!rhs || !lhs)
    {
        fGwip.fatalParseError = true;
        fGwip.parseErrorText = "non-supported scalar subquery";
        fGwip.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_SCALAR);
        return NULL;
    }

    ParseTree* pt = new ParseTree (new LogicOperator("and"));
    pt->left(lhs);
    pt->right(rhs);
    return pt;
}