cfg automata ini

This commit is contained in:
IlyaShurupov 2024-02-08 13:57:51 +03:00 committed by Ilusha
parent 35387395eb
commit 1d9ef2aa6c

View file

@ -39,37 +39,39 @@ namespace tp {
while (advancedIdx < size) { while (advancedIdx < size) {
tAlphabetType& symbol = *(stream + advancedIdx); tAlphabetType& symbol = *(stream + advancedIdx);
const Action& action = mTable.get({ ualni(symbol), mCurrentState }); if (!(symbol >= mRange.mBegin && symbol < mRange.mEnd)) {
return { false, advancedIdx, nullptr };
}
switch (action.type) { const Action& action = mTable.get({ ualni(symbol - mRange.mBegin), mCurrentState });
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 (action.type == Action::TRAP) {
if (advancedIdx == size) { return { false, advancedIdx, nullptr };
return { true, advancedIdx, newItem }; }
} else {
return { false, advancedIdx, {} };
}
}
mStack.append(&mItems.append({ mCurrentState, {}, {} })); if (action.type == Action::SHIFT) {
break; mStack.last()->symbol = symbol;
} mStack.append(&mItems.append({ mCurrentState, {}, {} }));
case Action::SHIFT: mCurrentState = action.num;
{ }
mStack.last()->symbol = symbol;
mStack.append(&mItems.append({ mCurrentState, {}, {} })); if (mTable.get({ 0, mCurrentState }).type == Action::REDUCE) {
mCurrentState = action.num; StackItem* newItem = &mItems.append({});
break; 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, {}, {} }));
} }
advancedIdx++; advancedIdx++;
@ -79,7 +81,47 @@ namespace tp {
} }
public: public:
void construct(const FiniteStateAutomation<tAlphabetType, tStateType>& automata) {} typedef FiniteStateAutomation<tAlphabetType, tStateType> Automata;
typedef Automata::State AutomataState;
void construct(const Automata& automata) {
mRange = automata.getAlphabetRange();
const ualni numStates = automata.numStates();
const ualni numSymbols = mRange.idxDiff();
mTable.reserve({ numSymbols, numStates });
mTable.assign(Action{ Action::TRAP, 0 });
Map<const AutomataState*, ualni> states;
ualni stateIndex = 0;
for (auto state : *automata.getStates()) {
states.put(state.data(), { stateIndex });
stateIndex++;
}
stateIndex = 0;
for (auto state : *automata.getStates()) {
if (state.data() == automata.getStartState()) {
mStartState = stateIndex;
}
if (state->isAccepting()) {
ASSERT(state->getTransitions().size() == 0)
for (auto symbolIndex : Range<ualni>(numSymbols)) {
mTable.set({ stateIndex, symbolIndex }, { Action::REDUCE, state->getStateVal() });
}
} else {
for (auto transition : *state->getTransitions()) {
ualni symbolIndex = ualni(transition->getSymbol()) - mRange.mBegin;
ualni targetStateIndex = states.get(transition->getState());
mTable.set({ stateIndex, symbolIndex }, { Action::SHIFT, targetStateIndex });
}
}
stateIndex++;
}
}
private: private:
Buffer2D<Action> mTable; Buffer2D<Action> mTable;
@ -89,5 +131,7 @@ namespace tp {
ualni mStartState = 0; ualni mStartState = 0;
ualni mCurrentState = 0; ualni mCurrentState = 0;
Range<tAlphabetType> mRange = { 0, 0 };
}; };
} }