string StringUtil::capitalizedCopy(const string& str) { string strn(str); capitalized(strn); return strn; }
void CodeGenerator::visitOperator(Model::OperatorItem *node) { out << "bool expectOperator = false;" << "while(true) {" << "if(expectOperator) {" << " "; const QString capNode = capitalized(node->mName); const QString nodeType = capNode + "Ast"; const QString baseNameC = node->mBase->mSymbol->mCapitalizedName; const QString baseType = baseNameC + "Ast"; Model::NonTerminalItem ntItem; ntItem.mSymbol = mSym; ntItem.kind = Model::NodeKindNonTerminal; { QTextStream argStr(&ntItem.mArguments); GenerateRecursiveDelegation del(argStr); } bool printElse = false; for(auto i = node->mPost.begin(); i != node->mPost.end(); ++i) { if(printElse) out << "else "; printElse = true; out << "if("; generateTestCondition(i->op.mTok, out); if(i->op.mCond.size() != 0) out << " && " << i->op.mCond; out << ") { const unsigned int priority = " << i->priority << ";"; out << i->op.mCode; out << "AstNode *last = 0; bool br = false;"; out << "while(priority < opStack.last().p + " << i->left << ") {"; out << "if(opStack.size() == 1) {" "if(last)\n" "opStack.last().n->endToken = last->endToken;" "last = opStack.last().n;" "opStack.pop_back();" "opStack.push_front(OperatorStackItem((*yynode) = create<Postfix"<< nodeType << ">(last), -2));" "(*yynode)->endToken = last->endToken + 1;" "(*yynode)->startToken = last->startToken;" "br = true; break; } else {" "AstNode *olast = last;" "last = opStack.last().n;\n" "if(olast)\nlast->endToken = olast->endToken;" "opStack.pop_back(); }}"; out << "if(!br) { " "opStack.last().n->endToken = last->endToken;" << "AstNode*& ref = opStack.last().n->kind == AstNode::Binary" << capNode << "Kind && ((Binary" << nodeType << "*)opStack.last().n)->second ? ((Binary" << nodeType << "*)opStack.last().n)->second : ((Binary" << nodeType << "*)opStack.last().n)->first;\n" << "opStack.push_back(OperatorStackItem(ref = create<Postfix" << nodeType << ">(last), -2));" "ref->endToken = last->endToken + 1;" "ref->startToken = last->startToken;" "} yylex(); }"; } for(auto i = node->mBin.begin(); i != node->mBin.end(); ++i) { if(printElse) out << "else "; printElse = true; out << "if("; generateTestCondition(i->op.mTok, out); if(i->op.mCond.size() != 0) out << " && " << i->op.mCond; out << ") { const unsigned int priority = " << i->priority << ";"; out << i->op.mCode; out << "AstNode *last = 0; bool br = false;"; out << "while(priority < opStack.last().p + " << i->left << ") {"; out << "if(opStack.size() == 1) {" "if(last)\n" "opStack.last().n->endToken = last->endToken;" "last = opStack.last().n;\n" "opStack.pop_back();" "opStack.push_front(OperatorStackItem((*yynode) = create<Binary" << nodeType << ">(last), priority));" "(*yynode)->startToken = last->startToken;" "br = true; break; } else {" "AstNode *olast = last;" "last = opStack.last().n;\n" "if(olast)\nlast->endToken = olast->endToken;" "opStack.pop_back(); }}"; out << "if(!br) { " "opStack.last().n->endToken = last->endToken;" << "AstNode*& ref = " "opStack.last().n->kind == AstNode::Ternary" << capNode << "Kind" " ? (((Ternary" << nodeType << "*)opStack.last().n)->third" " ? ((Ternary" << nodeType << "*)opStack.last().n)->third" " : (((Ternary" << nodeType << "*)opStack.last().n)->second" " ? ((Ternary" << nodeType << "*)opStack.last().n)->second" " : ((Ternary" << nodeType << "*)opStack.last().n)->first ))" " : opStack.last().n->kind == AstNode::Binary" << capNode << "Kind" " && ((Binary" << nodeType << "*)opStack.last().n)->second" " ? ((Binary" << nodeType << "*)opStack.last().n)->second" " : ((Binary" << nodeType << "*)opStack.last().n)->first;\n" << "opStack.push_back(OperatorStackItem(ref = create<Binary" << nodeType << ">(last), priority)); ref->startToken = last->startToken; } expectOperator = false; yylex(); }"; } for(auto i = node->mTern.begin(); i != node->mTern.end(); ++i) { if(printElse) out << "else "; printElse = true; out << "if("; generateTestCondition(i->first.mTok, out); if(i->first.mCond.size() != 0) out << " && " << i->first.mCond; out << ") { const unsigned int priority = " << i->priority << ";"; out << i->first.mCode; out << "AstNode *last = 0; bool br = false;"; out << "while(priority < opStack.last().p + " << i->left << ") {"; out << "if(opStack.size() == 1) {" "if(last)\n" "opStack.last().n->endToken = last->endToken;" "last = opStack.last().n;\n" "opStack.pop_back();" "opStack.push_front(OperatorStackItem((*yynode) = create<Ternary" << nodeType << ">(last), priority));" "(*yynode)->startToken = last->startToken;" "yylex();"; QString __var = generateParserCall(&ntItem, mCurrentCatchId, out); out << "if(!("; generateTestCondition(i->second.mTok, out); if(i->second.mCond.size() != 0) out << " && " << i->second.mCond; out << ")) return false;" "((Ternary" << nodeType << "*)*yynode)->second = " << __var << ";br = true; break; } else {" "AstNode *olast = last;" "last = opStack.last().n;\n" "if(olast)\nlast->endToken = olast->endToken;" "opStack.pop_back(); }}"; out << "if(!br) { " "opStack.last().n->endToken = last->endToken;" << "AstNode*& ref = " "opStack.last().n->kind == AstNode::Ternary" << capNode << "Kind" " ? (((Ternary" << nodeType << "*)opStack.last().n)->third" " ? ((Ternary" << nodeType << "*)opStack.last().n)->third" " : (((Ternary" << nodeType << "*)opStack.last().n)->second" " ? ((Ternary" << nodeType << "*)opStack.last().n)->second" " : ((Ternary" << nodeType << "*)opStack.last().n)->first ))" " : opStack.last().n->kind == AstNode::Binary" << capNode << "Kind" " && ((Binary" << nodeType << "*)opStack.last().n)->second" " ? ((Binary" << nodeType << "*)opStack.last().n)->second" " : ((Binary" << nodeType << "*)opStack.last().n)->first;\n" << "opStack.push_back(OperatorStackItem(ref = create<Ternary" << nodeType << ">(last), priority)); ref->startToken = last->startToken; } expectOperator = false; yylex(); }"; } out << "else "; out << "break;"; out << "} else {"; printElse = false; for(auto i = node->mPre.begin(); i != node->mPre.end(); ++i) { if(printElse) out << "else "; printElse = true; out << "if("; generateTestCondition(i->op.mTok, out); if(i->op.mCond.size() != 0) out << " && " << i->op.mCond; out << ") { const unsigned int priority = " << i->priority << ";"; out << i->op.mCode << "Prefix" << nodeType << " *node = create<Prefix" << nodeType << ">();" "if(opStack.empty())\n" "(*yynode) = node;" "else" "{\n" "void *last = opStack.last().n;" "if(reinterpret_cast<Prefix" << nodeType << "*>(last)->first == 0)\n" "reinterpret_cast<Prefix" << nodeType << "*>(last)->first = node;" "else if(reinterpret_cast<Binary" << nodeType << "*>(last)->second == 0)\n" "reinterpret_cast<Binary" << nodeType << "*>(last)->second = node;" "else\n" "reinterpret_cast<Ternary" << nodeType << "*>(last)->third = node;" "}" "opStack.push_back(OperatorStackItem(node, priority));" "node->startToken = tokenStream->index() - 1;" "yylex();" "}" << endl; } for(auto i = node->mParen.begin(); i != node->mParen.end(); ++i) { if(printElse) out << "else "; printElse = true; out << "if("; generateTestCondition(i->first.mTok, out); if(i->first.mCond.size() != 0) out << " && " << i->first.mCond; out << ") { yylex();" "if("; generateTestCondition(mSym, out); out << ") {"; QString __var = generateParserCall(&ntItem, mCurrentCatchId, out); out << "if(!("; generateTestCondition(i->second.mTok, out); if(i->second.mCond.size() != 0) out << " && " << i->second.mCond; out << ")) {" "return false;" "}" "--" << __var << "->startToken;" "++" << __var << "->endToken;" "yylex();"; #define PUSH_UNARY \ out << "\ if(!opStack.isEmpty())\ {\ void *last = opStack.last().n;\ if(reinterpret_cast<Prefix" << nodeType << "*>(last)->first == 0)\n\ reinterpret_cast<Prefix" << nodeType << "*>(last)->first = " << __var << ";" << endl; \ out << "else if(reinterpret_cast<Binary" << nodeType << "*>(last)->second == 0)\n\ reinterpret_cast<Binary" << nodeType << "*>(last)->second = " << __var << ";\ else\nreinterpret_cast<Ternary" << nodeType << "*>(last)->third = " << __var << ";}\ else\n\ (*yynode) = " << __var << ";\ opStack.push_back(OperatorStackItem(" << __var << ", -2));"; PUSH_UNARY out << "expectOperator = true; } else\nreturn false; }"; } if(printElse) out << "else "; out << "if("; generateTestCondition(node->mBase->mSymbol, out); out << ") { "; QString __var = generateParserCall(node->mBase, mCurrentCatchId, out); PUSH_UNARY #undef PUSH_UNARY out << "expectOperator = true; }"; out << "else" "{" "expectedSymbol(AstNode::" << capNode << "Kind" ", \"" << node->mName << "\");return false;" "} } }"; /// @TODO Further: empty binary operator }