refactor regular automata

This commit is contained in:
IlyaShurupov 2024-02-08 10:52:28 +03:00 committed by Ilya Shurupov
parent b883f0029c
commit 2ebf650381
2 changed files with 37 additions and 55 deletions

View file

@ -10,6 +10,13 @@ namespace tp {
template <typename tAlphabetType, typename tStateType> template <typename tAlphabetType, typename tStateType>
class ContextFreeAutomata { class ContextFreeAutomata {
struct Action {
enum Type { SHIFT, REDUCE, TRAP } type = TRAP;
ualni num = 0; // state to shift (shift action) or pop count (reduce action)
};
Buffer2D<Action> mTable;
public: public:
ContextFreeAutomata() = default; ContextFreeAutomata() = default;

View file

@ -7,66 +7,42 @@
namespace tp { namespace tp {
template <typename tAlphabetType, typename tStateType, tStateType tNoStateVal, tStateType tFailedStateVal> template <typename tAlphabetType, typename tStateType, tStateType tFailedStateVal>
class RegularAutomata { class RegularAutomata {
static_assert(TypeTraits<tAlphabetType>::isIntegral, "tAlphabetType must be enumerable."); Buffer2D<ualni> mTable;
Buffer<Pair<bool, tStateType>> mStates;
ualni mCurrentState = 0;
ualni mStartState = 0;
Buffer2D<ualni> mTransitions;
Buffer<tStateType> mStates;
Range<tAlphabetType> mSymbolRange = { 0, 0 }; Range<tAlphabetType> mSymbolRange = { 0, 0 };
ualni mIter = 0;
ualni mIterPrev = 0;
ualni mStart = 0;
public: public:
RegularAutomata() = default; RegularAutomata() = default;
auto getStates() const { return &mStates; } Pair<tStateType, ualni> accept(const tAlphabetType* stream, ualni size) {
auto getTransitions() const { return &mTransitions; } mCurrentState = mStartState;
auto getStart() const { return mStart; }
bool isTrapped() { return mStates[mIter] == tFailedStateVal; } ualni advancedIdx = 0;
tStateType move(tAlphabetType symbol) { while (advancedIdx < size) {
if (symbol >= mSymbolRange.mBegin && symbol < mSymbolRange.mEnd) { tAlphabetType& symbol = *(stream + advancedIdx);
mIter = mTransitions.get({ (ualni) (symbol - mSymbolRange.mBegin), (ualni) mIter });
} else { if (!(symbol >= mSymbolRange.mBegin && symbol < mSymbolRange.mEnd)) {
mIter = mStates.size() - 1; return { tFailedStateVal, advancedIdx };
}
mCurrentState = mTable.get({ (ualni) (symbol - mSymbolRange.mBegin), mCurrentState });
if (mStates[mCurrentState].first) {
return { mStates[mCurrentState].second, advancedIdx };
}
advancedIdx++;
} }
if (mIterPrev == mStart) { return { tFailedStateVal, advancedIdx };
if (mStates[mIter] == tFailedStateVal) {
reset();
return tFailedStateVal;
} else {
mIterPrev = mIter;
return tNoStateVal;
}
} else {
if (mStates[mIter] == tFailedStateVal) {
if (mStates[mIterPrev] != tNoStateVal) {
auto out = mStates[mIterPrev];
reset();
return out;
} else {
reset();
return tFailedStateVal;
}
} else {
mIterPrev = mIter;
return tNoStateVal;
}
}
mIterPrev = mIter;
return mStates[mIter];
}
void reset() {
mIter = mStart;
mIterPrev = mStart;
} }
void construct(const FiniteStateAutomation<tAlphabetType, tStateType>& automata) { void construct(const FiniteStateAutomation<tAlphabetType, tStateType>& automata) {
@ -77,23 +53,22 @@ namespace tp {
auto sizeX = range_len ? range_len : 1; auto sizeX = range_len ? range_len : 1;
auto sizeY = (ualni) (automata.numStates() + 1); auto sizeY = (ualni) (automata.numStates() + 1);
mTransitions.reserve({ sizeX, sizeY }); mTable.reserve({ sizeX, sizeY });
mTransitions.assign(automata.numStates()); mTable.assign(automata.numStates());
mStates.reserve(sizeY); mStates.reserve(sizeY);
ualni idx = 0; ualni idx = 0;
for (auto state : *automata.getStates()) { for (auto state : *automata.getStates()) {
auto stateVal = state->isAccepting() ? state->getStateVal() : tNoStateVal; mStates[idx] = { state->isAccepting(), state->getStateVal() };
mStates[idx] = stateVal;
idx++; idx++;
} }
mStates[automata.numStates()] = tFailedStateVal; mStates[automata.numStates()] = { true, tFailedStateVal };
idx = 0; idx = 0;
for (auto state : *automata.getStates()) { for (auto state : *automata.getStates()) {
if (&state.data() == automata.getStartState()) { if (&state.data() == automata.getStartState()) {
mStart = mIter = mIterPrev = idx; mStartState = mCurrentState = idx;
} }
idx++; idx++;
} }
@ -107,7 +82,7 @@ namespace tp {
stateIdx2++; stateIdx2++;
} }
auto const code = transition->getSymbol(); auto const code = transition->getSymbol();
mTransitions.set({ (ualni) (code - mSymbolRange.mBegin), (ualni) stateIdx }, stateIdx2); mTable.set({ (ualni) (code - mSymbolRange.mBegin), (ualni) stateIdx }, stateIdx2);
} }
stateIdx++; stateIdx++;
} }