#include "Parsodus/parser.h" #include namespace pds { Parser::Parser(ParsodusLexer lex) : parsodusParser>(), m_lex(lex) { } Parser::Token Parser::lex() { try { ParsodusLexer::Token orig = m_lex.nextToken(); std::unique_ptr cnf; parsodusParser_Symbol s; switch(orig.type) { case ParsodusLexer::PARSER: s = parsodusParser_Symbol::T_PARSER; break; case ParsodusLexer::PRECEDENCE: s = parsodusParser_Symbol::T_PRECEDENCE; break; case ParsodusLexer::LEXESIS: s = parsodusParser_Symbol::T_LEXESIS; break; case ParsodusLexer::TERMINALS: s = parsodusParser_Symbol::T_TERMINALS; break; case ParsodusLexer::START: s = parsodusParser_Symbol::T_START; break; case ParsodusLexer::GRAMMAR: s = parsodusParser_Symbol::T_GRAMMAR; break; case ParsodusLexer::PARSERTYPE: cnf = std::make_unique(); cnf->parserType = orig.content; return Token{ parsodusParser_Symbol::T_PARSERTYPE, cnf }; case ParsodusLexer::LEFT: cnf = std::make_unique(); cnf->grammar.precedence["type"] = std::make_pair(0, PrecedenceType::LEFT); return Token{ parsodusParser_Symbol::T_LEFT, cnf }; case ParsodusLexer::RIGHT: cnf = std::make_unique(); cnf->grammar.precedence["type"] = std::make_pair(2, PrecedenceType::RIGHT); return Token{ parsodusParser_Symbol::T_RIGHT, cnf }; case ParsodusLexer::NONASSOC: cnf = std::make_unique(); cnf->grammar.precedence["type"] = std::make_pair(1, PrecedenceType::NONASSOC); return Token{ parsodusParser_Symbol::T_NONASSOC, cnf }; case ParsodusLexer::LEXESISNAME: s = parsodusParser_Symbol::T_LEXESISNAME; break; case ParsodusLexer::TERMINAL: cnf = std::make_unique(); cnf->grammar.terminals.insert(orig.content); return { parsodusParser_Symbol::T_TERMINAL, cnf }; case ParsodusLexer::VARIABLE: cnf = std::make_unique(); cnf->grammar.variables.insert(orig.content); return { parsodusParser_Symbol::T_VARIABLE, cnf }; case ParsodusLexer::ARROW: s = parsodusParser_Symbol::T_ARROW; break; case ParsodusLexer::SEMICOLON: s = parsodusParser_Symbol::T_SEMICOLON; break; case ParsodusLexer::COLON: s = parsodusParser_Symbol::T_COLON; break; case ParsodusLexer::PIPE: s = parsodusParser_Symbol::T_PIPE; break; case ParsodusLexer::RULENAME: cnf = std::make_unique(); cnf->grammar.rules.emplace_back(std::make_shared("", std::vector{}, orig.content)); return { parsodusParser_Symbol::T_RULENAME, cnf }; default: break; } return Token{ s, nullptr }; } catch(ParsodusLexer::NoMoreTokens) { return Token{ parsodusParser_Symbol::T_EOF, nullptr }; } } std::unique_ptr Parser::reduce_0(std::deque subparts) { //
// Check whether there are no different parserType's given if (subparts[0].value->parserType.empty()) subparts[0].value->parserType = subparts[1].value->parserType; else if (!subparts[1].value->parserType.empty() && subparts[1].value->parserType != subparts[0].value->parserType) throw "Found more than 1 different parser types"; // MODIFY EXCEPTION // Check whether there are no different lexesisFile's given if (subparts[0].value->lexesisFile.empty()) subparts[0].value->lexesisFile = subparts[1].value->lexesisFile; else if (!subparts[1].value->lexesisFile.empty() && subparts[1].value->lexesisFile != subparts[0].value->lexesisFile) throw "Found more than 1 different lexesis files"; // MODIFY EXCEPTION // Check whether there are no different grammar's given // Check whether there are no different start terminals given if (subparts[0].value->grammar.start.empty()) subparts[0].value->grammar.start = subparts[1].value->grammar.start; else if (!subparts[1].value->grammar.start.empty() && subparts[1].value->grammar.start != subparts[0].value->grammar.start) throw "Found more than 1 different start terminals"; // MODIFY EXCEPTION // Check whether there are no different variable sets given if (subparts[0].value->grammar.variables.empty()) subparts[0].value->grammar.variables = subparts[1].value->grammar.variables; else if (!subparts[1].value->grammar.variables.empty() && subparts[1].value->grammar.variables != subparts[0].value->grammar.variables) throw "Found more than 1 different variable sets"; // MODIFY EXCEPTION // Check whether there are no different terminal sets given if (subparts[0].value->grammar.terminals.empty()) subparts[0].value->grammar.terminals = subparts[1].value->grammar.terminals; else if (!subparts[1].value->grammar.terminals.empty() && subparts[1].value->grammar.terminals != subparts[0].value->grammar.terminals) throw "Found more than 1 different terminal sets"; // MODIFY EXCEPTION // Check whether there are no different rule sets given if (subparts[0].value->grammar.rules.empty()) subparts[0].value->grammar.rules = subparts[1].value->grammar.rules; else if (!subparts[1].value->grammar.rules.empty() && subparts[1].value->grammar.rules != subparts[0].value->grammar.rules) throw "Found more than 1 different rule sets"; // MODIFY EXCEPTION // Check whether there are no different precedence sets given if (subparts[0].value->grammar.precedence.empty()) subparts[0].value->grammar.precedence = subparts[1].value->grammar.precedence; else if (!subparts[1].value->grammar.precedence.empty() && subparts[1].value->grammar.precedence != subparts[0].value->grammar.precedence) throw "Found more than 1 different precedence sets"; // MODIFY EXCEPTION // REMARK: Everything is now put into subparts[0] // Set precedence of each rule for(std::shared_ptr& rule : subparts[0].value->grammar.rules) { if (rule->tail.size() == 0) rule->precedence = std::make_pair(false,std::make_pair(-1,PrecedenceType::LEFT)); auto prec = subparts[0].value->grammar.precedence.find(rule->tail.back()); if (prec != subparts[0].value->grammar.precedence.end()) rule->precedence = std::make_pair(true,prec); else rule->precedence = std::make_pair(false,prec); } // REMARK: No option yet for explicit rule precedence return std::move(subparts[0].value); } std::unique_ptr Parser::reduce_1(std::deque subparts) { // "PARSER" "COLON" "PARSERTYPE" return std::move(subparts[2].value); } std::unique_ptr Parser::reduce_2(std::deque subparts) { // "LEXESIS" "COLON" "LEXESISNAME" return std::move(subparts[2].value); } std::unique_ptr Parser::reduce_3(std::deque subparts) { // "TERMINALS" "COLON" return std::move(subparts[2].value); } std::unique_ptr Parser::reduce_4(std::deque subparts) { // "PRECEDENCE" "COLON" return std::move(subparts[2].value); } std::unique_ptr Parser::reduce_5(std::deque subparts) { // "START" "COLON" "TERMINAL" auto cnf = std::make_unique(); cnf->grammar.start = *subparts[2].value->terminals.begin(); return std::move(cnf); } std::unique_ptr Parser::reduce_6(std::deque subparts) { // "GRAMMAR" "COLON" return std::move(subparts[2].value); } std::unique_ptr Parser::reduce_7(std::deque subparts) { // "TERMINAL" subparts[1].value->grammar.terminals.insert(*subparts[0].value->grammar.terminals.begin()); return std::move(subparts[1].value); } std::unique_ptr Parser::reduce_8(std::deque subparts) { // "" return std::make_unique(); } std::unique_ptr Parser::reduce_9(std::deque subparts) { // auto other = std::move(subparts[2].value); subparts.pop_back(); std::unique_ptr cfg = reduce_10(std::move(subparts)); for(auto& p : cfg->grammar.precedence) other->grammar.precedence.insert(p); return std::move(other); } std::unique_ptr Parser::reduce_10(std::deque subparts) { // PrecedenceType typ = subparts[0].value->grammar.precedence["type"].second; for (std::string t : subparts[1].value->grammar.terminals) { subparts[1].value->grammar.precedence[t] = {m_precedenceCounter, typ}; } m_precedenceCounter++; return std::move(subparts[1].value); } std::unique_ptr Parser::reduce_11(std::deque subparts) { //"LEFT" return std::move(subparts[0].value); } std::unique_ptr Parser::reduce_12(std::deque subparts) { // "RIGHT" return std::move(subparts[0].value); } std::unique_ptr Parser::reduce_13(std::deque subparts) { // "NONASSOC" return std::move(subparts[0].value); } std::unique_ptr Parser::reduce_14(std::deque subparts) { // subparts[1].value->grammar.rules.emplace_back(std::move(subparts[0].value->grammar.rules[0])); return std::move(subparts[1].value); } std::unique_ptr Parser::reduce_15(std::deque subparts) { // return std::move(subparts[0].value); } std::unique_ptr Parser::reduce_16(std::deque subparts) { //"VARIABLE" "ARROW" std::string head = subparts[0].value->grammar.rules[0]->head; subparts[0].value->grammar.rules.clear(); for(std::shared_ptr rule : subparts[2].value->grammar.rules) subparts[0].value->grammar.rules.push_back(std::make_shared(Rule(head, rule->tail, rule->name))); // SOMETHING WRONG WITH THIS STATEMENT return std::move(subparts[0].value); } std::unique_ptr Parser::reduce_17(std::deque subparts) { // "PIPE" for(auto rule : subparts[2].value->grammar.rules) subparts[0].value->grammar.rules.push_back(rule); return std::move(subparts[0].value); } std::unique_ptr Parser::reduce_18(std::deque subparts) { // return std::move(subparts[0].value); } std::unique_ptr Parser::reduce_19(std::deque subparts) { // "RULENAME" subparts[0].value->grammar.rules[0]->name = subparts[1].value->grammar.rules[0]->name; return std::move(subparts[0].value); } std::unique_ptr Parser::reduce_20(std::deque subparts) { // return std::move(subparts[0].value); } std::unique_ptr Parser::reduce_21(std::deque subparts) { // "VARIABLE" subparts[0].value->grammar.rules[0]->tail.push_back(subparts[1].value->grammar.rules[0]->tail[0]); return std::move(subparts[0].value); } std::unique_ptr Parser::reduce_22(std::deque subparts) { // "TERMINAL" subparts[0].value->grammar.rules[0]->tail.push_back(subparts[1].value->grammar.rules[0]->tail[0]); return std::move(subparts[0].value); } std::unique_ptr Parser::reduce_23(std::deque subparts) { // "" auto cnf = std::make_unique(); cnf->grammar.rules.emplace_back(std::make_shared("", {})); return std::move(subparts[0].value); } }