From 4f88c45c9e992425f0f3c185ab62eab39b85bd0c Mon Sep 17 00:00:00 2001 From: IlyaShurupov Date: Wed, 7 Feb 2024 19:20:29 +0300 Subject: [PATCH] tmp --- Language/public/Automata.hpp | 2 +- Language/public/ContextFreeAutomata.hpp | 18 +++++ Language/public/ContextFreeCompiler.hpp | 2 +- Language/public/Grammar.hpp | 1 + Language/public/Parser.hpp | 41 +++++++----- Language/public/RegularAutomata.hpp | 88 ++++++++++++------------- Language/public/RegularCompiler.hpp | 83 +++++++++-------------- Language/tests/Tests.cpp | 2 +- 8 files changed, 120 insertions(+), 117 deletions(-) create mode 100644 Language/public/ContextFreeAutomata.hpp diff --git a/Language/public/Automata.hpp b/Language/public/Automata.hpp index ccb34e0..e89ff06 100644 --- a/Language/public/Automata.hpp +++ b/Language/public/Automata.hpp @@ -92,7 +92,7 @@ namespace tp { void addAnyTransition(State* from, State* to) { from->mTransitions.append(Transition(Transition::ANY, to)); } - void setStartVertex(State* start) { mStartState = start; } + void setStartState(State* start) { mStartState = start; } [[nodiscard]] State* getStartState() const { return mStartState; } diff --git a/Language/public/ContextFreeAutomata.hpp b/Language/public/ContextFreeAutomata.hpp new file mode 100644 index 0000000..56fa990 --- /dev/null +++ b/Language/public/ContextFreeAutomata.hpp @@ -0,0 +1,18 @@ + +#pragma once + +#include "Strings.hpp" +#include "Automata.hpp" +#include "Buffer2D.hpp" + +namespace tp { + + template + class ContextFreeAutomata { + + public: + ContextFreeAutomata() = default; + + void construct(const FiniteStateAutomation& automata) {} + }; +} diff --git a/Language/public/ContextFreeCompiler.hpp b/Language/public/ContextFreeCompiler.hpp index 6473777..2b8b0a1 100644 --- a/Language/public/ContextFreeCompiler.hpp +++ b/Language/public/ContextFreeCompiler.hpp @@ -18,7 +18,7 @@ namespace tp { struct Item { Grammar::Rule mRule; - ualni mAdvanceIdx; + ualni mAdvanceIdx = 0; }; typedef FiniteStateAutomation NFA; diff --git a/Language/public/Grammar.hpp b/Language/public/Grammar.hpp index a19fdf6..8c65287 100644 --- a/Language/public/Grammar.hpp +++ b/Language/public/Grammar.hpp @@ -193,6 +193,7 @@ namespace tp { explicit ClassNode(const Buffer>& ranges, bool exclude = false) : Node(Node::CLASS) { mExclude = exclude; + mRanges = ranges; } ~ClassNode() override { mRanges.removeAll(); } diff --git a/Language/public/Parser.hpp b/Language/public/Parser.hpp index a56e3cf..5196bc1 100644 --- a/Language/public/Parser.hpp +++ b/Language/public/Parser.hpp @@ -2,45 +2,49 @@ #pragma once #include "AST.hpp" + #include "RegularCompiler.hpp" +#include "RegularAutomata.hpp" + #include "ContextFreeCompiler.hpp" +#include "ContextFreeAutomata.hpp" namespace tp { - template + template class Parser { - typedef RegularAutomata RegularTable; + typedef RegularGrammar RegularGrammar; + typedef RegularCompiler RegularCompiler; typedef FiniteStateAutomation RegularGraph; - typedef RegularCompiler RegularCompiler; - typedef FiniteStateAutomation RegularNonDetGraph; + typedef RegularAutomata RegularAutomata; - // ContextFreeCompiler::Alphabet PushDownTable; - typedef FiniteStateAutomation ContextFreeDFA; - typedef ContextFreeCompiler::NFA ContextFreeNFA; + // ContextFreeGrammar; + // ContextFreeCompiler; + typedef FiniteStateAutomation ContextFreeGraph; + typedef ContextFreeAutomata ContextFreeAutomata; public: Parser() = default; public: - void compileTables(const ContextFreeGrammar& cfGrammar, const RegularGrammar& reGrammar) { + void compileTables(const ContextFreeGrammar& cfGrammar, const RegularGrammar& reGrammar) { // Compile Regular Grammar { - RegularNonDetGraph nfa; + RegularGraph graph; RegularCompiler compiler; - compiler.compile(nfa, reGrammar); - - RegularGraph dfa(nfa); - mRegularTable.construct(dfa); + compiler.compile(graph, reGrammar); + graph.makeDeterministic(); + mRegularAutomata.construct(graph); } // compile context free grammar { - ContextFreeNFA nfa; + ContextFreeGraph graph; ContextFreeCompiler compiler; - compiler.compile(cfGrammar, nfa); - - ContextFreeDFA dfa(nfa); + compiler.compile(cfGrammar, graph); + graph.makeDeterministic(); + mContextFreeAutomata.construct(graph); } } @@ -48,6 +52,7 @@ namespace tp { public: // save load compiled tables - RegularTable mRegularTable; + RegularAutomata mRegularAutomata; + ContextFreeAutomata mContextFreeAutomata; }; } diff --git a/Language/public/RegularAutomata.hpp b/Language/public/RegularAutomata.hpp index 9b45da1..9b7def9 100644 --- a/Language/public/RegularAutomata.hpp +++ b/Language/public/RegularAutomata.hpp @@ -27,50 +27,6 @@ namespace tp { auto getTransitions() const { return &mTransitions; } auto getStart() const { return mStart; } - void construct(const FiniteStateAutomation& automata) { - mSymbolRange = { tAlphabetType(automata.getAlphabetRange().mBegin), - tAlphabetType(automata.getAlphabetRange().mEnd) }; - - auto range_len = ualni(mSymbolRange.mEnd - mSymbolRange.mBegin); - auto sizeX = range_len ? range_len : 1; - auto sizeY = (ualni) (automata.numStates() + 1); - - mTransitions.reserve({ sizeX, sizeY }); - mTransitions.assign(automata.numStates()); - mStates.reserve(sizeY); - - ualni idx = 0; - for (auto state : *automata.getStates()) { - auto stateVal = state->isAccepting() ? state->getStateVal() : tNoStateVal; - mStates[idx] = stateVal; - idx++; - } - - mStates[automata.numStates()] = tFailedStateVal; - - idx = 0; - for (auto state : *automata.getStates()) { - if (&state.data() == automata.getStartState()) { - mStart = mIter = mIterPrev = idx; - } - idx++; - } - - ualni stateIdx = 0; - for (auto state : *automata.getStates()) { - for (auto transition : *state->getTransitions()) { - ualni stateIdx2 = 0; - for (auto state2 : *automata.getStates()) { - if (transition->getState() == &state2.data()) break; - stateIdx2++; - } - auto const code = transition->getSymbol(); - mTransitions.set({ (ualni) (code - mSymbolRange.mBegin), (ualni) stateIdx }, stateIdx2); - } - stateIdx++; - } - } - bool isTrapped() { return mStates[mIter] == tFailedStateVal; } tStateType move(tAlphabetType symbol) { @@ -112,5 +68,49 @@ namespace tp { mIter = mStart; mIterPrev = mStart; } + + void construct(const FiniteStateAutomation& automata) { + const auto range = automata.getAlphabetRange(); + mSymbolRange = { tAlphabetType(range.mBegin), tAlphabetType(range.mEnd) }; + + auto range_len = ualni(mSymbolRange.mEnd - mSymbolRange.mBegin); + auto sizeX = range_len ? range_len : 1; + auto sizeY = (ualni) (automata.numStates() + 1); + + mTransitions.reserve({ sizeX, sizeY }); + mTransitions.assign(automata.numStates()); + mStates.reserve(sizeY); + + ualni idx = 0; + for (auto state : *automata.getStates()) { + auto stateVal = state->isAccepting() ? state->getStateVal() : tNoStateVal; + mStates[idx] = stateVal; + idx++; + } + + mStates[automata.numStates()] = tFailedStateVal; + + idx = 0; + for (auto state : *automata.getStates()) { + if (&state.data() == automata.getStartState()) { + mStart = mIter = mIterPrev = idx; + } + idx++; + } + + ualni stateIdx = 0; + for (auto state : *automata.getStates()) { + for (auto transition : *state->getTransitions()) { + ualni stateIdx2 = 0; + for (auto state2 : *automata.getStates()) { + if (transition->getState() == &state2.data()) break; + stateIdx2++; + } + auto const code = transition->getSymbol(); + mTransitions.set({ (ualni) (code - mSymbolRange.mBegin), (ualni) stateIdx }, stateIdx2); + } + stateIdx++; + } + } }; } diff --git a/Language/public/RegularCompiler.hpp b/Language/public/RegularCompiler.hpp index 89bf5d5..25571fa 100644 --- a/Language/public/RegularCompiler.hpp +++ b/Language/public/RegularCompiler.hpp @@ -2,11 +2,11 @@ #pragma once #include "Grammar.hpp" -#include "RegularAutomata.hpp" +#include "Automata.hpp" namespace tp { - template + template class RegularCompiler { typedef FiniteStateAutomation Graph; @@ -34,7 +34,6 @@ namespace tp { void compile(Graph& graph, const tAlphabetType* regex, tStateType state) { mGraph = &graph; compileUtil(regex, state); - setAlphabet(); } void compile(Graph& aGraph, const Grammar& grammar) { @@ -59,9 +58,7 @@ namespace tp { idx++; } - mGraph->setStartVertex(left); - - setAlphabet(); + mGraph->setStartState(left); } private: @@ -69,9 +66,10 @@ namespace tp { auto node = compileNode(astNode, nullptr, nullptr); - // mGraph->setVertexState(node.right, state, true); - // mGraph->setStartVertex(node.left); - ASSERT(0); + node.right->setValue(state); + node.right->setAcceptance(true); + + mGraph->setStartState(node.left); return node; } @@ -129,13 +127,13 @@ namespace tp { if (node->mRanges.size() == 1) { auto const& range = node->mRanges.first(); - transitionRange(left, right, { range.mBegin, range.mEnd }, node->mExclude); + transitionRange(left, right, { ualni(range.mBegin), ualni(range.mEnd) }, node->mExclude); return { left, right }; } for (auto range : node->mRanges) { auto middle = addVertex(); - transitionRange(left, middle, { range.data().mBegin, range.data().mEnd }, node->mExclude); + transitionRange(left, middle, { ualni(range->mBegin), ualni(range->mEnd) }, node->mExclude); transitionAny(middle, right); } return { left, right }; @@ -174,56 +172,37 @@ namespace tp { } void transitionAny(Vertex* from, Vertex* to, bool consumes = false) { - // mGraph->addTransition(from, to, {}, consumes, true, false); - ASSERT(0); + for (auto symbol : Range(tMinSymbol, tMaxSymbol)) { + transitionVal(from, to, symbol); + } } - void transitionVal(Vertex* from, Vertex* to, tAlphabetType val) { - // mGraph->addTransition(from, to, { val, val }, true, false, false); - ASSERT(0); - } + void transitionVal(Vertex* from, Vertex* to, tAlphabetType val) { mGraph->addTransition(from, to, val); } - void transitionRange(Vertex* from, Vertex* to, Range range, bool exclude) { - // mGraph->addTransition(from, to, range, true, false, exclude); - ASSERT(0); - } + void transitionRange(Vertex* from, Vertex* to, Range range, bool exclude) { + if (exclude) { + Range first = { tMinSymbol, range.mBegin - 1 }; + Range second = { range.mEnd + 1, tMaxSymbol }; - Vertex* addVertex() { - // return mGraph->addVertex(tNoStateVal, false); - ASSERT(0); - return nullptr; - } + if (first.valid()) { + for (auto symbol : first) { + transitionVal(from, to, symbol); + } + } - private: - Range getAlphabetRange() const { - /* - tAlphabetType start = 0, end = 0; - Range all_range( - std::numeric_limits::min(), std::numeric_limits::max() - ); - bool first = true; + if (second.valid()) { + for (auto symbol : second) { + transitionVal(from, to, symbol); + } + } - for (auto vertex : mGraph->mVertices) { - for (auto edge : vertex.data().edges) { - if (!edge.data().mConsumesSymbol) continue; - auto const& tran_range = edge.data().mAcceptingRange; - if (edge.data().mAcceptsAll || edge.data().mExclude) return all_range; - if (tran_range.mBegin < start || first) start = tran_range.mBegin; - if (tran_range.mEnd > end || first) end = tran_range.mEnd; - first = false; + } else { + for (auto symbol : range) { + transitionVal(from, to, symbol); } } - return Range(start, end + 1); - */ - ASSERT(0); - return {}; } - void setAlphabet() { - auto range = getAlphabetRange(); - for (auto iter : range) { - // mGraph->mAllSymbols.append(iter); - } - } + Vertex* addVertex() { return mGraph->addState(tStateType::InTransition, false); } }; } diff --git a/Language/tests/Tests.cpp b/Language/tests/Tests.cpp index cc11039..3f7a42e 100644 --- a/Language/tests/Tests.cpp +++ b/Language/tests/Tests.cpp @@ -12,7 +12,7 @@ void testAutomation() { automata.addTransition(start, end, 'a'); - automata.setStartVertex(start); + automata.setStartState(start); automata.makeDeterministic(); }