From 7a685e06344ac57005713d53e19e1cc2b852b8e9 Mon Sep 17 00:00:00 2001 From: IlyaShurupov Date: Thu, 8 Feb 2024 11:30:15 +0300 Subject: [PATCH] cfg accepting --- Language/public/ContextFreeAutomata.hpp | 70 ++++++++++++++++++++++++- Language/public/RegularAutomata.hpp | 42 +++++++++------ 2 files changed, 95 insertions(+), 17 deletions(-) diff --git a/Language/public/ContextFreeAutomata.hpp b/Language/public/ContextFreeAutomata.hpp index e1967e1..e9a0b9f 100644 --- a/Language/public/ContextFreeAutomata.hpp +++ b/Language/public/ContextFreeAutomata.hpp @@ -15,11 +15,79 @@ namespace tp { ualni num = 0; // state to shift (shift action) or pop count (reduce action) }; - Buffer2D mTable; + public: + struct StackItem { + ualni state = 0; + tAlphabetType symbol; + Buffer leafs; + }; + + struct AcceptResult { + bool accepted = false; + ualni advancedIdx = 0; + const StackItem* ast = nullptr; + }; public: ContextFreeAutomata() = default; + AcceptResult accept(const tAlphabetType* stream, ualni size) { + mCurrentState = mStartState; + mStack.append(&mItems.append({ mCurrentState, {}, {} })); + + ualni advancedIdx = 0; + while (advancedIdx < size) { + tAlphabetType& symbol = *(stream + advancedIdx); + + const Action& action = mTable.get({ ualni(symbol), mCurrentState }); + + switch (action.type) { + case Action::TRAP: return { false, advancedIdx, nullptr }; + case Action::REDUCE: + { + StackItem* newItem = &mItems.append({}); + for (auto iter : Range(action.num)) { + newItem->leafs.append(mStack.last()); + mCurrentState = mStack.last()->state; + mStack.pop(); + } + + if (!mStack.size()) { + if (advancedIdx == size) { + return { true, advancedIdx, newItem }; + } else { + return { false, advancedIdx, {} }; + } + } + + mStack.append(&mItems.append({ mCurrentState, {}, {} })); + break; + } + case Action::SHIFT: + { + mStack.last()->symbol = symbol; + mStack.append(&mItems.append({ mCurrentState, {}, {} })); + mCurrentState = action.num; + break; + } + } + + advancedIdx++; + } + + return { false, advancedIdx, nullptr }; + } + + public: void construct(const FiniteStateAutomation& automata) {} + + private: + Buffer2D mTable; + + Buffer mItems; + Buffer mStack; + + ualni mStartState = 0; + ualni mCurrentState = 0; }; } diff --git a/Language/public/RegularAutomata.hpp b/Language/public/RegularAutomata.hpp index c5b5b19..7b7e94f 100644 --- a/Language/public/RegularAutomata.hpp +++ b/Language/public/RegularAutomata.hpp @@ -7,21 +7,19 @@ namespace tp { - template + template class RegularAutomata { - - Buffer2D mTable; - Buffer> mStates; - - ualni mCurrentState = 0; - ualni mStartState = 0; - - Range mSymbolRange = { 0, 0 }; + public: + struct AcceptResult { + bool accepted = false; + ualni advancedIdx = 0; + tStateType state = tStateType(); + }; public: RegularAutomata() = default; - Pair accept(const tAlphabetType* stream, ualni size) { + AcceptResult accept(const tAlphabetType* stream, ualni size) { mCurrentState = mStartState; ualni advancedIdx = 0; @@ -30,28 +28,33 @@ namespace tp { tAlphabetType& symbol = *(stream + advancedIdx); if (!(symbol >= mSymbolRange.mBegin && symbol < mSymbolRange.mEnd)) { - return { tFailedStateVal, advancedIdx }; + return { false, advancedIdx, {} }; } mCurrentState = mTable.get({ (ualni) (symbol - mSymbolRange.mBegin), mCurrentState }); + if (mCurrentState == mStates.size()) { + return false; + } + if (mStates[mCurrentState].first) { - return { mStates[mCurrentState].second, advancedIdx }; + return { true, advancedIdx, mStates[mCurrentState].second }; } advancedIdx++; } - return { tFailedStateVal, advancedIdx }; + return { false, advancedIdx, {} }; } + public: void construct(const FiniteStateAutomation& automata) { const auto range = automata.getAlphabetRange(); mSymbolRange = { tAlphabetType(range.mBegin), tAlphabetType(range.mEnd) }; auto range_len = ualni(mSymbolRange.mEnd - mSymbolRange.mBegin); auto sizeX = range_len ? range_len : 1; - auto sizeY = (ualni) (automata.numStates() + 1); + auto sizeY = (ualni) (automata.numStates()); mTable.reserve({ sizeX, sizeY }); mTable.assign(automata.numStates()); @@ -63,8 +66,6 @@ namespace tp { idx++; } - mStates[automata.numStates()] = { true, tFailedStateVal }; - idx = 0; for (auto state : *automata.getStates()) { if (&state.data() == automata.getStartState()) { @@ -87,5 +88,14 @@ namespace tp { stateIdx++; } } + + private: + Buffer2D mTable; + Buffer> mStates; + + ualni mCurrentState = 0; + ualni mStartState = 0; + + Range mSymbolRange = { 0, 0 }; }; }