namespace tp { template void Parser::setIgnoreToken(tTokenType token) { mIgnoreToken = token; } template bool Parser::compileTables( const ContextFreeGrammar& cfGrammar, const ParserRegularGrammar& reGrammar, const Map& contextFreeToRegular ) { // Compile Regular Grammar { RegularGraph graph; ParserRegularCompiler compiler; compiler.compile(graph, reGrammar); graph.makeDeterministic(); mRegularAutomata.construct(graph); } // compile context free grammar { ContextFreeCompiler compiler; if (!compiler.compile(cfGrammar)) return false; mContextFreeAutomata.construct(compiler); // make glue for (auto symbol : *compiler.getSymbols()) { auto symbolId = compiler.getSymbolId(symbol->mId); if (symbol->mIsTerminal) { auto iter = contextFreeToRegular.presents(symbol->mId); if (!iter) { return false; } mGrammarGlue.put(contextFreeToRegular.getSlotVal(iter), symbolId); } else { mAstNames.put(symbolId, symbol->mId); } } } return true; } template auto Parser::parse(const tAlphabetType* sentence, ualni sentenceLength) -> ParseResult { // get tokens stream Buffer tokens; const tAlphabetType* sentenceIter = sentence; ualni lengthIter = sentenceLength; while (lengthIter) { auto result = mRegularAutomata.accept(sentenceIter, lengthIter); if (!result.accepted) { return { false, nullptr }; } if (result.state != mIgnoreToken) { if (!mGrammarGlue.presents(result.state)) { return { false, nullptr }; } tokens.append(ContextFreeCompiler::SymbolVal( mGrammarGlue.get(result.state), ualni(sentenceIter - sentence), result.advancedIdx )); } sentenceIter += result.advancedIdx; lengthIter -= result.advancedIdx; } ParserContextFreeAutomata::AcceptResult result = mContextFreeAutomata.accept(tokens.getBuff(), tokens.size()); return { result.accepted, result.ast }; } }