StructSymbol* Parser :: ParseStruct(bool param){ Token *token =scan.GetNext(); string name; if(token->Type == _IDENTIFIER){ name = token->Value; token =scan.GetNext(); } else name = "unnamed struct " + to_string((long double)struct_counter++); StructSymbol *struct_symbol = dynamic_cast<StructSymbol*>(symStack->find_symbol(name)); errorIf(param && !struct_symbol, "Unknown struct type"); if(param && !struct_symbol){ errorIf(isEq(token, _SEPARATION, "{"), "Using the definition type are not allowed", token); throw MyException("Expected type's name", token); } if(!struct_symbol){ struct_symbol = new StructSymbol(0, name); if(name.length() > 0) symStack->add_symbol(struct_symbol); } if(isEq(token, _SEPARATION, "{")){ errorIf(param, "Using the definition type are not allowed", token); errorIf(struct_symbol->m_fields, "Struct redefinetion", token); struct_symbol->m_fields = ParseStructBlock(); } return struct_symbol; }
VarSymbol* Parser :: ParseDirectDeclaration(){ VarSymbol *var_sym = 0; SymbolType *type = 0; while(isEq(scan.Get(), _OPERATION, "*") ) type = new PointerSymbol(type); if(isEq(scan.Get(), _SEPARATION, "(")){ scan.Next(); var_sym = ParseDirectDeclaration(); } else { errorIf(scan.Get()->Type != _IDENTIFIER, "Identifier expected", scan.Get()); errorIf(symStack->find_symbol(scan.Get()->Value), "Redefinition", scan.Get()); var_sym = new VarSymbol(scan.Get()->Value, 0); scan.Next(); } if(isEq(scan.Get(), _SEPARATION, "(")) type = createFunction("", type); else if(isEq(scan.Get(), _SEPARATION, "[")) type = ParseArrayDimension(type); if(!var_sym->type) var_sym->type = type; else { while(var_sym->type->upType()) var_sym->type = var_sym->type->upType(); var_sym->type->initType(type); } if(isEq(scan.Get(), _SEPARATION, ")")) scan.Next(); return var_sym; }
void Parser :: ParseArgList(){ Token *token =scan.GetNext(); while(!isEq(token, _SEPARATION, ")")){ ParseParam(); token = scan.Get(); if(isEq(token, _OPERATION, ",")) token =scan.GetNext(); else errorIf(!isEq(token, _SEPARATION, ")"), "Closing bracket expected", token); } scan.Next(); }
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); }
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; }
void MiniPS::dumpAdd3(GenBuffer::Writable &out, MiniPS::VALUE m, MiniPS::VALUE a, MiniPS::VALUE b, MiniPS::VALUE c, MiniPS::VALUE sub, unsigned rounding) { long ll; /* Sat Sep 7 15:30:28 CEST 2002 */ bool no_real_real=true; double d=0, dd; long l=0; if ((getType(m)==T_REAL && (isEq(m, 72) || isEq(m, -72))) || /* Imp: not so exact comparison */ (getType(m)==T_INTEGER && isEq(m, -72))) m = Qinteger(72); MiniPS::VALUE t[5], *tt; t[0]=a; t[1]=m; t[2]=b; t[3]=c; t[4]=sub; for (tt=t;tt<t+5;tt++) switch (getType(*tt)) { case T_REAL: dd=RREAL(*tt)->getBp(); doadd: if (no_real_real) { d=l; no_real_real=false; } if (tt==t+1) { /* multiply by m/72 or 72/-m */ if (dd==0.0 || d==0.0) { no_real_real=true; l=0; d=0.0; } else d *= dd >= 0 ? dd / 72 : 72 / -dd; } else if (tt==t+4) d-=dd; else d+=dd; break; case T_INTEGER: ll=int2ii(*tt); if (tt==t+1) { /* multiply by m/72 or 72/-m */ if (ll >= 0 && ll % 72 == 0) l *= ll / 72; else if (ll < 0 && 72 % -ll == 0) l *= 72 / -ll; else { dd=ll; goto doadd; } } else if (tt==t+4) l-=ll; else l+=ll; break; default: Error::sev(Error::EERROR) << "dumpAdd3: numbers expected" << (Error*)0; } if (no_real_real) { out << l; return; } if (rounding!=0) { ll=(long)d; if ((double)ll<d) ll++; assert((double)ll>=d); /* Imp: verify possible rounding errors */ out << (rounding>=2 && ll<0 ? 0 : ll); } else { char buf[64]; /* Dat: enough */ sprintf(buf, "%"PTS_CFG_PRINTFGLEN"g", d); out << buf; } }
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); }
VarSymbol* Parser :: ParseComplexDeclaration(SymbolType* start_type){ VarSymbol *var_sym = ParseDirectDeclaration(); if(isEq(scan.Get(), _SEPARATION, "(")) start_type = createFunction("", start_type); else if(isEq(scan.Get(), _SEPARATION, "[")) start_type = ParseArrayDimension(start_type); // if(scan.Get() == cl_bracket) // scan.Next(); if(!var_sym->type) var_sym->type = start_type; else { while(var_sym->type->upType()) var_sym->type = var_sym->type->upType(); var_sym->type->initType(start_type); } return var_sym; }
void PolyDDV::computeHull(PolyDDV& ddv) { if (ddv.getSize() != _types.size()) return; int i; for (i = 0; i < ddv.getSize(); ++i) { if (ddv.isPlus(i)) { if (isEq(i) || isScalar(i)) setPlus(i); else if (isMinus(i)) setStar(i); } else if (ddv.isMinus(i)) { if (isEq(i) || isScalar(i)) setMinus(i); else if (isPlus(i)) setStar(i); } else if (ddv.isStar(i)) setStar(i); else if (ddv.isScalar(i) && ! isStar(i)) { int s1 = ddv.getScalar(i); if (isScalar(i) || isEq(i)) { int s2 = 0; if (isScalar(i)) s2 = getScalar(i); if (s1 > 0 && s2 < 0 || s1 < 0 && s2 > 0) setStar(i); else if (s1 > 0 && s1 != s2) setPlus(i); else if (s1 < 0 && s1 != s2) setMinus(i); } else { if (s1 > 0 && isMinus(i) || s1 < 0 && isPlus(i)) setStar(i); } } } }
SymTable* Parser::ParseStructBlock(){ SymTable* structBlock = new SymTable(); symStack->push(structBlock); Token *token =scan.GetNext(); while(!isEq(scan.Get(), _SEPARATION, "}")){ ParseDeclaration(); VarSymbol* var = dynamic_cast<VarSymbol*> (symStack->top()->back()); if (dynamic_cast<StructSymbol*>(symStack->top()->back())) { continue; } errorIf(dynamic_cast<FuncSymbol*>(var->type), "No statements and function in struct", scan.Get()); errorIf(isEq(scan.Get(), _SEPARATION, ";")&& scan.isEnd(), "Unexpected brace",scan.Get()); } symStack->pop(); return structBlock; }
Block* Parser :: ParseBlock(){ Block *block = new Block(new SymTable()); symStack->push(block->table); blocks.push(block); if(isEq(scan.Get(), _SEPARATION, "{")){ Token *token =scan.GetNext(); while(!isEq(scan.Get(), _SEPARATION, "}") && !scan.isEnd()){ if((token->Value == "const" || token->Value == "struct" || symStack->find_type(token->Value)||token->Value == ";" ) &&(!dynamic_cast<FuncSymbol*>(symStack->find_type(token->Value)))) { ParseDeclaration(); } else { //ParseDeclaration(dynamic_cast<SymbolType*>(symStack->find_type(token->Value))); block->AddStatement(ParseStatement()); //isCanUseBreak = false; // scan.Next(); } token = scan.Get(); } } else { Token *token = scan.Get(); if(token->Value == "const" || token->Value == "struct" || symStack->find_type(token->Value)) ParseDeclaration(); else { block->AddStatement(ParseStatement()); //scan.Next(); symStack->pop(); return block; } } errorIf (!isEq(scan.Get(), _SEPARATION, "}"),"Unexpected brace", scan.Get()); blocks.pop(); symStack->pop(); return block; }
void Parser :: ParseParam(){ SymbolType *type = ParseType(true); Token *token =scan.Get(); errorIf(type->name == "void" && isEq(token, _OPERATION, "*") ,"Parameter can not be of type void", token); while(isEq(token, _OPERATION, "*")){ type = new PointerSymbol(type); token =scan.GetNext(); } if(isEq(token, _SEPARATION, "(")) type = dynamic_cast<SymbolType*>(ParseComplexDeclaration(type)); string name = token->Type == _IDENTIFIER ? token->Value : ""; if(name.length() > 0){ errorIf(symStack->top()->isExist(name), "Redefinition", token); token =scan.GetNext(); } if(isEq(token, _SEPARATION, "[")) type = ParseArrayDimension(type); symStack->add_symbol(new VarSymbol(name, type)); }
SymbolType* Parser :: ParseArrayDimension(SymbolType *type, bool param){ vector <int> index; auto token = scan.Get(); while(isEq(token, _SEPARATION, "[")){ token =scan.GetNext(); int size = token->Type == _INTEGER ? atoi(token->Value.c_str()) : 0; errorIf(size <= 0, "Array size must be int number higher than zero", token); //errorIf(size >= 1e5, "Array size exceeds the allowable", token); index.push_back(size); token =scan.GetNext(); errorIf(!isEq(token, _SEPARATION, "]"), "Closing bracket expected after the array index", token); token =scan.GetNext(); } for(int i = index.size() - 1; i >= 0; i--) type = new ArraySymbol(type, index[i]); return type; }
bool isPalindrome(string s) { if(s.length() == 0) return true; int begin = 0, end = s.length() -1; do{ while(begin < end && !isAlpha(s[begin])) begin++; while(begin < end && !isAlpha(s[end])) end--; while(begin < end && isEq(s[begin], s[end])){ begin++; end--; } }while(begin < end && !(isAlpha(s[begin]) && isAlpha(s[end]))); return begin >= end; }
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); }
Statement* Parser :: ParseJumpStatement(){ Statement *jump = 0; if(scan.Get()->Value =="return"){ ExprNode *arg = (!isEq(scan.GetNext(),_SEPARATION,";")) ? ParseExpr() : 0; jump = new ReturnStatement(arg); errorIf(!parsingFunc, "Unexpected return statement", scan.Get()); scan.Next(); return jump; }else if (scan.Get()->Value =="break"){ errorIf(!isCanUseBreak, "You can't use break", scan.Get()); jump = new BreakStatement(); } else if(scan.Get()->Value =="continue"){ errorIf(!isCanUseBreak, "You can't use continue",scan.Get()); jump = new ContinueStatement(); } errorIf(!isEq(scan.GetNext() ,_SEPARATION,";"), "Semicolon expected", scan.Get()); scan.Next(); return jump; }
int64_t Euler_52() { int d[10]; int num = 1000; int bignum = 10000; while (1 == 1) { while (num <= bignum / 6) { num++; int a[10]; arrayVal(num, a); arrayVal(num * 2, d); if (isEq(a, d)) continue; arrayVal(num * 3, d); if (isEq(a, d)) continue; arrayVal(num * 4, d); if (isEq(a, d)) continue; arrayVal(num * 5, d); if (isEq(a, d)) continue; arrayVal(num * 6, d); if (isEq(a, d)) continue; return (int64_t) num; } num = bignum; bignum *= 10; } }
// do the actual operation void BlockEquality::out(void) { LOG(LOG_EQ, 2,"EQ Execute"); // retrieve ports and signals pointers from the script datastructure float* signals = scriptHandler->getSignals(); ports_t* ports = scriptHandler->getPorts(); float in1 = signals[ports[blockId].in[0]]; float in2 = signals[ports[blockId].in[1]]; float out1 = isEq(in1,in2); float out2 = !((uint8_t)out1); signals[ports[blockId].out[0]] = out1; signals[ports[blockId].out[1]] = out2; LOG(LOG_EQ, 1,"EQ in1=%f, in2=%f, out1=%f, out2=%f",in1,in2,signals[ports[blockId].out[0]],signals[ports[blockId].out[1]]); }
SymbolType * Parser :: ParseType(bool param){ Token *token = scan.Get(); SymbolType *type = nullptr; bool Const = false; if ( token->Value =="typedef"){ scan.Next(); type = ParseType(); token = scan.Get(); type = new TypedefSymbol(type, token->Value); symStack->add_symbol(type); scan.Next(); return type; } while(token->Value == "const"){ Const = true; token = scan.GetNext(); // ParseDeclaration(); } if (token->Value == "double"){ token = new Token("float", _FLOAT, "float", "float", token->num, token->line); } if(token->Value == "struct") type = ParseStruct(param); else { type = dynamic_cast<SymbolType*>(symStack->find_type(token->Value)); errorIf(type == nullptr, "Unknown type", token); } while(isEq(scan.GetNext(), _OPERATION, "*")){ type = new PointerSymbol(type); token = scan.Get(); } if(Const){ type = new ConstSymbolType(type); } return type; }
bool isPalindrome(string s) { if(s.empty()) return true; size_t i = 0, j = s.size() - 1; for(;i < j;++i, --j){ while(i < j && !isAlphaNum(s[i])) ++i; if(i >= j) return true; while(i < j && !isAlphaNum(s[j])) --j; if(i >= j) return true; if(!isEq(s[i], s[j])) return false; } return true; }
bool PolyDDV::isIdenticalVector(PolyDDV& ddv) { if (ddv.getSize() != _types.size()) return false; int i; for (i = 0; i < ddv.getSize(); ++i) { if (ddv.isPlus(i) && ! isPlus(i)) return false; else if (ddv.isMinus(i) && ! isMinus(i)) return false; else if (ddv.isStar(i) && ! isStar(i)) return false; else if (ddv.isEq(i) && ! isEq(i)) return false; else if (ddv.isScalar(i)) { if (! isScalar(i) || getScalar(i) != ddv.getScalar(i)) return false; } } return true; }
void ut_slice(void) { useclass(Slice); UTEST_START("Slice") // equality and default args UTEST( Slice_isEqual(atSlice(10) , atSlice(0,10, 1)) ); UTEST( Slice_isEqual(atSlice(0,10), atSlice(0,10, 1)) ); UTEST(!Slice_isEqual(atSlice(0,10), atSlice(0,10,-1)) ); UTEST( Slice_isEqual(atSlice(0,10), atSlice(0,10, 0)) ); UTEST( gisEqual(aSlice(10) , aSlice(0,10, 1)) == True ); UTEST( gisEqual(aSlice(0,10), aSlice(0,10, 1)) == True ); UTEST( gisEqual(aSlice(0,10), aSlice(0,10,-1)) == False ); // new vs auto UTEST( isEq(gnewSlc(Slice, 0, 10, 1), aSlice(0,10,1)) ); UTEST(!isEq(gnewSlc(Slice, 0, 10, 1), aSlice(0,10,-1)) ); // clone vs auto UTEST( isEq(gclone(aSlice(10)), aSlice(10)) ); UTEST( isEq(gclone(aSlice(0,10)), aSlice(0,10)) ); UTEST( isEq(gclone(aSlice(0,10,-1)), aSlice(0,10,-1)) ); // eval UTEST( Slice_eval(atSlice(10),0) == 0 ); UTEST( Slice_eval(atSlice(10),1) == 1 ); UTEST( Slice_eval(atSlice(10),10) == 10 ); UTEST( Slice_eval(atSlice(1,10),0) == 1 ); UTEST( Slice_eval(atSlice(1,10),1) == 2 ); UTEST( Slice_eval(atSlice(1,10),10) == 11 ); UTEST( Slice_eval(atSlice(1,10,2),0) == 1 ); UTEST( Slice_eval(atSlice(1,10,2),1) == 3 ); UTEST( Slice_eval(atSlice(1,10,2),10) == 21 ); UTEST( Slice_eval(atSlice(10,1,-2),0) == 10 ); UTEST( Slice_eval(atSlice(10,1,-2),1) == 8 ); UTEST( Slice_eval(atSlice(10,1,-2),10) == -10 ); // first UTEST( Slice_first(atSlice(10)) == 0 ); UTEST( Slice_first(atSlice(1,10)) == 1 ); UTEST( Slice_first(atSlice(-1,10)) == (U32)-1 ); UTEST( Slice_first(atSlice(-1,-10)) == (U32)-1 ); // last UTEST( Slice_last(atSlice(10)) == 9 ); UTEST( Slice_last(atSlice(1,10)) == 10 ); UTEST( Slice_last(atSlice(1,10,2)) == 19 ); UTEST( Slice_last(atSlice(0,-10)) == (U32)-11 ); UTEST( Slice_last(atSlice(-1,-10)) == (U32)-12 ); // size UTEST( Slice_size(atSlice(0,9,1)) == 9 ); UTEST( Slice_size(atSlice(1,10,1)) == 10 ); UTEST( Slice_size(atSlice(1,10,2)) == 10 ); UTEST( Slice_size(atSlice(1,10,3)) == 10 ); UTEST( Slice_size(atSlice(1,9,3)) == 9 ); UTEST( Slice_size(atSlice(9,0,-1)) == 0 ); UTEST( Slice_size(atSlice(10,1,-1)) == 1 ); UTEST( Slice_size(atSlice(10,1,-2)) == 1 ); UTEST( Slice_size(atSlice(10,1,-3)) == 1 ); UTEST( Slice_size(atSlice(9,1,-3)) == 1 ); // slice vs range UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,1,1), 0), atSlice(-1,3,1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,1,2), 0), atSlice(-1,2,2)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,5,3), 0), atSlice(-1,3,3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,4,3), 0), atSlice(-1,2,3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange( 1,5,3), 0), atSlice( 1,2,3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,0,-1), 0), atSlice(9,10,-1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,1,-2), 0), atSlice(9,5,-2)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,0,-3), 0), atSlice(9,4,-3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,3,-3), 0), atSlice(9,3,-3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(0,9,1) , 0), atSlice(0,10,1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(1,10,1), 0), atSlice(1,10,1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(1,9,2) , 0), atSlice(1,5,2)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(1,10,3), 0), atSlice(1,4,3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(1,7,3) , 0), atSlice(1,3,3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,0,-1) , 0), atSlice(9,10,-1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(10,1,-1), 0), atSlice(10,10,-1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(10,2,-2), 0), atSlice(10,5,-2)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(10,1,-3), 0), atSlice(10,4,-3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,3,-3) , 0), atSlice(9,3,-3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,-10,-1), 0), atSlice(-1,10,-1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,-9,-2) , 0), atSlice(-1,5,-2)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,-10,-3), 0), atSlice(-1,4,-3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,-7,-3) , 0), atSlice(-1,3,-3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-10,-1,1), 0), atSlice(-10,10,1)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-10,-2,2), 0), atSlice(-10,5,2)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-10,-1,3), 0), atSlice(-10,4,3)) ); UTEST( eq(Slice_fromRange(atSlice(0), atRange(-9,-3,3) , 0), atSlice(-9,3,3)) ); UTEST_END }
static Statement *statement(void) { if (isId()) { Statement *p = NEW(Statement); p->kind = sAssignment; p->assignName = getId(); consume(); if (!isEq()) error(); consume(); p->assignValue = expression(); if (isSemi()) { consume(); } return p; } else if (isReturn()) { Statement *p = NEW(Statement); p->kind = sReturn; consume(); p->returnValue = expression(); if (isSemi()) { consume(); } return p; } else if (isLeftBlock()) { Statement *p = NEW(Statement); p->kind = sBlock; consume(); p->block = block(); if (!isRightBlock()) error(); consume(); return p; } else if (isPrint()) { Statement *p = NEW(Statement); p->kind = sPrint; consume(); p->printValue = expression(); if (isSemi()) { consume(); } return p; } else if (isIf()) { Statement *p = NEW(Statement); p->kind = sIf; consume(); p->ifCondition = expression(); p->ifThen = statement(); if (isElse()) { consume(); p->ifElse = statement(); } else { p->ifElse = 0; } return p; } else if (isWhile()) { Statement *p = NEW(Statement); p->kind = sWhile; consume(); /* while */ p->whileCondition = expression(); p->whileBody = statement(); return p; } else if (isSemi()) { Statement *p = NEW(Statement); p->kind = sBlock; p->block = 0; consume(); return p; } else { return 0; } }
bool IpAddr::operator==(const IpAddr& b) const { return isEq(b); }
ExprNode* Parser :: ParseExpr(int priority){ if (priority > 15) return ParseFactor(); ExprNode *left = ParseExpr(priority + 1); ExprNode *root = left; Token *op = scan.Get(); if(scan.isEnd() || isEq(op, _SEPARATION, "}") || isEq(op, _SEPARATION, ")") || isEq(op, _SEPARATION, "]") || isEq(op, _OPERATION, ":") || isEq(op, _SEPARATION, ";") || isEq(op, _SEPARATION, "{")){ //root->getType(); return root; } // if ( // isEq(op, _SEPARATION, ",")){ // scan.Next(); // // return root; // } errorIf(((op->Type != _OPERATION && op->Value != ",")) &&( op->Value !="(") &&(!isEq(op, _SEPARATION,"[")) , "Invalid expression. Operation expected",op); if(priorityTable[op->Value] < priority) return root; while(!scan.isEnd() && ((op->Type == _OPERATION && (priorityTable[op->Value] >= priority) && op->Value != "}") || op->Value =="(" || op->Value == "[")){ string oper = op->Value; if(oper == "("){ root = ParseFuncCall(root); } else if(oper == "["){ root = ParseArrIndex(root); break; } else if(oper == "--" ||oper == "++"){ root = new PostfixUnaryOpNode(op, root); scan.Next(); } else if(oper == "?"){ scan.Next(); ExprNode* l = ParseExpr(); if(scan.Get()->Value != ":") throw MyException("Invalid ternary operator", scan.Get()); scan.Next(); ExprNode* r = ParseExpr(); root = new TernaryOpNode(op, root, l, r); } else if(oper == "." || oper == "->") root = ParseMember(root); else { if(isEq(op, _SEPARATION, "]")) break; scan.Next(); root = new BinOpNode(op, root, ParseExpr(priority + 1)); } op = scan.Get(); } root->getType(); return root; }
ExprNode* Parser :: ParseFactor(){ ExprNode *root = nullptr; Token *token = scan.Get(); if(isEq(token, _SEPARATION, ";")) return 0; switch (token->Type){ case _INTEGER: root = new IntNode(token); break; case _FLOAT: root = new FloatNode(token); break; case _IDENTIFIER: { Symbol *sym = symStack->find_symbol(token->Value); if(!sym && parsingFunc) sym = parsingFunc->params->find_symbol(token->Value); string exc = "Identifier \"" + token->Value + "\" not defined"; errorIf(!sym, exc.c_str(), token); errorIf(!dynamic_cast<VarSymbol*>(sym) && !dynamic_cast<FuncSymbol*>(sym), "Unknown symbol", token); errorIf(!sym, "Identifier is undefined", token); root = new IdentifierNode(token, dynamic_cast<VarSymbol*>(sym)); if (dynamic_cast<PointerSymbol*>(sym->getType())) root = new PointerNode(root); if(isEq(scan.GetNext() ,_SEPARATION ,"(")) root = ParseFuncCall(root); //scan.Next(); return root; } case _CHAR: root = new CharNode(token); break; case _STRING: root = new StringNode(token); root->SetIndex(++index); stringConsts.push_back(dynamic_cast<StringNode*>(root)); break; case _KEYWORD: { string kw = token->Value; if(kw == "printf" || kw == "scanf"){ errorIf( scan.GetNext()->Value != "(", "Open bracket expected", token); scan.Next(); StringNode *format = dynamic_cast<StringNode*>(ParseExpr(priorityTable[","] + 1)); errorIf(!format, "Expected string format", token); IONode *node = new IONode(dynamic_cast<Token*>(token), format); if(scan.Get()->Value == ","){ scan.Next(); while(true){ ExprNode *arg = ParseExpr(priorityTable[","] + 1); errorIf (!arg, "Argument expected", token); node->addArg(arg); if(scan.Get()->Value == ")") break; if(scan.Get()->Value == ",") scan.Next(); } } scan.Next(); root = node; } else if(kw == "char" || kw == "int" || kw == "float"){ // scan.Next(); SymbolType* type = ParseType(); errorIf(isEq(scan.Get(), _SEPARATION, "("), "Expected open bracket '('", token); scan.Next(); root = new CastNode(token, ParseExpr(), type); // errorIf((isEq(scan.GetNext(), _SEPARATION, ")") && !scan.isEnd()), "Expected closing bracket", token); } else throw MyException("You can use keywords just such as char, int and float in expressions"); } break; case _OPERATION: if (token->Value == "*"){ scan.Next(); auto temp = ParseExpr(priorityTable["--"]); // if (dynamic_cast<PointerNode*>(temp)) // root = dynamic_cast<PointerNode*>(temp)->name; // root = temp; // else root = new PointerNode(temp); }else if(unary[token->Value]){ scan.Next(); root = new UnOpNode(token, ParseExpr(priorityTable["--"])); } else throw MyException("Wrong expression", token); break; case _SEPARATION : if(isEq(scan.Get(), _SEPARATION, "(")){ scan.Next(); root = ParseExpr(); if(dynamic_cast<CastNode*>(root)){ return root; } if(!isEq(scan.Get(), _SEPARATION, ")")) throw MyException("Expected closing bracket"); } else throw MyException("Wrong expression", token); break; } if (!(token->Type == _OPERATION && unary[token->Value]) && token->Value != "printf" && token->Value != "scanf") scan.Next(); root->getType(); return root; }
VarSymbol * Parser :: ParseIdentifier(SymbolType *type, bool param){ VarSymbol *result = 0; Token *token = scan.Get(); bool Const = false; Token* name = token; if(isEq(token, _SEPARATION, "(")) return ParseComplexDeclaration(type); while (isEq(token, _OPERATION, "*") || isEq(token, _OPERATION, "**") || token->Type == _CONST){ if(token->Type == _CONST) Const = true; else type = new PointerSymbol(type); token =scan.GetNext(); } // else{ token = scan.GetNext();} if (token->Type == _IDENTIFIER){ name = token; } errorIf(name->Type != _IDENTIFIER, "Identifier expected", token); token = scan.GetNext(); if(!isEq(token, _SEPARATION, "(")){ errorIf(type->name == "void", "Incomplete type is invalid", token); if(isEq(token, _SEPARATION, "[")) type = ParseArrayDimension(type); } else{ VarSymbol* buf = new VarSymbol(name->Value,type) ; if((symbolBuffer = symStack->tables.back()->find_symbol(name->Value)) != 0 ){ buf = dynamic_cast<VarSymbol*>(symbolBuffer); FuncSymbol* func = dynamic_cast<FuncSymbol*>(buf->type); errorIf(!CheckArgs(func), "Redefinition",token); errorIf(type != func->value, "banned over-the return value :" + func->name ,token ); result = new VarSymbol(name->Value, func); // errorIf(!(isEq(token, _SEPARATION, ",")|| isEq(token, _SEPARATION, ";") || isEq(token, _OPERATION, "=") ||isEq(token, _SEPARATION, "{")), // "Semicolon expected", scan.Get()); return result; } else type = createFunction(name->Value, type,Const); } if(Const) type = new ConstSymbolType(type); result = new VarSymbol(name->Value, type); // token = scan.GetNext(); errorIf(symStack->tables.back()->find_symbol(name->Value) != 0, "Redefinition", scan.Get()); errorIf(!(isEq(scan.Get(), _OPERATION, ",")|| isEq(scan.Get(), _SEPARATION, ";") || isEq(scan.Get(), _OPERATION, "=") ||isEq(scan.Get(), _SEPARATION, "{")), "Semicolon expected", scan.Get()); return result; }
ExprNode* Parser :: ParseDeclaration(SymbolType* sym_type){ if (isEq(scan.Get(), _SEPARATION, ";")){ scan.Next(); return nullptr; } SymbolType* t_symbol; if (!sym_type) { t_symbol = ParseType(); }else t_symbol = sym_type; VarSymbol* var = nullptr; BinOpNode *node = nullptr; while(true){ Token *token; token = scan.Get(); if(isEq(token, _SEPARATION, ";" )&& (t_symbol->isStruct() || dynamic_cast<TypedefSymbol*>(t_symbol))) break; if (isEq(scan.Get(), _SEPARATION,"(")) var = ParseComplexDeclaration(t_symbol); else var = ParseIdentifier(t_symbol); if(symStack->tables.back()->find_symbol(var->name) == 0) symStack->add_symbol(var); if(isEq(scan.Get(), _OPERATION, "=")){ Token *asgn = scan.Get(); scan.Next(); ExprNode* Assing_operand = ParseExpr(priorityTable[","] + 1); node = new BinOpNode(asgn, new IdentifierNode(token, var), Assing_operand); if(dynamic_cast<ConstSymbolType*> (var->getType())) errorIf(!var->getType()->getType()->canConvertTo(node->right->getType()),"Cannot perform conversion",scan.Get() ); else node->getType(); blocks.top()->AddStatement(node); } if(isEq(scan.Get() ,_SEPARATION, ";") || isEq(scan.Get() ,_SEPARATION, "{")) break; errorIf(!isEq(scan.Get(), _OPERATION, ","), "Comma Expected"); scan.Next(); } if(isEq (scan.Get(),_SEPARATION,"{")){ FuncSymbol *func = dynamic_cast<FuncSymbol*>(var->type); errorIf(!func, "Unexpected brace", scan.Get()); errorIf((symStack->tables.size() != 1), "Can not define the function in the block", scan.Get()); parsingFunc = func; func->body = ParseBlock(); parsingFunc = 0; CheckReturn(func); if(func->name == "main") main_func = func; scan.Next(); } else scan.Next(); return node; }