Modules/Language/private/Parser.ipp
Шурупов Илья Викторович 5fce4b2074 Language: reorganize code
2026-10-08 18:09:18 +03:00

76 lines
No EOL
2.5 KiB
C++

namespace tp {
template <typename tAlphabetType, typename tTokenType, tTokenType tInTransition, ualni MinSymbol, ualni MaxSymbol>
void Parser<tAlphabetType, tTokenType, tInTransition, MinSymbol, MaxSymbol>::setIgnoreToken(tTokenType token) { mIgnoreToken = token; }
template <typename tAlphabetType, typename tTokenType, tTokenType tInTransition, ualni MinSymbol, ualni MaxSymbol>
bool Parser<tAlphabetType, tTokenType, tInTransition, MinSymbol, MaxSymbol>::compileTables(
const ContextFreeGrammar& cfGrammar,
const ParserRegularGrammar& reGrammar,
const Map<String, tTokenType>& 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 <typename tAlphabetType, typename tTokenType, tTokenType tInTransition, ualni MinSymbol, ualni MaxSymbol>
auto Parser<tAlphabetType, tTokenType, tInTransition, MinSymbol, MaxSymbol>::parse(const tAlphabetType* sentence, ualni sentenceLength) -> ParseResult {
// get tokens stream
Buffer<ContextFreeCompiler::SymbolVal> 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 };
}
}