shared_ptr<Expression> Parser::parseExpression() { auto rootExp = parseExpression1(); it++; while (it->tag == OR || it->tag == AND) { auto opExp = make_shared<Expression>(); opExp->addNode(rootExp); opExp->value = *it; it++; opExp->addNode(parseExpression1()); rootExp = opExp; } return rootExp; }
static struct expr* parseExpression(ParserObjectRecordT* curSeq) { return parseExpression1(1,1,curSeq); }
static struct expr* parseExpression1(int priority, int isFirst, ParserObjectRecordT* curSeq) { struct expr *res, *op; ParserObjectT* varObj; ParserObjectRecordWithDataT tmp; char ch; if (priority > priorityNumber) { switch (curToken->type) { case ttIdentifier: res = AllocateBuffer(sizeof(struct expr)); res->op1 = res->op2 = 0; res->opCode = 0; res->varName = AllocateBuffer(strlen(curToken->str) + 1); strcpy(res->varName, curToken->str); tmp.pointerToData = 0; tmp.recPart = curSeq; varObj = ParserFindObject(res->varName, tmp, 1).objPart; if (!varObj) genParseError(E_UNKNOWN_OBJECT); if (!ParserIsErrorRaised() && varObj->objKind != PARSER_OBJECT_KIND_INTEGER) genParseError(E_INTEGER_OBJECT_EXPECTED); if (ParserIsErrorRaised()) {exprDestructor(res); return 0;} moveToNextToken(); if (ParserIsErrorRaised()) {exprDestructor(res); return 0;} return res; case ttInteger: res = AllocateBuffer(sizeof(struct expr)); res->op1 = res->op2 = 0; res->opCode = 0; res->varName = 0; res->intConst = curToken->value; moveToNextToken(); if (ParserIsErrorRaised()) {exprDestructor(res); return 0;} return res; case ttDelim: if (curToken->value == '(') { moveToNextToken(); res = parseExpression1(1, 1, curSeq); if (res && !chkCurToken(')')) { genParseError(E_RB_EXPECTED); exprDestructor(res); return NULL; } moveToNextToken(); return res; } // don't need "break" here default: return NULL; } } else { op = parseExpression1(priority + 1, 1, curSeq); if (ParserIsErrorRaised()) {exprDestructor(op); return NULL;} if (!op) { if (priority == getOpPriority('+') && isFirst && (chkCurToken('+') || chkCurToken('-'))) { // unary operations op = AllocateBuffer(sizeof(struct expr)); op->op1 = op->op2 = 0; op->opCode = 0; op->varName = 0; op->intConst = 0; } else { if (priority == getOpPriority('+')) { genParseError(E_OPERAND_EXPECTED); } return NULL; } } if (chkCurToken('^')) { if (priority < getOpPriority('^')) { genParseError(B_UNEXPECTED_CAP); exprDestructor(op); return NULL; } res = AllocateBuffer(sizeof(struct expr)); res->op1 = op; res->opCode = '^'; res->varName = 0; res->intConst = 0; moveToNextToken(); res->op2 = parseExpression1(priority, 0, curSeq); if (!res->op2) {exprDestructor(res->op2); return NULL;} op = res; } else { while ((chkCurToken('+') || chkCurToken('-') || chkCurToken('*') || chkCurToken('/')) && getOpPriority((int)curToken->value) == priority) { ch = (char)curToken->value; res = AllocateBuffer(sizeof(struct expr)); res->op1 = op; res->opCode = ch; res->varName = 0; res->intConst = 0; moveToNextToken(); res->op2 = parseExpression1(priority, 0, curSeq); if (!res->op2) {exprDestructor(res); return NULL;} op = res; } } if (ParserIsErrorRaised()) {exprDestructor(op); return NULL;} return op; } }