cfg automata ini
This commit is contained in:
parent
35387395eb
commit
1d9ef2aa6c
1 changed files with 72 additions and 28 deletions
|
|
@ -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 };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue