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; }
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; }