void ParseAssignExpr() { ParseExpr(); while(Token==TOK_COMMA) { Match(); ParseExpr(); } }
// // Helper function to create an ItemExpr tree that converts a SQL // value to a SQL string without null terminator. // static ItemExpr *CreateLmString(ItemExpr &source, const NAType &sourceType, ComRoutineLanguage language, ComRoutineParamStyle style, CmpContext *cmpContext) { // // We want an ItemExpr that converts any value X to a // string. We will use this SQL syntax: // // cast(X as {CHAR|VARCHAR}(N) CHARACTER SET ISO88591) // // where N is the max display length of X. The datatype of the // result will be CHAR(N) or VARCHAR(N) depending on the language. // ItemExpr *result = NULL; NAMemory *h = cmpContext->statementHeap(); Lng32 maxLength = GetDisplayLength(sourceType); char buf[100]; sprintf(buf, "%d", maxLength); NAString *s = new (h) NAString("cast (@A1 as ", h); if (style == COM_STYLE_JAVA_CALL) (*s) += "VARCHAR("; else (*s) += "CHAR("; (*s) += buf; (*s) += ") CHARACTER SET ISO88591);"; result = ParseExpr(*s, *cmpContext, source); return result; }
void ParseSizeofExpr() { if(CheckType()) ParseType(); else ParseExpr(); }
/* ParseArrayInitializers - parse array initializers */ static void ParseArrayInitializers(ParseContext *c, VMVALUE size) { VMVALUE *dataPtr = (VMVALUE *)c->codeBuf; VMVALUE *dataTop = (VMVALUE *)c->ctop; int done = VMFALSE; Token tkn; FRequire(c, '{'); /* handle each line of initializers */ while (!done) { int lineDone = VMFALSE; /* look for the first non-blank line */ while ((tkn = GetToken(c)) == T_EOL) { if (!GetLine(c)) ParseError(c, "unexpected end of file in initializers"); } /* check for the end of the initializers */ if (tkn == '}') break; SaveToken(c, tkn); /* handle each initializer in the current line */ while (!lineDone) { ParseTreeNode *expr; /* get a constant expression */ expr = ParseExpr(c); if (!IsIntegerLit(expr)) ParseError(c, "expecting a constant expression"); /* check for too many initializers */ if (--size < 0) ParseError(c, "too many initializers"); /* store the initial value */ if (dataPtr >= dataTop) ParseError(c, "insufficient object data space"); *dataPtr++ = expr->u.integerLit.value; switch (tkn = GetToken(c)) { case T_EOL: lineDone = VMTRUE; break; case '}': lineDone = VMTRUE; done = VMTRUE; break; case ',': break; default: ParseError(c, "expecting a comma, right brace or end of line"); break; } } } }
// Helper function to create an ItemExpr tree that converts a string // to an INTERVAL value. This expression tree is necessary because // SQL/MX will only convert arbitrary strings to INTERVALs when moving // values into the CLI via an input expression. static ItemExpr *CreateIntervalExpr(ItemExpr &source, const NAType &target, CmpContext *cmpContext) { // Our goal is to create the following expression tree. Assume "@A1" // is the input string // // case substring(@A1 from 1 for 1) // when '-' then // cast(-cast(substring(@A1 from 2) as interval year) as interval year) // else // cast(@A1 as interval year) // end ItemExpr *result = NULL; NAMemory *h = cmpContext->statementHeap(); NAString T = target.getTypeSQLname(TRUE); if (!target.supportsSQLnull()) T += " NOT NULL"; NAString *s = new (h) NAString("case substring(@A1 from 1 for 1) ", h); (*s) += "when '-' then cast(-cast(substring(@A1 from 2) as "; (*s) += T; (*s) += ") as "; (*s) += T; (*s) += ") else cast(@A1 as "; (*s) += T; (*s) += ") end;"; result = ParseExpr(*s, *cmpContext, source); return result; }
static NodeRef ParsePrimary( char **spec, int *status ) { NodeRef node = NIL; if ( !_ok(status) ) node = NIL; else if ( curtok == TOK_ID ) { node = NewNode( TOK_ID, curid, NIL, NIL, status ); NextToken( spec, status ); } else if ( curtok == TOK_OPAREN ) { NextToken( spec, status ); node = ParseExpr( spec, status ); if ( curtok == TOK_CPAREN ) NextToken( spec, status ); else { *status = SAI__ERROR; ems_rep_c( " ", "Syntax error - right parenthesis expected", status ); } } else { *status = SAI__ERROR; ems_rep_c( " ", "Unexpected token in model specification", status ); } return node; }
static NodeRef TreeCreate( char **spec, int *status ) { curid = 0; NextToken( spec, status ); return ParseExpr( spec, status ); }
/* ParseScalarInitializer - parse a scalar initializer */ static VMVALUE ParseScalarInitializer(ParseContext *c) { ParseTreeNode *expr = ParseExpr(c); if (!IsIntegerLit(expr)) ParseError(c, "expecting a constant expression"); return expr->u.integerLit.value; }
/* ParseFor - parse the 'FOR' statement */ static void ParseFor(ParseContext *c) { ParseTreeNode *var, *step; int test, body, inst; Token tkn; PVAL pv; PushBlock(c); c->bptr->type = BLOCK_FOR; /* get the control variable */ FRequire(c, T_IDENTIFIER); var = GetSymbolRef(c, c->token); code_lvalue(c, var, &pv); FRequire(c, '='); /* parse the starting value expression */ ParseRValue(c); /* parse the TO expression and generate the loop termination test */ test = codeaddr(c); (*pv.fcn)(c, PV_STORE, &pv); (*pv.fcn)(c, PV_LOAD, &pv); FRequire(c, T_TO); ParseRValue(c); putcbyte(c, OP_LE); putcbyte(c, OP_BRT); body = putcword(c, 0); /* branch to the end if the termination test fails */ putcbyte(c, OP_BR); c->bptr->u.ForBlock.end = putcword(c, 0); /* update the for variable after an iteration of the loop */ c->bptr->u.ForBlock.nxt = codeaddr(c); (*pv.fcn)(c, PV_LOAD, &pv); /* get the STEP expression */ if ((tkn = GetToken(c)) == T_STEP) { step = ParseExpr(c); code_rvalue(c, step); tkn = GetToken(c); } /* no step so default to one */ else { putcbyte(c, OP_LIT); putcword(c, 1); } /* generate the increment code */ putcbyte(c, OP_ADD); inst = putcbyte(c, OP_BR); putcword(c, test - inst - 1 - sizeof(VMUVALUE)); /* branch to the loop body */ fixupbranch(c, body, codeaddr(c)); Require(c, tkn, T_EOL); }
Expression *Parser::ParseLet(bool rec) { Token* tk = lexer_->GetToken(); lexer_->Advance(); ELet::DefList defs = ParseDefs(); Advance(Token::IN); Expression* body = ParseExpr(); return new ELet(tk, rec, defs, body); }
void ParseVarDecl() { while(Token==TOK_MUL || Token==TOK_CONST || Token==TOK_VOLATILE) { Match(); Out(" "); } if(Token==TOK_STDCALL || Token==TOK_CDECL || Token==TOK_FASTCALL || Token==TOK_WINAPI || Token==TOK_APIENTRY || Token==TOK_CALLBACK) { Match(); Out(" "); } while(Token==TOK_MUL || Token==TOK_CONST || Token==TOK_VOLATILE) { Match(); Out(" "); } /* while(Token==TOK_TYPE) { Match(TOK_TYPE); Match(TOK_SCOPE); } */ if(Token==TOK_NAME) // sometimes, we have no name! { if(intypedef) { AddType(Value); gottype=sTRUE; } Match(TOK_NAME); } else if(Token==TOK_OPERATOR) // operator overload { Match(); Out(" "); if(Token != TOK_SOPEN) Match(); else { Match(); Match(TOK_SCLOSE); } } while(Token==TOK_SOPEN) { Match(); if(Token!=TOK_SCLOSE) ParseExpr(); Match(TOK_SCLOSE); } if(Token==TOK_ASSIGN) { Match(TOK_ASSIGN); ParseInitialiser(); } }
Expression *Parser::ParseCase() { Token* tk = lexer_->GetToken(); lexer_->Advance(); Expression* cond = ParseExpr(); Advance(Token::OF); ECase::Alter alter = ParseAlter(); return new ECase(tk, cond, alter); }
bool Parser::ParseFuncCallParams(FuncCallCreator& creator, TokIterator& it) { ArithmExpr expr; ParsingResult expr_res = ParseExpr(expr, it); if(expr_res != CORRECT) { return expr_res == NOT_MATCHED; } creator.params.push_back(expr); return ParseFuncCallParamsLoop(creator, it) ? true : false; }
ASTUnaryOp* ParseUnaryOperation(MemoryArena* arena, Lexer* lex) { assert(IsUnaryOperator(lex->token)); lex->nextToken(); auto expr = ParseExpr(arena, lex); auto op = TokenToUnaryOp(lex->token); auto unaryOperation = arena->alloc<ASTUnaryOp>(op, expr); return unaryOperation; }
int main(int argc, char* argv[]) { FILE * fp = NULL; char inputExpression[256]; char strOperand1[128]; char strOperand2[128]; char strResult[128]; if (argc < 2) { printf_s("File argument is not present\n"); return -1; } fopen_s(&fp, argv[1], "r"); if (fp == NULL) { printf_s("Error opening the file %s\n", argv[1]); return -1; } fgets(inputExpression, 256, fp); RationalNumber operand1, operand2, result; long resNumer = 0, resDenom = 0; ParseExpr(inputExpression, operand1, operand2); ReduceRationalNumber(operand1); ReduceRationalNumber(operand2); FormatRationalNumString(operand1, strOperand1); FormatRationalNumString(operand2, strOperand2); printf_s("Sample Input : \n%s", inputExpression); printf_s("\n\nSample Output : \n"); AdditionExpression(operand1, operand2, result); ReduceRationalNumber(result); FormatRationalNumString(result, strResult); printf_s("%s + %s = %s\n", strOperand1, strOperand2, strResult); SubtractExpression(operand1, operand2, result); ReduceRationalNumber(result); FormatRationalNumString(result, strResult); printf_s("%s - %s = %s\n", strOperand1, strOperand2, strResult); MultiplyExpression(operand1, operand2, result); ReduceRationalNumber(result); FormatRationalNumString(result, strResult); printf_s("%s * %s = %s\n", strOperand1, strOperand2, strResult); QuotientExpression(operand1, operand2, result); ReduceRationalNumber(result); FormatRationalNumString(result, strResult); printf_s("%s / %s = %s\n", strOperand1, strOperand2, strResult); return 0; }
std::pair<std::string, Expression*> Parser::ParseDef() { std::pair<std::string, Expression*> result; Token *var_tk = Advance(Token::ID); Advance(Token::ASSIGN); Expression* expr = ParseExpr(); result.first = var_tk->TokenStr().c_str(); result.second = expr; return result; }
void ParseExpr() { ParseExprA(); if(Token==TOK_COND) { Match(); ParseExprA(); Match(TOK_COLON); ParseExpr(); } }
ForStatement* Parser :: ParseFor(){ errorIf(symStack->size() < 2, "Can not use \"for\" at the global field", scan.Get()); ExprNode *first = 0, *second = 0, *third = 0; errorIf((!isEq(scan.GetNext(), _SEPARATION, "(")), "Opening bracket expected", scan.Get()); scan.Next(); first = symStack->find_type(scan.Get()->Value) ? ParseDeclaration() :ParseExpr(); //errorIf(!isEq(scan.Get(), _SEPARATION, ";"), "Semicolon expected", scan.Get()); scan.Next(); second = ParseExpr(); errorIf(!isEq(scan.Get(), _SEPARATION, ";"), "Semicolon expected", scan.Get()); scan.Next(); if(!isEq(scan.Get(), _SEPARATION, ")")) third = ParseExpr(); errorIf(!isEq(scan.Get(), _SEPARATION, ")"), "Closing bracket expected", scan.Get()); scan.Next(); Block *body = ParseBlock(); scan.Next(); // isCanUseBreak = false; return new ForStatement(first, second, third, body); }
WhileStatement* Parser :: ParseWhile(){ errorIf(symStack->size() < 2, "Can not use \"while\" at the global field", scan.Get()); errorIf(!isEq(scan.GetNext(), _SEPARATION, "("), "Opening bracket expected", scan.Get()); scan.Next(); ExprNode *condition = ParseExpr(); errorIf(!isEq(scan.Get(), _SEPARATION, ")"), "Closing bracket expected", scan.Get()); scan.Next(); Block *body = ParseBlock(); scan.Next(); // isCanUseBreak = false; return new WhileStatement(condition, body); }
bool Parser::ParseFuncCallParamsLoop(FuncCallCreator& creator, TokIterator& it) { if(it->type_ != COMMA) { return true; } else { ArithmExpr expr; ParsingResult expr_res = ParseExpr(expr, ++it); if(expr_res != CORRECT) { return false; } creator.params.push_back(expr); } return ParseFuncCallParamsLoop(creator, it); }
ArrNode* Parser :: ParseArrIndex(ExprNode *root){ ArrNode *r = new ArrNode(root); Token *t = scan.Get(); while(isEq(t, _SEPARATION, "[")){ scan.Next(); ExprNode *index = ParseExpr(); dynamic_cast<ArrNode*>(r)->addArg(index); t = scan.Get(); errorIf(!isEq(t, _SEPARATION, "]") ,"Expected bracket close after array index", t); scan.Next(); t = scan.Get(); } return r; }
ParsingResult Parser::ParseControlFlowInstr(InstructionBlock& body, TokIterator& it) { if(it->value_ != "if" && it->value_ != "while") { return NOT_MATCHED; } std::string instruction_type = it->value_; ArithmExpr left_expr; ParsingResult expr_res = ParseExpr(left_expr, ++it); if(expr_res == INCORRECT || expr_res == NOT_MATCHED) { return INCORRECT; } if(it->type_ != COMPARISON_OP) { return INCORRECT; } std::string comp_char = it->value_; ArithmExpr right_expr; expr_res = ParseExpr(right_expr, ++it); InstructionBlock cf_instr_body; if(expr_res == INCORRECT || expr_res == NOT_MATCHED || !ParseBlock(cf_instr_body, it)) { return INCORRECT; } Condition cond(left_expr, right_expr, comp_char); if(instruction_type == "while") { WhileInstr while_instr(cond, cf_instr_body); body.AddInstruction(PtrVisitable(new WhileInstr(while_instr))); } else { IfInstr if_instr(cond, cf_instr_body); body.AddInstruction(PtrVisitable(new IfInstr(if_instr))); } return CORRECT; }
ParsingResult Parser::ParseExprInParanthesis(ArithmExpr& term, TokIterator &it, bool is_unary_minus) { if(it->type_ != OPEN_BRACE) { return NOT_MATCHED; } ArithmExpr expr; ParsingResult expr_res = ParseExpr(expr, ++it); if(expr_res != CORRECT) { return INCORRECT; } PtrVisitable PtrExpr = PtrVisitable(new ArithmExpr(expr)); if(is_unary_minus) { PtrExpr = PtrVisitable(new UnaryMinExpr(PtrExpr)); } term.AddElem(PtrExpr); return (it++)->type_ == CLOSE_BRACE ? CORRECT : INCORRECT; }
/* ParseVariableDecl - parse a variable declaration */ static int ParseVariableDecl(ParseContext *c, char *name, VMVALUE *pSize) { Token tkn; /* parse the variable name */ FRequire(c, T_IDENTIFIER); strcpy(name, c->token); /* handle arrays */ if ((tkn = GetToken(c)) == '[') { int size; /* check for an array with unspecified size */ if ((tkn = GetToken(c)) == ']') size = 0; /* otherwise, parse the array size */ else { ParseTreeNode *expr; /* put back the token */ SaveToken(c, tkn); /* get the array size */ expr = ParseExpr(c); /* make sure it's a constant */ if (!IsIntegerLit(expr) || expr->u.integerLit.value <= 0) ParseError(c, "expecting a positive constant expression"); size = expr->u.integerLit.value; /* only one dimension allowed for now */ FRequire(c, ']'); } /* return an array and its size */ *pSize = size; return VMTRUE; } /* not an array */ else SaveToken(c, tkn); /* return a scalar */ return VMFALSE; }
IfStatement *Parser :: ParseIf(){ errorIf(symStack->size() < 2, "Can not use \"if\" at the global field", scan.Get()); errorIf(!isEq(scan.GetNext(), _SEPARATION, "("), "Opening bracket expected", scan.Get()); scan.Next(); ExprNode *condition = ParseExpr(); errorIf(!isEq(scan.Get(), _SEPARATION, ")"), "Closing bracket expected", scan.Get()); scan.Next(); Block *if_branch = ParseBlock(); Block *else_branch = 0; scan.Next(); if(scan.Get()->Value == "else"){ scan.Next(); else_branch = ParseBlock(); scan.Next(); } return new IfStatement(condition, if_branch, else_branch); }
/* ParseConstantDef - parse a 'DEF <name> =' statement */ static void ParseConstantDef(ParseContext *c, char *name) { ParseTreeNode *expr; Symbol *sym; /* get the constant value */ expr = ParseExpr(c); /* make sure it's a constant */ if (!IsIntegerLit(expr)) ParseError(c, "expecting a constant expression"); /* add the symbol as a global */ sym = AddGlobal(c, name, SC_CONSTANT, expr->u.integerLit.value, 0); FRequire(c, T_EOL); }
FunctionalNode* Parser::ParseFuncCall(ExprNode *r){ FuncCallNode* f = new FuncCallNode(r->token, r, dynamic_cast<FuncSymbol*>(r->getType())); scan.Next(); Token* t = scan.Get(); while(*t != ")"){ ExprNode* s = ParseExpr(priorityTable[","] + 1); f->addArg(s); t =scan.Get(); errorIf(scan.isEnd(), "Expected closing bracket after function argument list", scan.Get()); if(*t == ","){ scan.Next(); t = scan.Get(); } } scan.Next(); return f; }
void ParseInitList() { while(1) { if(Token==TOK_NAME || Token==TOK_TYPE) { Match(); Match(TOK_OPEN); ParseExpr(); Match(TOK_CLOSE); if(Token==TOK_COMMA) Match(); } else if(Token==TOK_BOPEN) break; } }
ParsingResult Parser::ParseIOInstr(InstructionBlock& body, TokIterator& it) { if(it->value_ == "read") { if((++it)->type_ != ID) { return INCORRECT; } body.AddInstruction(PtrVisitable(new ReadInstr((it++)->value_, current_line_))); return CORRECT; } if(it->value_ == "print") { ArithmExpr expr; if(ParseExpr(expr, ++it) != CORRECT) { return INCORRECT; } body.AddInstruction(PtrVisitable(new PrintInstr(expr, current_line_))); return CORRECT; } return NOT_MATCHED; }
ECase::AlterItem Parser::ParseAlterItem() { ECase::AlterItem result; Advance(Token::LT); Token* tid_tk = Advance(Token::INT); Advance(Token::GT); result.type_id = atoi(tid_tk->TokenStr().c_str()); while (lexer_->GetToken()->type() == Token::ID) { result.vars.push_back(lexer_->GetToken()->TokenStr()); lexer_->Advance(); } Advance(Token::ARROW); result.body = ParseExpr(); return result; }