cfg accepting
This commit is contained in:
parent
2ebf650381
commit
7a685e0634
2 changed files with 95 additions and 17 deletions
|
|
@ -15,11 +15,79 @@ namespace tp {
|
||||||
ualni num = 0; // state to shift (shift action) or pop count (reduce action)
|
ualni num = 0; // state to shift (shift action) or pop count (reduce action)
|
||||||
};
|
};
|
||||||
|
|
||||||
Buffer2D<Action> mTable;
|
public:
|
||||||
|
struct StackItem {
|
||||||
|
ualni state = 0;
|
||||||
|
tAlphabetType symbol;
|
||||||
|
Buffer<StackItem*> leafs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AcceptResult {
|
||||||
|
bool accepted = false;
|
||||||
|
ualni advancedIdx = 0;
|
||||||
|
const StackItem* ast = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ContextFreeAutomata() = default;
|
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<ualni>(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<tAlphabetType, tStateType>& automata) {}
|
void construct(const FiniteStateAutomation<tAlphabetType, tStateType>& automata) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Buffer2D<Action> mTable;
|
||||||
|
|
||||||
|
Buffer<StackItem> mItems;
|
||||||
|
Buffer<StackItem*> mStack;
|
||||||
|
|
||||||
|
ualni mStartState = 0;
|
||||||
|
ualni mCurrentState = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,21 +7,19 @@
|
||||||
|
|
||||||
namespace tp {
|
namespace tp {
|
||||||
|
|
||||||
template <typename tAlphabetType, typename tStateType, tStateType tFailedStateVal>
|
template <typename tAlphabetType, typename tStateType>
|
||||||
class RegularAutomata {
|
class RegularAutomata {
|
||||||
|
public:
|
||||||
Buffer2D<ualni> mTable;
|
struct AcceptResult {
|
||||||
Buffer<Pair<bool, tStateType>> mStates;
|
bool accepted = false;
|
||||||
|
ualni advancedIdx = 0;
|
||||||
ualni mCurrentState = 0;
|
tStateType state = tStateType();
|
||||||
ualni mStartState = 0;
|
};
|
||||||
|
|
||||||
Range<tAlphabetType> mSymbolRange = { 0, 0 };
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RegularAutomata() = default;
|
RegularAutomata() = default;
|
||||||
|
|
||||||
Pair<tStateType, ualni> accept(const tAlphabetType* stream, ualni size) {
|
AcceptResult accept(const tAlphabetType* stream, ualni size) {
|
||||||
mCurrentState = mStartState;
|
mCurrentState = mStartState;
|
||||||
|
|
||||||
ualni advancedIdx = 0;
|
ualni advancedIdx = 0;
|
||||||
|
|
@ -30,28 +28,33 @@ namespace tp {
|
||||||
tAlphabetType& symbol = *(stream + advancedIdx);
|
tAlphabetType& symbol = *(stream + advancedIdx);
|
||||||
|
|
||||||
if (!(symbol >= mSymbolRange.mBegin && symbol < mSymbolRange.mEnd)) {
|
if (!(symbol >= mSymbolRange.mBegin && symbol < mSymbolRange.mEnd)) {
|
||||||
return { tFailedStateVal, advancedIdx };
|
return { false, advancedIdx, {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentState = mTable.get({ (ualni) (symbol - mSymbolRange.mBegin), mCurrentState });
|
mCurrentState = mTable.get({ (ualni) (symbol - mSymbolRange.mBegin), mCurrentState });
|
||||||
|
|
||||||
|
if (mCurrentState == mStates.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (mStates[mCurrentState].first) {
|
if (mStates[mCurrentState].first) {
|
||||||
return { mStates[mCurrentState].second, advancedIdx };
|
return { true, advancedIdx, mStates[mCurrentState].second };
|
||||||
}
|
}
|
||||||
|
|
||||||
advancedIdx++;
|
advancedIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { tFailedStateVal, advancedIdx };
|
return { false, advancedIdx, {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
void construct(const FiniteStateAutomation<tAlphabetType, tStateType>& automata) {
|
void construct(const FiniteStateAutomation<tAlphabetType, tStateType>& automata) {
|
||||||
const auto range = automata.getAlphabetRange();
|
const auto range = automata.getAlphabetRange();
|
||||||
mSymbolRange = { tAlphabetType(range.mBegin), tAlphabetType(range.mEnd) };
|
mSymbolRange = { tAlphabetType(range.mBegin), tAlphabetType(range.mEnd) };
|
||||||
|
|
||||||
auto range_len = ualni(mSymbolRange.mEnd - mSymbolRange.mBegin);
|
auto range_len = ualni(mSymbolRange.mEnd - mSymbolRange.mBegin);
|
||||||
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());
|
||||||
|
|
||||||
mTable.reserve({ sizeX, sizeY });
|
mTable.reserve({ sizeX, sizeY });
|
||||||
mTable.assign(automata.numStates());
|
mTable.assign(automata.numStates());
|
||||||
|
|
@ -63,8 +66,6 @@ namespace tp {
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
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()) {
|
||||||
|
|
@ -87,5 +88,14 @@ namespace tp {
|
||||||
stateIdx++;
|
stateIdx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Buffer2D<ualni> mTable;
|
||||||
|
Buffer<Pair<bool, tStateType>> mStates;
|
||||||
|
|
||||||
|
ualni mCurrentState = 0;
|
||||||
|
ualni mStartState = 0;
|
||||||
|
|
||||||
|
Range<tAlphabetType> mSymbolRange = { 0, 0 };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue