void Parser::buildStatement(Statement** toBuild, TokenSequence* relatedSequence) { if (StatementSetValue::first()->isSet(relatedSequence->tokenAt(0, false))) { *toBuild = new StatementSetValue(); ((StatementSetValue*)(*toBuild))->identifier = relatedSequence->tokenAt(0, false); TokenSequence* exceptIdentifier = nullptr; TokenSequence* isolatedIdentifier = relatedSequence->splitOn(0, &exceptIdentifier); if (isolatedIdentifier != nullptr) { isolatedIdentifier->prepareDelete(true); delete isolatedIdentifier; } TokenSequence* assigningCore = nullptr; TokenSequence* indexPart = exceptIdentifier->splitOn(ParseTree::splitIndexes->pop(), &assigningCore); if (exceptIdentifier != nullptr) { exceptIdentifier->prepareDelete(true); delete exceptIdentifier; } ((StatementSetValue*)(*toBuild))->index = this->buildIndex(indexPart); if (indexPart != nullptr) { indexPart->prepareDelete(true); delete indexPart; } TokenSequence* expression = nullptr; TokenSequence* assignment = assigningCore->splitOn(0, &expression); if (assigningCore != nullptr) { assigningCore->prepareDelete(true); delete assigningCore; } if (assignment != nullptr) { assignment->prepareDelete(true); delete assignment; } ((StatementSetValue*)(*toBuild))->aimValue = this->buildExp(expression); if (expression != nullptr) { expression->prepareDelete(true); delete expression; } } else if (StatementWrite::first()->isSet(relatedSequence->tokenAt(0, false))) { *toBuild = new StatementWrite(); TokenSequence* exp = nullptr; TokenSequence* preExp = relatedSequence->splitOn(1, &exp); TokenSequence* postExp = nullptr; TokenSequence* actualExp = exp->splitOn(exp->getSize() - 2, &postExp); ((StatementWrite*)(*toBuild))->toPrint = this->buildExp(actualExp); if (exp != nullptr) { exp->prepareDelete(true); delete exp; } if (actualExp != nullptr) { actualExp->prepareDelete(true); delete actualExp; } if (preExp != nullptr) { preExp->prepareDelete(true); delete preExp; } if (postExp != nullptr) { postExp->prepareDelete(true); delete postExp; } } else if (StatementRead::first()->isSet(relatedSequence->tokenAt(0, false))) { *toBuild = new StatementRead(); TokenSequence* sub = nullptr; TokenSequence* post = nullptr; TokenSequence* pre = relatedSequence->splitOn(2, &sub); TokenSequence* core = sub->splitOn(sub->getSize()-2, &post); ((StatementRead*)(*toBuild))->identifier = pre->tokenAt(2, false); ((StatementRead*)(*toBuild))->index = this->buildIndex(core); if (sub != nullptr) { sub->prepareDelete(true); delete sub; } if (pre != nullptr) { pre->prepareDelete(true); delete pre; } if (core != nullptr) { core->prepareDelete(true); delete core; } if (post != nullptr) { post->prepareDelete(true); delete post; } } else if (StatementBlock::first()->isSet(relatedSequence->tokenAt(0, false))) { *toBuild = new StatementBlock(); TokenSequence* subcore0 = nullptr; TokenSequence* preBrace = relatedSequence->splitOn(0, &subcore0); if (preBrace != nullptr) { preBrace->prepareDelete(true); delete preBrace; } TokenSequence* postBrace = nullptr; TokenSequence* statementCore = subcore0->splitOn(subcore0->getSize() - 2, &postBrace); Statements* currentStatements = ((StatementBlock*)(*toBuild))->blockContent; if (statementCore->getSize() != 0) { currentStatements = new StatementsSeq(); TokenSequence* singleStatement = nullptr; TokenSequence* rest0 = nullptr; TokenSequence* semicolon = nullptr; TokenSequence* otherStatements = nullptr; do { singleStatement = statementCore->splitOn(ParseTree::splitIndexes->pop(), &rest0); semicolon = rest0->splitOn(0, &otherStatements); this->buildStatement(&(((StatementsSeq*)currentStatements)->firstStatement), singleStatement); ((StatementsSeq*) currentStatements)->restOfStatements = (otherStatements->getSize() == 0 ? ((Statements*)new StatementsSeq()) : ((Statements*)new StatementsEps())); if (singleStatement != nullptr) { singleStatement->prepareDelete(true); delete singleStatement; } if (rest0 != nullptr) { rest0->prepareDelete(true); delete rest0; } if (semicolon != nullptr) { semicolon->prepareDelete(true); delete semicolon; } if (statementCore != nullptr) { statementCore->prepareDelete(true); delete statementCore; } statementCore = otherStatements; currentStatements = ((StatementsSeq*) currentStatements)->restOfStatements; } while(!currentStatements->isEps()); } else { currentStatements = new StatementsEps(); } } else if (StatementIfElse::first()->isSet(relatedSequence->tokenAt(0, false))) { *toBuild = new StatementIfElse(); TokenSequence* majorPrefix = nullptr; TokenSequence* elseStatement = nullptr; TokenSequence* elsePart = nullptr; TokenSequence* ifAndItsStatement = nullptr; TokenSequence* ifPart = nullptr; TokenSequence* semiCore = nullptr; TokenSequence* ifExpression = nullptr; TokenSequence* endOfIf = nullptr; TokenSequence* core = nullptr; TokenSequence* ifStatement = nullptr; majorPrefix = relatedSequence->splitOn(ParseTree::splitIndexes->pop(), &elseStatement); this->buildStatement(&(((StatementIfElse*)(*toBuild))->elseCase), elseStatement); if (elseStatement != nullptr) { elseStatement->prepareDelete(true); delete elseStatement; } ifAndItsStatement = majorPrefix->splitOn(majorPrefix->getSize() - 3, &elsePart); if (majorPrefix != nullptr) { majorPrefix->prepareDelete(true); delete majorPrefix; } if (elsePart != nullptr) { elsePart->prepareDelete(true); delete elsePart; } ifPart = ifAndItsStatement->splitOn(1, &semiCore); if (ifAndItsStatement != nullptr) { ifAndItsStatement->prepareDelete(true); delete ifAndItsStatement; } if (ifPart != nullptr) { ifPart->prepareDelete(true); delete ifPart; } ifExpression = semiCore->splitOn(ParseTree::splitIndexes->pop(), &endOfIf); ((StatementIfElse*)(*toBuild))->condition = this->buildExp(ifExpression); if (ifExpression != nullptr) { ifExpression->prepareDelete(true); delete ifExpression; } if (semiCore != nullptr) { semiCore->prepareDelete(true); delete semiCore; } core = endOfIf->splitOn(0, &ifStatement); if (core != nullptr) { core->prepareDelete(true); delete core; } if (endOfIf != nullptr) { endOfIf->prepareDelete(true); delete endOfIf; } this->buildStatement(&(((StatementIfElse*)(*toBuild))->thenCase), ifStatement); if (ifStatement != nullptr) { ifStatement->prepareDelete(true); delete ifStatement; } } else if (StatementWhile::first()->isSet(relatedSequence->tokenAt(0, false))) { *toBuild = new StatementWhile(); TokenSequence* remainings = nullptr; TokenSequence* whileBeginning = relatedSequence->splitOn(1, &remainings); if (whileBeginning != nullptr) { whileBeginning->prepareDelete(true); delete whileBeginning; } TokenSequence* parStat = nullptr; TokenSequence* exp = remainings->splitOn(ParseTree::splitIndexes->pop(), &parStat); TokenSequence* statement = nullptr; TokenSequence* paranth = parStat->splitOn(0, &statement); if (paranth != nullptr) { paranth->prepareDelete(true); delete paranth; } ((StatementWhile*)(*toBuild))->condition = this->buildExp(exp); this->buildStatement(&(((StatementWhile*)(*toBuild))->loop), statement); if (exp != nullptr) { exp->prepareDelete(true); delete exp; } if (statement != nullptr) { statement->prepareDelete(true); delete statement; } } }
ParseTree* Parser::parse() { if (this->currentCodeSnippet == nullptr) { throw "Undefined file for parser\n"; } if (!ProgOnly::isMatching(this->currentCodeSnippet)) { std::cerr << "error some spot: syntax error type 2 (invalid token composition)\n"; exit(1); } // if it does match, the entire code (in the test file) is OK and all dynamic indexes the Parser must split the sequence on are in ParseTree::splitIndexes ProgOnly* prog = new ProgOnly(); TokenSequence* statementPart = nullptr; TokenSequence* declarationPart = this->currentCodeSnippet->splitOn(ParseTree::splitIndexes->pop(), &statementPart); if (Decls::first()->isSet(this->currentCodeSnippet->tokenAt(0, false))) { prog->declarationSegment = new DeclsSeq(); TokenSequence* singleDeclaration = nullptr; TokenSequence* rest0 = nullptr; TokenSequence* semicolon = nullptr; TokenSequence* otherDeclarations = nullptr; Decls* currentDecls = prog->declarationSegment; do { singleDeclaration = declarationPart->splitOn(ParseTree::splitIndexes->pop(), &rest0); semicolon = rest0->splitOn(0, &otherDeclarations); ((DeclsSeq*) currentDecls)->firstDeclaration = new DeclOnly(); this->buildDecl(&(((DeclsSeq*)currentDecls)->firstDeclaration), singleDeclaration); ((DeclsSeq*) currentDecls)->restOfDeclarations = (otherDeclarations->getSize() == 0 ? ((Decls*)new DeclsSeq()) : ((Decls*)new DeclsEps())); if (singleDeclaration != nullptr) { singleDeclaration->prepareDelete(true); delete singleDeclaration; } if (rest0 != nullptr) { rest0->prepareDelete(true); delete rest0; } if (semicolon != nullptr) { semicolon->prepareDelete(true); delete semicolon; } if (declarationPart != nullptr) { declarationPart->prepareDelete(true); delete declarationPart; } declarationPart = otherDeclarations; currentDecls = ((DeclsSeq*) currentDecls)->restOfDeclarations; } while(!currentDecls->isEps()); } else { prog->declarationSegment = new DeclsEps(); } if (statementPart->getSize() != 0) { prog->statementSegment = new StatementsSeq(); TokenSequence* singleStatement = nullptr; TokenSequence* rest0 = nullptr; TokenSequence* semicolon = nullptr; TokenSequence* otherStatements = nullptr; Statements* currentStatements = prog->statementSegment; do { singleStatement = statementPart->splitOn(ParseTree::splitIndexes->pop(), &rest0); semicolon = rest0->splitOn(0, &otherStatements); this->buildStatement(&(((StatementsSeq*)currentStatements)->firstStatement), singleStatement); ((StatementsSeq*) currentStatements)->restOfStatements = (otherStatements->getSize() == 0 ? ((Statements*)new StatementsSeq()) : ((Statements*)new StatementsEps())); if (singleStatement != nullptr) { singleStatement->prepareDelete(true); delete singleStatement; } if (rest0 != nullptr) { rest0->prepareDelete(true); delete rest0; } if (semicolon != nullptr) { semicolon->prepareDelete(true); delete semicolon; } if (statementPart != nullptr) { statementPart->prepareDelete(true); delete statementPart; } statementPart = otherStatements; currentStatements = ((StatementsSeq*) currentStatements)->restOfStatements; } while(!currentStatements->isEps()); } else { prog->statementSegment = new StatementsEps(); } if (declarationPart != nullptr) { declarationPart->prepareDelete(true); delete declarationPart; } if (statementPart != nullptr) { statementPart->prepareDelete(true); delete statementPart; } std::cout << "Parsing works\n"; return prog; }