From dbd53719b0f14a1662997f80b5c777a43ab2ac5c Mon Sep 17 00:00:00 2001 From: Ilusha <63184036+IlyaShurupov@users.noreply.github.com> Date: Thu, 7 Mar 2024 12:31:26 +0300 Subject: [PATCH] tmp --- Containers/public/List.hpp | 2 +- Externals/lalr | 1 + Language/public/Automata.hpp | 116 +++++++++++++++--------- Language/public/ContextFreeCompiler.hpp | 4 +- Language/public/Parser.hpp | 6 +- Language/public/RegularAutomata.hpp | 9 +- Language/public/RegularCompiler.hpp | 31 +++++-- Language/tests/Tests.cpp | 15 +++ 8 files changed, 124 insertions(+), 60 deletions(-) create mode 160000 Externals/lalr diff --git a/Containers/public/List.hpp b/Containers/public/List.hpp index dbcfd44..3a36de5 100644 --- a/Containers/public/List.hpp +++ b/Containers/public/List.hpp @@ -18,7 +18,7 @@ namespace tp { Type data; Node* next = nullptr; Node* prev = nullptr; - Node() = default; + Node() { data = Type(); } explicit Node(TypeArg p_data) : data(p_data) {} Type& operator->() { return data; } diff --git a/Externals/lalr b/Externals/lalr new file mode 160000 index 0000000..ebf4183 --- /dev/null +++ b/Externals/lalr @@ -0,0 +1 @@ +Subproject commit ebf41832eb51205afd7aaf3e097d0a6197fefc26 diff --git a/Language/public/Automata.hpp b/Language/public/Automata.hpp index 7914c0a..b4077d8 100644 --- a/Language/public/Automata.hpp +++ b/Language/public/Automata.hpp @@ -47,6 +47,7 @@ namespace tp { class State { friend FiniteStateAutomation; + public: State() = default; public: @@ -61,7 +62,7 @@ namespace tp { private: List mStates; - const State* mStartState = nullptr; + State* mStartState = nullptr; public: FiniteStateAutomation() = default; @@ -69,18 +70,18 @@ namespace tp { State* addState(const tStateType& state, bool accepting) { auto node = mStates.newNode(); node->data.mIsAccepting = accepting; - node->data.mState = state; + node->data.mStateVal = state; mStates.pushBack(node); return &node->data; } void addTransition(State* from, State* to, const tAlphabetType& symbol) { - from->edges.pushBack(Transition(Transition::SYMBOL, to, symbol)); + from->mTransitions.append(Transition(Transition::SYMBOL, to, symbol)); } - void addEpsilonTransition(State* from, State* to) { from->edges.pushBack(Transition(Transition::SYMBOL, to)); } + void addEpsilonTransition(State* from, State* to) { from->mTransitions.append(Transition(Transition::SYMBOL, to)); } - void addAnyTransition(State* from, State* to) { from->edges.pushBack(Transition(Transition::ANY, to)); } + void addAnyTransition(State* from, State* to) { from->mTransitions.append(Transition(Transition::ANY, to)); } void setStartVertex(State* start) { mStartState = start; } @@ -96,7 +97,7 @@ namespace tp { // vertices that are reachable from initial set with no input consumption (E-transitions) // does not include initial set void findClosureSet(const Buffer& from, Buffer& closureSet) const { - Map lookup; + Map lookup; List workingSet; for (auto item : from) { @@ -106,10 +107,11 @@ namespace tp { while (workingSet.length()) { auto first = workingSet.first()->data; closureSet.append(first); + lookup.put((alni) first, {}); for (auto edge : first->mTransitions) { if (!edge.data().isEpsilon()) continue; - if (lookup.presents(edge.data().mState)) continue; + if (lookup.presents((alni) edge.data().mState)) continue; workingSet.pushBack(edge.data().mState); } @@ -119,88 +121,118 @@ namespace tp { // vertices that are reachable from initial set with symbol transition void findMoveSet(const Buffer& from, Buffer& moveSet, tAlphabetType symbol) const { - Map lookup; + Map lookup; for (auto vertex : from) { - for (auto edge : vertex.mTransitions) { - if (edge.data().isepsilon()) continue; + for (auto edge : vertex->mTransitions) { + if (edge.data().isEpsilon()) continue; if (!edge.data().isTransition(symbol)) continue; - if (lookup.presents(edge.data().mState)) continue; + if (lookup.presents((alni) edge.data().mState)) continue; moveSet.append(edge.data().mState); - lookup.put(edge.data().mState, {}); + lookup.put((alni) edge.data().mState, {}); } } } template bool makeDeterministic(const tAlphabetIterator& allSymbols) { - if (!isValid()) { - return false; - } + if (!isValid()) return false; - struct Group { - Buffer states; - AvlTree transitions; + typedef Buffer Group; + + struct GroupKey { + const Group* group; + static ualni hash(GroupKey key) { return 0; } + bool operator==(const GroupKey& key) const { return false; } + }; + + struct GroupInfo { + Group* group = nullptr; + AvlTree, tAlphabetType> transitions; State* newState = nullptr; bool accepting = false; tStateType stateVal = tStateType(); }; - struct GroupKey { - const Group* group; - }; + Buffer groups = { {} }; + Map groupInfos; - Buffer newStates = { {} }; + findClosureSet({ getStartState() }, groups.first()); + groupInfos.put({ &groups.first() }, { &groups.first() }); // 1) find new states - Map lookup; List workingSet; + workingSet.pushBack(&groups.first()); - findClosureSet({ getStartState() }, newStates.first().states); - - workingSet.pushBack(&newStates.first()); while (workingSet.length()) { - auto group = workingSet.first(); + Group* group = workingSet.first()->data; + GroupInfo* info = &groupInfos.get({ group }); for (auto symbol : allSymbols) { // calculate new possible state + Group potentialGroupTmp; Group potentialGroup; - findMoveSet(group.states, potentialGroup.states, symbol); - if (!potentialGroup.states.size()) continue; + + findMoveSet(*group, potentialGroupTmp, symbol); + findClosureSet(potentialGroupTmp, potentialGroup); + + if (!potentialGroup.size()) continue; // find existing or create group Group* targetGroup = nullptr; - auto iter = lookup.presents({ &potentialGroup }); + auto iter = groupInfos.presents({ &potentialGroup }); if (iter) { - targetGroup = lookup.getSlotVal(iter); + targetGroup = groupInfos.getSlotVal(iter).group; } else { - targetGroup = newStates.append({}); - lookup.put({ targetGroup }, {}); + targetGroup = &groups.append(potentialGroup); + groupInfos.put({ targetGroup }, { targetGroup }); + workingSet.pushBack(targetGroup); } - // add transition - group.transitions.insert(targetGroup, symbol); + // assert transition is added + info->transitions.insert((alni) targetGroup, symbol); } workingSet.popFront(); } // 2) find new states termination values - // ... + for (auto group : groupInfos) { + GroupInfo* info = &group->val; + bool accepting = false; + for (auto item : *info->group) { + if (item->mIsAccepting) { + if (accepting) return false; + accepting = true; + info->accepting = true; + info->stateVal = item->mStateVal; + } + } + if (!accepting) { + info->accepting = false; + info->stateVal = info->group->first()->mStateVal; + } + } // 3) transfer mStates.removeAll(); - for (auto group : newStates) { - group.newState = addState(); + // create states + for (auto group : groupInfos) { + group->val.newState = addState(group->val.stateVal, group->val.accepting); } - for (auto group : newStates) { - for (auto transition : group.transitions) { - addTransition(/* ... */); - } + // create transitions + for (auto group : groupInfos) { + auto functor = [&](AvlNumericKey targetGroupKey, tAlphabetType symbol) { + GroupInfo* targetGroup = &groupInfos.get({ (Group*) targetGroupKey.val }); + addTransition(group->val.newState, targetGroup->newState, symbol); + }; + group->val.transitions.forEach(functor); } + + return true; } }; } \ No newline at end of file diff --git a/Language/public/ContextFreeCompiler.hpp b/Language/public/ContextFreeCompiler.hpp index 29fb439..6473777 100644 --- a/Language/public/ContextFreeCompiler.hpp +++ b/Language/public/ContextFreeCompiler.hpp @@ -21,8 +21,8 @@ namespace tp { ualni mAdvanceIdx; }; - typedef NFA NFA; - typedef typename NFA::Vertex State; + typedef FiniteStateAutomation NFA; + typedef typename NFA::State State; public: void compile(const Grammar& in, NFA& out) { nfa = &out; } diff --git a/Language/public/Parser.hpp b/Language/public/Parser.hpp index 43870c8..9834aea 100644 --- a/Language/public/Parser.hpp +++ b/Language/public/Parser.hpp @@ -11,12 +11,12 @@ namespace tp { class Parser { typedef TransitionMatrix RegularTable; - typedef DFA RegularGraph; + typedef FiniteStateAutomation RegularGraph; typedef RegularCompiler RegularCompiler; - typedef NFA RegularNonDetGraph; + typedef FiniteStateAutomation RegularNonDetGraph; // ContextFreeCompiler::Alphabet PushDownTable; - typedef DFA ContextFreeDFA; + typedef FiniteStateAutomation ContextFreeDFA; typedef ContextFreeCompiler::NFA ContextFreeNFA; public: diff --git a/Language/public/RegularAutomata.hpp b/Language/public/RegularAutomata.hpp index 08a895c..0146923 100644 --- a/Language/public/RegularAutomata.hpp +++ b/Language/public/RegularAutomata.hpp @@ -27,8 +27,11 @@ namespace tp { auto getTransitions() const { return &mTransitions; } auto getStart() const { return mStart; } - void construct(const DFA& dfa) { - mSymbolRange = { dfa.getRange().first(), dfa.getRange().last() }; + void construct(const FiniteStateAutomation& dfa) { + // mSymbolRange = { dfa.getRange().first(), dfa.getRange().last() }; + ASSERT(0); + + /* auto range_len = ualni(mSymbolRange.mEnd - mSymbolRange.mBegin); auto sizeX = range_len ? range_len : 1; auto sizeY = (ualni) (dfa.nVertices() + 1); @@ -67,6 +70,8 @@ namespace tp { } vertexIdx++; } + + */ } bool isTrapped() { return mStates[mIter] == tFailedStateVal; } diff --git a/Language/public/RegularCompiler.hpp b/Language/public/RegularCompiler.hpp index 479e9b6..89bf5d5 100644 --- a/Language/public/RegularCompiler.hpp +++ b/Language/public/RegularCompiler.hpp @@ -9,8 +9,8 @@ namespace tp { template class RegularCompiler { - typedef NFA Graph; - typedef typename Graph::Vertex Vertex; + typedef FiniteStateAutomation Graph; + typedef typename Graph::State Vertex; typedef RegularGrammar Grammar; struct Node { @@ -69,8 +69,9 @@ namespace tp { auto node = compileNode(astNode, nullptr, nullptr); - mGraph->setVertexState(node.right, state, true); - mGraph->setStartVertex(node.left); + // mGraph->setVertexState(node.right, state, true); + // mGraph->setStartVertex(node.left); + ASSERT(0); return node; } @@ -173,21 +174,29 @@ namespace tp { } void transitionAny(Vertex* from, Vertex* to, bool consumes = false) { - mGraph->addTransition(from, to, {}, consumes, true, false); + // mGraph->addTransition(from, to, {}, consumes, true, false); + ASSERT(0); } void transitionVal(Vertex* from, Vertex* to, tAlphabetType val) { - mGraph->addTransition(from, to, { val, val }, true, false, false); + // mGraph->addTransition(from, to, { val, val }, true, false, false); + ASSERT(0); } void transitionRange(Vertex* from, Vertex* to, Range range, bool exclude) { - mGraph->addTransition(from, to, range, true, false, exclude); + // mGraph->addTransition(from, to, range, true, false, exclude); + ASSERT(0); } - Vertex* addVertex() { return mGraph->addVertex(tNoStateVal, false); } + Vertex* addVertex() { + // return mGraph->addVertex(tNoStateVal, false); + ASSERT(0); + return nullptr; + } private: Range getAlphabetRange() const { + /* tAlphabetType start = 0, end = 0; Range all_range( std::numeric_limits::min(), std::numeric_limits::max() @@ -204,14 +213,16 @@ namespace tp { first = false; } } - return Range(start, end + 1); + */ + ASSERT(0); + return {}; } void setAlphabet() { auto range = getAlphabetRange(); for (auto iter : range) { - mGraph->mAllSymbols.append(iter); + // mGraph->mAllSymbols.append(iter); } } }; diff --git a/Language/tests/Tests.cpp b/Language/tests/Tests.cpp index 7619a24..3e0f2bc 100644 --- a/Language/tests/Tests.cpp +++ b/Language/tests/Tests.cpp @@ -3,6 +3,20 @@ using namespace tp; +void testAutomation() { + + FiniteStateAutomation automata; + + auto start = automata.addState(0, false); + auto end = automata.addState(1, true); + + automata.addTransition(start, end, 'a'); + + automata.setStartVertex(start); + + automata.makeDeterministic(Range(10, 30)); +} + void test() { auto parser = SimpleParser(); auto ast = AST(); @@ -20,6 +34,7 @@ int main() { return 1; } + testAutomation(); test(); testModule.deinitialize();