From 150b0deccc97231d39ad39bfa8be7a0c6d33fc20 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Sun, 4 Jan 2015 21:18:46 +0100 Subject: [PATCH] reimplement from/to string parsers/composers --- aconvert2/src/DotConverter.cpp | 225 ++++------- aconvert2/src/GasTexConverter.cpp | 78 ++-- aconvert2/src/aconvert.cpp | 42 +-- .../grammar/simplify/GrammarToCNFTest.cpp | 9 +- alib2algo/test-src/regexp/RegExpTest.cpp | 32 +- .../regexp/properties/RegExpEmptyTest.cpp | 12 +- .../regexp/properties/RegExpEpsilonTest.cpp | 31 +- .../regexp/simplify/RegExpOptimizeTest.cpp | 13 +- .../test-src/regexp/toAutomaton/re2faTest.cpp | 17 +- .../transform/RegExpConcatenateTest.cpp | 35 +- .../regexp/transform/RegExpDerivationTest.cpp | 18 +- .../regexp/transform/RegExpIntegralTest.cpp | 17 +- alib2data/src/FromStringParser.hpp | 45 --- alib2data/src/StringApi.cpp | 88 +++++ alib2data/src/StringApi.hpp | 105 ++++++ .../src/alphabet/SymbolFromStringLexer.cpp | 83 +++-- .../src/alphabet/SymbolFromStringLexer.h | 14 +- .../src/alphabet/SymbolFromStringParser.cpp | 44 +-- .../src/alphabet/SymbolFromStringParser.h | 50 +-- .../src/alphabet/SymbolToStringComposer.cpp | 72 ++-- .../src/alphabet/SymbolToStringComposer.h | 32 +- .../FSM/FiniteAutomatonFromStringLexer.cpp | 145 ++++---- .../FSM/FiniteAutomatonFromStringLexer.h | 11 +- .../FSM/FiniteAutomatonFromStringParser.cpp | 348 ++++++++---------- .../FSM/FiniteAutomatonFromStringParser.h | 47 ++- .../FSM/FiniteAutomatonToStringComposer.cpp | 144 ++++---- .../FSM/FiniteAutomatonToStringComposer.h | 31 +- alib2data/src/factory/StringDataFactory.hpp | 75 ++++ .../src/grammar/GrammarFromStringLexer.cpp | 144 ++++---- .../src/grammar/GrammarFromStringLexer.h | 10 +- .../src/grammar/GrammarFromStringParser.cpp | 62 +--- .../src/grammar/GrammarFromStringParser.h | 26 +- .../src/grammar/GrammarToStringComposer.cpp | 124 +++---- .../src/grammar/GrammarToStringComposer.h | 32 +- alib2data/src/label/LabelFromStringLexer.cpp | 78 ++-- alib2data/src/label/LabelFromStringLexer.h | 14 +- alib2data/src/label/LabelFromStringParser.cpp | 82 ++--- alib2data/src/label/LabelFromStringParser.h | 45 +-- alib2data/src/label/LabelToStringComposer.cpp | 37 +- alib2data/src/label/LabelToStringComposer.h | 17 +- .../primitive/PrimitiveFromStringLexer.cpp | 108 +++--- .../src/primitive/PrimitiveFromStringLexer.h | 14 +- .../primitive/PrimitiveFromStringParser.cpp | 41 +-- .../src/primitive/PrimitiveFromStringParser.h | 31 +- .../primitive/PrimitiveToStringComposer.cpp | 17 +- .../src/primitive/PrimitiveToStringComposer.h | 13 +- .../src/regexp/RegExpFromStringLexer.cpp | 107 +++--- alib2data/src/regexp/RegExpFromStringLexer.h | 30 +- .../src/regexp/RegExpFromStringParser.cpp | 132 +++---- alib2data/src/regexp/RegExpFromStringParser.h | 42 +-- .../src/regexp/RegExpToStringComposer.cpp | 132 ++++--- alib2data/src/regexp/RegExpToStringComposer.h | 32 +- .../src/string/StringFromStringLexer.cpp | 94 ++--- alib2data/src/string/StringFromStringLexer.h | 17 +- .../src/string/StringFromStringParser.cpp | 69 ++-- alib2data/src/string/StringFromStringParser.h | 29 +- .../src/string/StringToStringComposer.cpp | 27 +- alib2data/src/string/StringToStringComposer.h | 14 +- alib2data/test-src/alphabet/SymbolTest.cpp | 41 +-- .../test-src/automaton/AutomatonTest.cpp | 58 ++- alib2data/test-src/grammar/GrammarTest.cpp | 5 - alib2data/test-src/label/LabelTest.cpp | 53 +-- alib2data/test-src/regexp/RegExpTest.cpp | 42 +-- alib2data/test-src/string/StringTest.cpp | 41 +-- 64 files changed, 1629 insertions(+), 2094 deletions(-) delete mode 100644 alib2data/src/FromStringParser.hpp create mode 100644 alib2data/src/StringApi.cpp create mode 100644 alib2data/src/StringApi.hpp create mode 100644 alib2data/src/factory/StringDataFactory.hpp diff --git a/aconvert2/src/DotConverter.cpp b/aconvert2/src/DotConverter.cpp index fa7e22a488..dda74e017d 100644 --- a/aconvert2/src/DotConverter.cpp +++ b/aconvert2/src/DotConverter.cpp @@ -25,12 +25,9 @@ #include <automaton/PDA/SinglePopDPDA.h> #include <automaton/TM/OneTapeDTM.h> -#include <exception/AlibException.h> +#include <factory/StringDataFactory.hpp> -#include <alphabet/SymbolToStringComposer.h> -#include <regexp/RegExpToStringComposer.h> -#include <string/StringToStringComposer.h> -#include <label/LabelToStringComposer.h> +#include <exception/AlibException.h> #include <set> #include <map> @@ -52,7 +49,6 @@ void DotConverter::convert(const automaton::Automaton& a, std::ostream& out) { } void DotConverter::convert(const automaton::EpsilonNFA& a, std::ostream& out) { - label::LabelToStringComposer composer; out << "digraph automaton {\n"; out << "rankdir=LR;\n"; @@ -66,13 +62,13 @@ void DotConverter::convert(const automaton::EpsilonNFA& a, std::ostream& out) { //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -85,8 +81,6 @@ void DotConverter::convert(const automaton::EpsilonNFA& a, std::ostream& out) { } void DotConverter::convert(const automaton::MultiInitialStateNFA& a, std::ostream& out) { - label::LabelToStringComposer composer; - out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -99,13 +93,13 @@ void DotConverter::convert(const automaton::MultiInitialStateNFA& a, std::ostrea //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -120,8 +114,6 @@ void DotConverter::convert(const automaton::MultiInitialStateNFA& a, std::ostrea } void DotConverter::convert(const automaton::NFA& a, std::ostream& out) { - label::LabelToStringComposer composer; - out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -134,13 +126,13 @@ void DotConverter::convert(const automaton::NFA& a, std::ostream& out) { //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -153,8 +145,6 @@ void DotConverter::convert(const automaton::NFA& a, std::ostream& out) { } void DotConverter::convert(const automaton::DFA& a, std::ostream& out) { - label::LabelToStringComposer composer; - out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -167,13 +157,13 @@ void DotConverter::convert(const automaton::DFA& a, std::ostream& out) { //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -186,8 +176,6 @@ void DotConverter::convert(const automaton::DFA& a, std::ostream& out) { } void DotConverter::convert(const automaton::ExtendedNFA& a, std::ostream& out) { - label::LabelToStringComposer composer; - out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -200,13 +188,13 @@ void DotConverter::convert(const automaton::ExtendedNFA& a, std::ostream& out) { //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -219,8 +207,6 @@ void DotConverter::convert(const automaton::ExtendedNFA& a, std::ostream& out) { } void DotConverter::convert(const automaton::CompactNFA& a, std::ostream& out) { - label::LabelToStringComposer composer; - out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -233,13 +219,13 @@ void DotConverter::convert(const automaton::CompactNFA& a, std::ostream& out) { //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -252,8 +238,6 @@ void DotConverter::convert(const automaton::CompactNFA& a, std::ostream& out) { } void DotConverter::convert(const automaton::DPDA& a, std::ostream& out) { - label::LabelToStringComposer composer; - out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -266,13 +250,13 @@ void DotConverter::convert(const automaton::DPDA& a, std::ostream& out) { //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -285,8 +269,6 @@ void DotConverter::convert(const automaton::DPDA& a, std::ostream& out) { } void DotConverter::convert(const automaton::SinglePopDPDA& a, std::ostream& out) { - label::LabelToStringComposer composer; - out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -299,13 +281,13 @@ void DotConverter::convert(const automaton::SinglePopDPDA& a, std::ostream& out) //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -318,8 +300,6 @@ void DotConverter::convert(const automaton::SinglePopDPDA& a, std::ostream& out) } void DotConverter::convert(const automaton::InputDrivenNPDA& a, std::ostream& out) { - label::LabelToStringComposer composer; - out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -332,13 +312,13 @@ void DotConverter::convert(const automaton::InputDrivenNPDA& a, std::ostream& ou //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -353,8 +333,6 @@ void DotConverter::convert(const automaton::InputDrivenNPDA& a, std::ostream& ou } void DotConverter::convert(const automaton::VisiblyPushdownDPDA& a, std::ostream& out) { - label::LabelToStringComposer composer; - out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -367,13 +345,13 @@ void DotConverter::convert(const automaton::VisiblyPushdownDPDA& a, std::ostream //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -386,8 +364,6 @@ void DotConverter::convert(const automaton::VisiblyPushdownDPDA& a, std::ostream } void DotConverter::convert(const automaton::VisiblyPushdownNPDA& a, std::ostream& out) { - label::LabelToStringComposer composer; - out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -400,13 +376,13 @@ void DotConverter::convert(const automaton::VisiblyPushdownNPDA& a, std::ostream //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -421,8 +397,6 @@ void DotConverter::convert(const automaton::VisiblyPushdownNPDA& a, std::ostream } void DotConverter::convert(const automaton::RealTimeHeightDeterministicDPDA& a, std::ostream& out) { - label::LabelToStringComposer composer; - out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -435,13 +409,13 @@ void DotConverter::convert(const automaton::RealTimeHeightDeterministicDPDA& a, //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -454,8 +428,6 @@ void DotConverter::convert(const automaton::RealTimeHeightDeterministicDPDA& a, } void DotConverter::convert(const automaton::RealTimeHeightDeterministicNPDA& a, std::ostream& out) { - label::LabelToStringComposer composer; - out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -468,13 +440,13 @@ void DotConverter::convert(const automaton::RealTimeHeightDeterministicNPDA& a, //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -489,8 +461,6 @@ void DotConverter::convert(const automaton::RealTimeHeightDeterministicNPDA& a, } void DotConverter::convert(const automaton::NPDA& a, std::ostream& out) { - label::LabelToStringComposer composer; - out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -503,13 +473,13 @@ void DotConverter::convert(const automaton::NPDA& a, std::ostream& out) { //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -524,8 +494,6 @@ void DotConverter::convert(const automaton::NPDA& a, std::ostream& out) { } void DotConverter::convert(const automaton::SinglePopNPDA& a, std::ostream& out) { - label::LabelToStringComposer composer; - out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -538,13 +506,13 @@ void DotConverter::convert(const automaton::SinglePopNPDA& a, std::ostream& out) //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -559,8 +527,6 @@ void DotConverter::convert(const automaton::SinglePopNPDA& a, std::ostream& out) } void DotConverter::convert(const automaton::OneTapeDTM& a, std::ostream& out) { - label::LabelToStringComposer composer; - out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -573,13 +539,13 @@ void DotConverter::convert(const automaton::OneTapeDTM& a, std::ostream& out) { //Print final states for (const automaton::State& state : a.getFinalStates()) { - out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; + out << "node [shape = doublecircle, label=\"" << alib::StringDataFactory::toString(state.getName()) << "\"]; " << states.find(state)->second << ";\n"; } //Print nonfinal states for (const auto& state : states) { if (!a.getFinalStates().count(state.first)) { - out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n"; + out << "node [shape = circle, label=\"" << alib::StringDataFactory::toString(state.first.getName()) << "\" ]; " << state.second << ";\n"; } } @@ -600,8 +566,7 @@ void DotConverter::transitions(const automaton::EpsilonNFA& fsm, const std::map< if (transition.first.second.is<string::Epsilon>()) { symbol = "ε"; } else { - alphabet::SymbolToStringComposer composer; - symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first).get<alphabet::Symbol>()); } for(const automaton::State& to : transition.second) { @@ -636,8 +601,7 @@ void DotConverter::transitions(const automaton::MultiInitialStateNFA& fsm, const //put transitions from automaton to "transitions" for (const auto& transition : fsm.getTransitions()) { - alphabet::SymbolToStringComposer composer; - std::string symbol = composer.compose(transition.first.second); + std::string symbol = alib::StringDataFactory::toString(transition.first.second); for(const automaton::State& to : transition.second) { std::pair<int, int> key(states.find(transition.first.first)->second, states.find(to)->second); @@ -671,8 +635,7 @@ void DotConverter::transitions(const automaton::NFA& fsm, const std::map<automat //put transitions from automaton to "transitions" for (const auto& transition : fsm.getTransitions()) { - alphabet::SymbolToStringComposer composer; - std::string symbol = composer.compose(transition.first.second); + std::string symbol = alib::StringDataFactory::toString(transition.first.second); for(const automaton::State& to : transition.second) { std::pair<int, int> key(states.find(transition.first.first)->second, states.find(to)->second); @@ -706,8 +669,7 @@ void DotConverter::transitions(const automaton::DFA& fsm, const std::map<automat //put transitions from automaton to "transitions" for (const auto& transition : fsm.getTransitions()) { - alphabet::SymbolToStringComposer composer; - std::string symbol = composer.compose(transition.first.second); + std::string symbol = alib::StringDataFactory::toString(transition.first.second); std::pair<int, int> key(states.find(transition.first.first)->second, states.find(transition.second)->second); std::map<std::pair<int, int>, std::string>::iterator mapit = transitions.find(key); @@ -739,8 +701,7 @@ void DotConverter::transitions(const automaton::ExtendedNFA& fsm, const std::map //put transitions from automaton to "transitions" for (const auto& transition : fsm.getTransitions()) { - regexp::RegExpToStringComposer composer; - std::string symbol = composer.compose(transition.first.second); + std::string symbol = alib::StringDataFactory::toString(transition.first.second); for(const automaton::State& to : transition.second) { std::pair<int, int> key(states.find(transition.first.first)->second, states.find(to)->second); @@ -774,8 +735,7 @@ void DotConverter::transitions(const automaton::CompactNFA& fsm, const std::map< //put transitions from automaton to "transitions" for (const auto& transition : fsm.getTransitions()) { - string::StringToStringComposer composer; - std::string symbol = composer.compose(string::String { transition.first.second } ); + std::string symbol = alib::StringDataFactory::toString(string::String { transition.first.second } ); for(const automaton::State& to : transition.second) { std::pair<int, int> key(states.find(transition.first.first)->second, states.find(to)->second); @@ -814,8 +774,7 @@ void DotConverter::transitions(const automaton::DPDA& pda, const std::map<automa if (std::get<1>(transition.first).is<string::Epsilon>()) { symbol = "ε"; } else { - alphabet::SymbolToStringComposer composer; - symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first).get<alphabet::Symbol>()); } symbol += " |"; @@ -825,8 +784,7 @@ void DotConverter::transitions(const automaton::DPDA& pda, const std::map<automa symbol += " ε"; } else { for (alphabet::Symbol symb : std::get<2>(transition.first)) { - alphabet::SymbolToStringComposer composer; - symbol += " " + composer.compose(symb); + symbol += " " + alib::StringDataFactory::toString(symb); } } @@ -838,8 +796,7 @@ void DotConverter::transitions(const automaton::DPDA& pda, const std::map<automa symbol += " ε"; } else { for (alphabet::Symbol symb : transition.second.second) { - alphabet::SymbolToStringComposer composer; - symbol += " " + composer.compose(symb); + symbol += " " + alib::StringDataFactory::toString(symb); } } @@ -880,15 +837,13 @@ void DotConverter::transitions(const automaton::SinglePopDPDA& pda, const std::m if (std::get<1>(transition.first).is<string::Epsilon>()) { symbol = "ε"; } else { - alphabet::SymbolToStringComposer composer; - symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first).get<alphabet::Symbol>()); } symbol += " |"; //Pop part - alphabet::SymbolToStringComposer composer; - symbol += " " + composer.compose(std::get<2>(transition.first)); + symbol += " " + alib::StringDataFactory::toString(std::get<2>(transition.first)); symbol += " ->"; @@ -897,8 +852,7 @@ void DotConverter::transitions(const automaton::SinglePopDPDA& pda, const std::m symbol += " ε"; } else { for (alphabet::Symbol symb : transition.second.second) { - alphabet::SymbolToStringComposer composer; - symbol += " " + composer.compose(symb); + symbol += " " + alib::StringDataFactory::toString(symb); } } @@ -940,8 +894,7 @@ void DotConverter::transitions(const automaton::InputDrivenNPDA& pda, const std: std::string symbol; //input symbol - alphabet::SymbolToStringComposer composer; - symbol = composer.compose(transition.first.second); + symbol = alib::StringDataFactory::toString(transition.first.second); symbol += " |"; @@ -950,8 +903,7 @@ void DotConverter::transitions(const automaton::InputDrivenNPDA& pda, const std: symbol += " ε"; } else { for (alphabet::Symbol symb : pop) { - alphabet::SymbolToStringComposer composer; - symbol += " " + composer.compose(symb); + symbol += " " + alib::StringDataFactory::toString(symb); } } @@ -966,8 +918,7 @@ void DotConverter::transitions(const automaton::InputDrivenNPDA& pda, const std: symbol2 += " ε"; } else { for (alphabet::Symbol symb : push) { - alphabet::SymbolToStringComposer composer; - symbol2 += " " + composer.compose(symb); + symbol2 += " " + alib::StringDataFactory::toString(symb); } } @@ -1006,8 +957,7 @@ void DotConverter::transitions(const automaton::VisiblyPushdownDPDA& pda, const std::string symbol; //input symbol - alphabet::SymbolToStringComposer composer; - symbol = composer.compose(transition.first.second); + symbol = alib::StringDataFactory::toString(transition.first.second); symbol += " |"; @@ -1015,7 +965,7 @@ void DotConverter::transitions(const automaton::VisiblyPushdownDPDA& pda, const symbol += " ε"; symbol += " ->"; - symbol += " " + composer.compose(transition.second.second); + symbol += " " + alib::StringDataFactory::toString(transition.second.second); //Insert into map std::pair<int, int> key(states.find(transition.first.first)->second, states.find(transition.second.first)->second); @@ -1039,13 +989,12 @@ void DotConverter::transitions(const automaton::VisiblyPushdownDPDA& pda, const std::string symbol; //input symbol - alphabet::SymbolToStringComposer composer; - symbol = composer.compose(std::get<1>(transition.first)); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first)); symbol += " |"; //Pop part - symbol += " " + composer.compose(std::get<2>(transition.first)); + symbol += " " + alib::StringDataFactory::toString(std::get<2>(transition.first)); symbol += " ->"; symbol += " ε"; @@ -1072,8 +1021,7 @@ void DotConverter::transitions(const automaton::VisiblyPushdownDPDA& pda, const std::string symbol; //input symbol - alphabet::SymbolToStringComposer composer; - symbol = composer.compose(transition.first.second); + symbol = alib::StringDataFactory::toString(transition.first.second); symbol += " |"; @@ -1116,8 +1064,7 @@ void DotConverter::transitions(const automaton::VisiblyPushdownNPDA& pda, const std::string symbol; //input symbol - alphabet::SymbolToStringComposer composer; - symbol = composer.compose(transition.first.second); + symbol = alib::StringDataFactory::toString(transition.first.second); symbol += " |"; @@ -1128,8 +1075,7 @@ void DotConverter::transitions(const automaton::VisiblyPushdownNPDA& pda, const std::string symbol2; for(const auto& to : transition.second) { symbol2 = symbol; - alphabet::SymbolToStringComposer composer; - symbol2 += " " + composer.compose(to.second); + symbol2 += " " + alib::StringDataFactory::toString(to.second); //Insert into map std::pair<int, int> key(states.find(transition.first.first)->second, states.find(to.first)->second); @@ -1154,13 +1100,12 @@ void DotConverter::transitions(const automaton::VisiblyPushdownNPDA& pda, const std::string symbol; //input symbol - alphabet::SymbolToStringComposer composer; - symbol = composer.compose(std::get<1>(transition.first)); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first)); symbol += " |"; //Pop part - symbol += " " + composer.compose(std::get<2>(transition.first)); + symbol += " " + alib::StringDataFactory::toString(std::get<2>(transition.first)); symbol += " ->"; std::string symbol2; @@ -1191,8 +1136,7 @@ void DotConverter::transitions(const automaton::VisiblyPushdownNPDA& pda, const std::string symbol; //input symbol - alphabet::SymbolToStringComposer composer; - symbol = composer.compose(transition.first.second); + symbol = alib::StringDataFactory::toString(transition.first.second); symbol += " |"; @@ -1239,11 +1183,10 @@ void DotConverter::transitions(const automaton::RealTimeHeightDeterministicDPDA& std::string symbol; //input symbol - alphabet::SymbolToStringComposer composer; if(transition.first.second.is<string::Epsilon>()) symbol = "&epsilon"; else - symbol = composer.compose(transition.first.second.get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(transition.first.second.get<alphabet::Symbol>()); symbol += " |"; @@ -1251,7 +1194,7 @@ void DotConverter::transitions(const automaton::RealTimeHeightDeterministicDPDA& symbol += " ε"; symbol += " ->"; - symbol += " " + composer.compose(transition.second.second); + symbol += " " + alib::StringDataFactory::toString(transition.second.second); //Insert into map std::pair<int, int> key(states.find(transition.first.first)->second, states.find(transition.second.first)->second); @@ -1275,16 +1218,15 @@ void DotConverter::transitions(const automaton::RealTimeHeightDeterministicDPDA& std::string symbol; //input symbol - alphabet::SymbolToStringComposer composer; if(std::get<1>(transition.first).is<string::Epsilon>()) symbol = "&epsilon"; else - symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first).get<alphabet::Symbol>()); symbol += " |"; //Pop part - symbol += " " + composer.compose(std::get<2>(transition.first)); + symbol += " " + alib::StringDataFactory::toString(std::get<2>(transition.first)); symbol += " ->"; symbol += " ε"; @@ -1311,11 +1253,10 @@ void DotConverter::transitions(const automaton::RealTimeHeightDeterministicDPDA& std::string symbol; //input symbol - alphabet::SymbolToStringComposer composer; if(transition.first.second.is<string::Epsilon>()) symbol = "&epsilon"; else - symbol = composer.compose(transition.first.second.get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(transition.first.second.get<alphabet::Symbol>()); symbol += " |"; @@ -1358,11 +1299,10 @@ void DotConverter::transitions(const automaton::RealTimeHeightDeterministicNPDA& std::string symbol; //input symbol - alphabet::SymbolToStringComposer composer; if(transition.first.second.is<string::Epsilon>()) symbol = "&epsilon"; else - symbol = composer.compose(transition.first.second.get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(transition.first.second.get<alphabet::Symbol>()); symbol += " |"; @@ -1373,8 +1313,7 @@ void DotConverter::transitions(const automaton::RealTimeHeightDeterministicNPDA& std::string symbol2; for(const auto& to : transition.second) { symbol2 = symbol; - alphabet::SymbolToStringComposer composer; - symbol2 += " " + composer.compose(to.second); + symbol2 += " " + alib::StringDataFactory::toString(to.second); //Insert into map std::pair<int, int> key(states.find(transition.first.first)->second, states.find(to.first)->second); @@ -1399,16 +1338,15 @@ void DotConverter::transitions(const automaton::RealTimeHeightDeterministicNPDA& std::string symbol; //input symbol - alphabet::SymbolToStringComposer composer; if(std::get<1>(transition.first).is<string::Epsilon>()) symbol = "ε"; else - symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first).get<alphabet::Symbol>()); symbol += " |"; //Pop part - symbol += " " + composer.compose(std::get<2>(transition.first)); + symbol += " " + alib::StringDataFactory::toString(std::get<2>(transition.first)); symbol += " ->"; std::string symbol2; @@ -1439,11 +1377,10 @@ void DotConverter::transitions(const automaton::RealTimeHeightDeterministicNPDA& std::string symbol; //input symbol - alphabet::SymbolToStringComposer composer; if(transition.first.second.is<string::Epsilon>()) symbol = "ε"; else - symbol = composer.compose(transition.first.second.get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(transition.first.second.get<alphabet::Symbol>()); symbol += " |"; @@ -1493,8 +1430,7 @@ void DotConverter::transitions(const automaton::NPDA& pda, const std::map<automa if (std::get<1>(transition.first).is<string::Epsilon>()) { symbol = "ε"; } else { - alphabet::SymbolToStringComposer composer; - symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first).get<alphabet::Symbol>()); } symbol += " |"; @@ -1504,8 +1440,7 @@ void DotConverter::transitions(const automaton::NPDA& pda, const std::map<automa symbol += " ε"; } else { for (alphabet::Symbol symb : std::get<2>(transition.first)) { - alphabet::SymbolToStringComposer composer; - symbol += " " + composer.compose(symb); + symbol += " " + alib::StringDataFactory::toString(symb); } } @@ -1520,8 +1455,7 @@ void DotConverter::transitions(const automaton::NPDA& pda, const std::map<automa symbol2 += " ε"; } else { for (alphabet::Symbol symb : to.second) { - alphabet::SymbolToStringComposer composer; - symbol2 += " " + composer.compose(symb); + symbol2 += " " + alib::StringDataFactory::toString(symb); } } @@ -1563,15 +1497,13 @@ void DotConverter::transitions(const automaton::SinglePopNPDA& pda, const std::m if (std::get<1>(transition.first).is<string::Epsilon>()) { symbol = "ε"; } else { - alphabet::SymbolToStringComposer composer; - symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first).get<alphabet::Symbol>()); } symbol += " |"; //Pop part - alphabet::SymbolToStringComposer composer; - symbol += " " + composer.compose(std::get<2>(transition.first)); + symbol += " " + alib::StringDataFactory::toString(std::get<2>(transition.first)); symbol += " ->"; @@ -1583,8 +1515,7 @@ void DotConverter::transitions(const automaton::SinglePopNPDA& pda, const std::m symbol2 += " ε"; } else { for (alphabet::Symbol symb : to.second) { - alphabet::SymbolToStringComposer composer; - symbol2 += " " + composer.compose(symb); + symbol2 += " " + alib::StringDataFactory::toString(symb); } } @@ -1619,15 +1550,13 @@ void DotConverter::transitions(const automaton::SinglePopNPDA& pda, const std::m void DotConverter::transitions(const automaton::OneTapeDTM& tm, const std::map<automaton::State, int>& states, std::ostream& out) { std::map<std::pair<int, int>, std::string> transitions; for (const auto& transition : tm.getTransitions()) { - alphabet::SymbolToStringComposer composer; - std::string symbol; //input symbol symbol = "("; - symbol += composer.compose(transition.first.second); + symbol += alib::StringDataFactory::toString(transition.first.second); symbol += ", "; - symbol += composer.compose(std::get<1>(transition.second)); + symbol += alib::StringDataFactory::toString(std::get<1>(transition.second)); symbol += " "; switch(std::get<2>(transition.second)) { case automaton::Shift::LEFT: diff --git a/aconvert2/src/GasTexConverter.cpp b/aconvert2/src/GasTexConverter.cpp index d02190f7c6..65647c7879 100644 --- a/aconvert2/src/GasTexConverter.cpp +++ b/aconvert2/src/GasTexConverter.cpp @@ -24,9 +24,7 @@ #include <automaton/PDA/SinglePopNPDA.h> #include <automaton/TM/OneTapeDTM.h> -#include <alphabet/SymbolToStringComposer.h> -#include <regexp/RegExpToStringComposer.h> -#include <string/StringToStringComposer.h> +#include <factory/StringDataFactory.hpp> #include <set> #include <map> @@ -784,12 +782,11 @@ void GasTexConverter::transitions(const automaton::DFA& fsm, std::ostream& out) void GasTexConverter::transitions(const automaton::ExtendedNFA& fsm, std::ostream& out) { std::map<std::pair<std::string, std::string>, std::string> transitionMap; - regexp::RegExpToStringComposer composer; for (const auto& transition : fsm.getTransitions()) { for(const auto& to : transition.second) { std::pair<std::string, std::string> key(transition.first.first.getName(), to.getName()); - std::string symbol = composer.compose(transition.first.second); + std::string symbol = alib::StringDataFactory::toString(transition.first.second); auto mapIterator = transitionMap.find(key); if (mapIterator == transitionMap.end()) { @@ -805,12 +802,11 @@ void GasTexConverter::transitions(const automaton::ExtendedNFA& fsm, std::ostrea void GasTexConverter::transitions(const automaton::CompactNFA& fsm, std::ostream& out) { std::map<std::pair<std::string, std::string>, std::string> transitionMap; - string::StringToStringComposer composer; for (const auto& transition : fsm.getTransitions()) { for(const auto& to : transition.second) { std::pair<std::string, std::string> key(transition.first.first.getName(), to.getName()); - std::string symbol = composer.compose(string::String(transition.first.second)); + std::string symbol = alib::StringDataFactory::toString(string::String(transition.first.second)); auto mapIterator = transitionMap.find(key); if (mapIterator == transitionMap.end()) { @@ -826,7 +822,6 @@ void GasTexConverter::transitions(const automaton::CompactNFA& fsm, std::ostream void GasTexConverter::transitions(const automaton::DPDA& pda, std::ostream& out) { std::map<std::pair<std::string, std::string>, std::string> transitionMap; - alphabet::SymbolToStringComposer composer; for (const auto& transition : pda.getTransitions()) { std::pair<std::string, std::string> key((std::string) std::get<0>(transition.first).getName(), (std::string) transition.second.first.getName()); auto mapIterator = transitionMap.find(key); @@ -835,7 +830,7 @@ void GasTexConverter::transitions(const automaton::DPDA& pda, std::ostream& out) if (std::get<1>(transition.first).is<string::Epsilon>()) { symbol = "$\\varepsilon;$"; } else { - symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first).get<alphabet::Symbol>()); } symbol += "|"; @@ -857,7 +852,6 @@ void GasTexConverter::transitions(const automaton::DPDA& pda, std::ostream& out) void GasTexConverter::transitions(const automaton::SinglePopDPDA& pda, std::ostream& out) { std::map<std::pair<std::string, std::string>, std::string> transitionMap; - alphabet::SymbolToStringComposer composer; for (const auto& transition : pda.getTransitions()) { std::pair<std::string, std::string> key((std::string) std::get<0>(transition.first).getName(), (std::string) transition.second.first.getName()); auto mapIterator = transitionMap.find(key); @@ -866,12 +860,12 @@ void GasTexConverter::transitions(const automaton::SinglePopDPDA& pda, std::ostr if (std::get<1>(transition.first).is<string::Epsilon>()) { symbol = "$\\varepsilon;$"; } else { - symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first).get<alphabet::Symbol>()); } symbol += "|"; - symbol += composer.compose(std::get<2>(transition.first)); + symbol += alib::StringDataFactory::toString(std::get<2>(transition.first)); symbol += "\\rarrow"; symbol += getStackSymbols(transition.second.second); @@ -888,7 +882,6 @@ void GasTexConverter::transitions(const automaton::SinglePopDPDA& pda, std::ostr void GasTexConverter::transitions(const automaton::InputDrivenNPDA& pda, std::ostream& out) { std::map<std::pair<std::string, std::string>, std::string> transitionMap; - alphabet::SymbolToStringComposer composer; const auto& symbolToPDSOperation = pda.getPushdownStoreOperations(); for (const auto& transition : pda.getTransitions()) { const auto& pop = symbolToPDSOperation.find(std::get<1>(transition.first))->second.first; @@ -898,7 +891,7 @@ void GasTexConverter::transitions(const automaton::InputDrivenNPDA& pda, std::os std::pair<std::string, std::string> key((std::string) transition.first.first.getName(), (std::string) to.getName()); auto mapIterator = transitionMap.find(key); - std::string symbol = composer.compose(transition.first.second); + std::string symbol = alib::StringDataFactory::toString(transition.first.second); symbol += "|"; @@ -920,19 +913,18 @@ void GasTexConverter::transitions(const automaton::InputDrivenNPDA& pda, std::os void GasTexConverter::transitions(const automaton::VisiblyPushdownDPDA& pda, std::ostream& out) { std::map<std::pair<std::string, std::string>, std::string> transitionMap; - alphabet::SymbolToStringComposer composer; for (const auto& transition : pda.getCallTransitions()) { std::pair<std::string, std::string> key((std::string) transition.first.first.getName(), (std::string) transition.second.first.getName()); auto mapIterator = transitionMap.find(key); std::string symbol; - symbol = composer.compose(transition.first.second); + symbol = alib::StringDataFactory::toString(transition.first.second); symbol += "|"; symbol += "$\\varepsilon;$"; symbol += "\\rarrow"; - symbol += composer.compose(transition.second.second); + symbol += alib::StringDataFactory::toString(transition.second.second); if (mapIterator == transitionMap.end()) { transitionMap.insert(std::make_pair(key, symbol)); @@ -946,11 +938,11 @@ void GasTexConverter::transitions(const automaton::VisiblyPushdownDPDA& pda, std auto mapIterator = transitionMap.find(key); std::string symbol; - symbol = composer.compose(std::get<1>(transition.first)); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first)); symbol += "|"; - symbol += composer.compose(std::get<2>(transition.first)); + symbol += alib::StringDataFactory::toString(std::get<2>(transition.first)); symbol += "\\rarrow"; symbol += "$\\varepsilon;$"; @@ -966,7 +958,7 @@ void GasTexConverter::transitions(const automaton::VisiblyPushdownDPDA& pda, std auto mapIterator = transitionMap.find(key); std::string symbol; - symbol = composer.compose(transition.first.second); + symbol = alib::StringDataFactory::toString(transition.first.second); symbol += "|"; @@ -987,20 +979,19 @@ void GasTexConverter::transitions(const automaton::VisiblyPushdownDPDA& pda, std void GasTexConverter::transitions(const automaton::VisiblyPushdownNPDA& pda, std::ostream& out) { std::map<std::pair<std::string, std::string>, std::string> transitionMap; - alphabet::SymbolToStringComposer composer; for (const auto& transition : pda.getCallTransitions()) { for(const auto& to : transition.second) { std::pair<std::string, std::string> key((std::string) transition.first.first.getName(), (std::string) to.first.getName()); auto mapIterator = transitionMap.find(key); std::string symbol; - symbol = composer.compose(transition.first.second); + symbol = alib::StringDataFactory::toString(transition.first.second); symbol += "|"; symbol += "$\\varepsilon;$"; symbol += "\\rarrow"; - symbol += composer.compose(to.second); + symbol += alib::StringDataFactory::toString(to.second); if (mapIterator == transitionMap.end()) { transitionMap.insert(std::make_pair(key, symbol)); @@ -1016,11 +1007,11 @@ void GasTexConverter::transitions(const automaton::VisiblyPushdownNPDA& pda, std auto mapIterator = transitionMap.find(key); std::string symbol; - symbol = composer.compose(std::get<1>(transition.first)); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first)); symbol += "|"; - symbol += composer.compose(std::get<2>(transition.first)); + symbol += alib::StringDataFactory::toString(std::get<2>(transition.first)); symbol += "\\rarrow"; symbol += "$\\varepsilon;$"; @@ -1038,7 +1029,7 @@ void GasTexConverter::transitions(const automaton::VisiblyPushdownNPDA& pda, std auto mapIterator = transitionMap.find(key); std::string symbol; - symbol = composer.compose(transition.first.second); + symbol = alib::StringDataFactory::toString(transition.first.second); symbol += "|"; @@ -1060,7 +1051,6 @@ void GasTexConverter::transitions(const automaton::VisiblyPushdownNPDA& pda, std void GasTexConverter::transitions(const automaton::RealTimeHeightDeterministicDPDA& pda, std::ostream& out) { std::map<std::pair<std::string, std::string>, std::string> transitionMap; - alphabet::SymbolToStringComposer composer; for (const auto& transition : pda.getCallTransitions()) { std::pair<std::string, std::string> key((std::string) transition.first.first.getName(), (std::string) transition.second.first.getName()); auto mapIterator = transitionMap.find(key); @@ -1069,13 +1059,13 @@ void GasTexConverter::transitions(const automaton::RealTimeHeightDeterministicDP if(transition.first.second.is<string::Epsilon>()) symbol = "$\\varepsilon;$"; else - symbol = composer.compose(transition.first.second.get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(transition.first.second.get<alphabet::Symbol>()); symbol += "|"; symbol += "$\\varepsilon;$"; symbol += "\\rarrow"; - symbol += composer.compose(transition.second.second); + symbol += alib::StringDataFactory::toString(transition.second.second); if (mapIterator == transitionMap.end()) { transitionMap.insert(std::make_pair(key, symbol)); @@ -1092,11 +1082,11 @@ void GasTexConverter::transitions(const automaton::RealTimeHeightDeterministicDP if(std::get<1>(transition.first).is<string::Epsilon>()) symbol = "$\\varepsilon;$"; else - symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first).get<alphabet::Symbol>()); symbol += "|"; - symbol += composer.compose(std::get<2>(transition.first)); + symbol += alib::StringDataFactory::toString(std::get<2>(transition.first)); symbol += "\\rarrow"; symbol += "$\\varepsilon;$"; @@ -1115,7 +1105,7 @@ void GasTexConverter::transitions(const automaton::RealTimeHeightDeterministicDP if(transition.first.second.is<string::Epsilon>()) symbol = "$\\varepsilon;$"; else - symbol = composer.compose(transition.first.second.get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(transition.first.second.get<alphabet::Symbol>()); symbol += "|"; @@ -1136,7 +1126,6 @@ void GasTexConverter::transitions(const automaton::RealTimeHeightDeterministicDP void GasTexConverter::transitions(const automaton::RealTimeHeightDeterministicNPDA& pda, std::ostream& out) { std::map<std::pair<std::string, std::string>, std::string> transitionMap; - alphabet::SymbolToStringComposer composer; for (const auto& transition : pda.getCallTransitions()) { for(const auto& to : transition.second) { std::pair<std::string, std::string> key((std::string) transition.first.first.getName(), (std::string) to.first.getName()); @@ -1146,13 +1135,13 @@ void GasTexConverter::transitions(const automaton::RealTimeHeightDeterministicNP if(transition.first.second.is<string::Epsilon>()) symbol = "$\\varepsilon;$"; else - symbol = composer.compose(transition.first.second.get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(transition.first.second.get<alphabet::Symbol>()); symbol += "|"; symbol += "$\\varepsilon;$"; symbol += "\\rarrow"; - symbol += composer.compose(to.second); + symbol += alib::StringDataFactory::toString(to.second); if (mapIterator == transitionMap.end()) { transitionMap.insert(std::make_pair(key, symbol)); @@ -1171,11 +1160,11 @@ void GasTexConverter::transitions(const automaton::RealTimeHeightDeterministicNP if(std::get<1>(transition.first).is<string::Epsilon>()) symbol = "$\\varepsilon;$"; else - symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first).get<alphabet::Symbol>()); symbol += "|"; - symbol += composer.compose(std::get<2>(transition.first)); + symbol += alib::StringDataFactory::toString(std::get<2>(transition.first)); symbol += "\\rarrow"; symbol += "$\\varepsilon;$"; @@ -1196,7 +1185,7 @@ void GasTexConverter::transitions(const automaton::RealTimeHeightDeterministicNP if(transition.first.second.is<string::Epsilon>()) symbol = "$\\varepsilon;$"; else - symbol = composer.compose(transition.first.second.get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(transition.first.second.get<alphabet::Symbol>()); symbol += "|"; @@ -1218,7 +1207,6 @@ void GasTexConverter::transitions(const automaton::RealTimeHeightDeterministicNP void GasTexConverter::transitions(const automaton::NPDA& pda, std::ostream& out) { std::map<std::pair<std::string, std::string>, std::string> transitionMap; - alphabet::SymbolToStringComposer composer; for (const auto& transition : pda.getTransitions()) { for(const auto& to : transition.second) { std::pair<std::string, std::string> key((std::string) std::get<0>(transition.first).getName(), (std::string) to.first.getName()); @@ -1228,7 +1216,7 @@ void GasTexConverter::transitions(const automaton::NPDA& pda, std::ostream& out) if (std::get<1>(transition.first).is<string::Epsilon>()) { symbol = "$\\varepsilon;$"; } else { - symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first).get<alphabet::Symbol>()); } symbol += "|"; @@ -1251,7 +1239,6 @@ void GasTexConverter::transitions(const automaton::NPDA& pda, std::ostream& out) void GasTexConverter::transitions(const automaton::SinglePopNPDA& pda, std::ostream& out) { std::map<std::pair<std::string, std::string>, std::string> transitionMap; - alphabet::SymbolToStringComposer composer; for (const auto& transition : pda.getTransitions()) { for(const auto& to : transition.second) { std::pair<std::string, std::string> key((std::string) std::get<0>(transition.first).getName(), (std::string) to.first.getName()); @@ -1261,12 +1248,12 @@ void GasTexConverter::transitions(const automaton::SinglePopNPDA& pda, std::ostr if (std::get<1>(transition.first).is<string::Epsilon>()) { symbol = "$\\varepsilon;$"; } else { - symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>()); + symbol = alib::StringDataFactory::toString(std::get<1>(transition.first).get<alphabet::Symbol>()); } symbol += "|"; - symbol += composer.compose(std::get<2>(transition.first)); + symbol += alib::StringDataFactory::toString(std::get<2>(transition.first)); symbol += "\\rarrow"; symbol += getStackSymbols(to.second); @@ -1284,14 +1271,13 @@ void GasTexConverter::transitions(const automaton::SinglePopNPDA& pda, std::ostr void GasTexConverter::transitions(const automaton::OneTapeDTM& tm, std::ostream& out) { std::map<std::pair<std::string, std::string>, std::string> transitionMap; - alphabet::SymbolToStringComposer composer; for (auto& transition : tm.getTransitions()) { std::pair<std::string, std::string> key((std::string) transition.first.first.getName(), (std::string) std::get<0>(transition.second).getName()); auto mapIterator = transitionMap.find(key); - std::string symbol = composer.compose(transition.first.second); + std::string symbol = alib::StringDataFactory::toString(transition.first.second); symbol += "/"; - symbol += composer.compose(std::get<1>(transition.second)); + symbol += alib::StringDataFactory::toString(std::get<1>(transition.second)); symbol += ","; switch(std::get<2>(transition.second)) { case automaton::Shift::LEFT: diff --git a/aconvert2/src/aconvert.cpp b/aconvert2/src/aconvert.cpp index dd732bde7e..8ee133ebcf 100644 --- a/aconvert2/src/aconvert.cpp +++ b/aconvert2/src/aconvert.cpp @@ -8,68 +8,44 @@ #include <tclap/CmdLine.h> #include <fstream> -#include "automaton/FSM/FiniteAutomatonFromStringParser.h" -#include "automaton/FSM/FiniteAutomatonToStringComposer.h" -#include "grammar/GrammarFromStringParser.h" -#include "grammar/GrammarToStringComposer.h" -#include "regexp/RegExpFromStringParser.h" -#include "regexp/RegExpToStringComposer.h" -#include "string/StringFromStringParser.h" -#include "string/StringToStringComposer.h" - #include "automaton/Automaton.h" #include "factory/DataFactory.hpp" +#include "factory/StringDataFactory.hpp" #include "exception/AlibException.h" #include "DotConverter.h" #include "GasTexConverter.h" void automatonFromString(std::istream& in, std::ostream& out) { - automaton::FiniteAutomatonFromStringParser parser(in); - automaton::Automaton result = parser.parseValue(); - alib::DataFactory::toStream(result, out); + alib::DataFactory::toStream(alib::StringDataFactory::fromStream<automaton::Automaton>(in), out); } void grammarFromString(std::istream& in, std::ostream& out) { - grammar::GrammarFromStringParser parser(in); - grammar::Grammar result = parser.parseValue(); - alib::DataFactory::toStream(result, out); + alib::DataFactory::toStream(alib::StringDataFactory::fromStream<grammar::Grammar>(in), out); } void regexpFromString(std::istream& in, std::ostream& out) { - regexp::RegExpFromStringParser parser(in); - regexp::RegExp result = parser.parseValue(); - alib::DataFactory::toStream(result, out); + alib::DataFactory::toStream(alib::StringDataFactory::fromStream<regexp::RegExp>(in), out); } void stringFromString(std::istream& in, std::ostream& out) { - string::StringFromStringParser parser(in); - string::String result = parser.parseValue(); - alib::DataFactory::toStream(result, out); + alib::DataFactory::toStream(alib::StringDataFactory::fromStream<string::String>(in), out); } void automatonToString(std::istream& in, std::ostream& out) { - automaton::Automaton automaton = alib::DataFactory::fromStream<automaton::Automaton>(in); - automaton::FiniteAutomatonToStringComposer composer; - out << composer.compose(automaton); + alib::StringDataFactory::toStream(alib::DataFactory::fromStream<automaton::Automaton>(in), out); } void grammarToString(std::istream& in, std::ostream& out) { - grammar::Grammar grammar = alib::DataFactory::fromStream<grammar::Grammar>(in); - grammar::GrammarToStringComposer composer; - out << composer.compose(grammar); + alib::StringDataFactory::toStream(alib::DataFactory::fromStream<grammar::Grammar>(in), out); } void regexpToString(std::istream& in, std::ostream& out) { - regexp::RegExp regexp = alib::DataFactory::fromStream<regexp::RegExp>(in); - regexp::RegExpToStringComposer composer; - out << composer.compose(regexp); + alib::StringDataFactory::toStream(alib::DataFactory::fromStream<regexp::RegExp>(in), out); } void stringToString(std::istream& in, std::ostream& out) { - string::String string = alib::DataFactory::fromStream<string::String>(in); - string::StringToStringComposer composer; - out << composer.compose(string); + alib::StringDataFactory::toStream(alib::DataFactory::fromStream<string::String>(in), out); } void automatonToDot(std::istream& in, std::ostream& out) { diff --git a/alib2algo/test-src/grammar/simplify/GrammarToCNFTest.cpp b/alib2algo/test-src/grammar/simplify/GrammarToCNFTest.cpp index 5619eb15b7..825517bdf6 100644 --- a/alib2algo/test-src/grammar/simplify/GrammarToCNFTest.cpp +++ b/alib2algo/test-src/grammar/simplify/GrammarToCNFTest.cpp @@ -5,13 +5,14 @@ #include "grammar/ContextFree/CFG.h" #include "grammar/ContextFree/CNF.h" -#include "grammar/GrammarToStringComposer.h" #include "alphabet/SymbolPairSymbol.h" #include "alphabet/UniqueSymbol.h" #include "primitive/Integer.h" #include "std/pair.hpp" +#include <factory/StringDataFactory.hpp> + #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) CPPUNIT_TEST_SUITE_REGISTRATION( GrammarToCNFTest ); @@ -103,10 +104,8 @@ void GrammarToCNFTest::testToCNFRules2() { grammar3.addRule(bP, b); grammar3.addRule(cP, c); - grammar::GrammarToStringComposer gscomp; - - std::cout << gscomp.compose(grammar2) << std::endl; - std::cout << gscomp.compose(grammar3) << std::endl; + std::cout << alib::StringDataFactory::toString<grammar::Grammar>(grammar::Grammar(grammar2)) << std::endl; + std::cout << alib::StringDataFactory::toString<grammar::Grammar>(grammar::Grammar(grammar3)) << std::endl; CPPUNIT_ASSERT(grammar2 == grammar3); } diff --git a/alib2algo/test-src/regexp/RegExpTest.cpp b/alib2algo/test-src/regexp/RegExpTest.cpp index 3c76331c1f..6b2fc44481 100644 --- a/alib2algo/test-src/regexp/RegExpTest.cpp +++ b/alib2algo/test-src/regexp/RegExpTest.cpp @@ -9,6 +9,8 @@ #include "regexp/GlushkovTraversal.h" +#include <factory/StringDataFactory.hpp> + #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) #define CPPUNIT_EXCLUSIVE_OR(x, y) CPPUNIT_ASSERT((!(x) && (y)) || ((x) && !(y))) @@ -23,10 +25,7 @@ void RegExpTest::tearDown() { void RegExpTest::testFirst() { { std::string input = "#E* #0*"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) ); + regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) ); std::set<regexp::GlushkovSymbol> first = regexp::GlushkovTraversal::first(regexp); @@ -34,10 +33,7 @@ void RegExpTest::testFirst() { } { std::string input = "#E* a"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) ); + regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) ); std::set<regexp::GlushkovSymbol> first = regexp::GlushkovTraversal::first(regexp); @@ -49,10 +45,7 @@ void RegExpTest::testFirst() { void RegExpTest::testLast() { { std::string input = "a+a"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) ); + regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) ); std::set<regexp::GlushkovSymbol> last = regexp::GlushkovTraversal::last(regexp); @@ -60,10 +53,7 @@ void RegExpTest::testLast() { } { std::string input = "(a+a)b"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) ); + regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) ); std::set<regexp::GlushkovSymbol> last = regexp::GlushkovTraversal::last(regexp); @@ -74,10 +64,7 @@ void RegExpTest::testLast() { void RegExpTest::testFollow() { { std::string input = "(a+a)b"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) ); + regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) ); std::set<regexp::GlushkovSymbol> symbols = regexp::GlushkovTraversal::getSymbols(regexp); auto symbolsIter = symbols.begin(); @@ -98,10 +85,7 @@ void RegExpTest::testFollow() { } { std::string input = "a+a* (b+a)* c"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) ); + regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) ); std::set<regexp::GlushkovSymbol> symbols = regexp::GlushkovTraversal::getSymbols(regexp); auto symbolsIter = symbols.begin(); diff --git a/alib2algo/test-src/regexp/properties/RegExpEmptyTest.cpp b/alib2algo/test-src/regexp/properties/RegExpEmptyTest.cpp index bf5dfdb0d2..30070bee67 100644 --- a/alib2algo/test-src/regexp/properties/RegExpEmptyTest.cpp +++ b/alib2algo/test-src/regexp/properties/RegExpEmptyTest.cpp @@ -2,9 +2,9 @@ #include "regexp/properties/RegExpEmpty.h" -#include <sstream> #include <regexp/RegExp.h> -#include <regexp/RegExpFromStringParser.h> + +#include <factory/StringDataFactory.hpp> CPPUNIT_TEST_SUITE_REGISTRATION( RegExpEmptyTest ); @@ -17,17 +17,13 @@ void RegExpEmptyTest::tearDown() { void RegExpEmptyTest::testRegExpEmpty() { { std::string input = "(#E #0 ) + ( #0 a + (b ( #0 (a*) ) ) )"; - std::stringstream inputs(input); - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp re = parser.parseValue(); + regexp::RegExp re = alib::StringDataFactory::fromString<regexp::RegExp>(input); CPPUNIT_ASSERT(regexp::properties::RegExpEmpty::languageIsEmpty(re)); } { std::string input = "(#E + a ) + ( #0 a + (b ( #0 (a*) ) ) )"; - std::stringstream inputs(input); - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp re = parser.parseValue(); + regexp::RegExp re = alib::StringDataFactory::fromString<regexp::RegExp>(input); CPPUNIT_ASSERT(! regexp::properties::RegExpEmpty::languageIsEmpty(re)); } diff --git a/alib2algo/test-src/regexp/properties/RegExpEpsilonTest.cpp b/alib2algo/test-src/regexp/properties/RegExpEpsilonTest.cpp index 05c2af2065..3af298b6ab 100644 --- a/alib2algo/test-src/regexp/properties/RegExpEpsilonTest.cpp +++ b/alib2algo/test-src/regexp/properties/RegExpEpsilonTest.cpp @@ -1,9 +1,8 @@ #include "RegExpEpsilonTest.h" #include "regexp/properties/RegExpEpsilon.h" -#include <sstream> -#include <regexp/RegExpFromStringParser.h> +#include <factory/StringDataFactory.hpp> CPPUNIT_TEST_SUITE_REGISTRATION( RegExpEpsilonTest ); @@ -16,57 +15,43 @@ void RegExpEpsilonTest::tearDown() { void RegExpEpsilonTest::testRegExpEpsilon() { { std::string input = "#E + ( (a #E) + a*)"; - std::stringstream inputs(input); - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp re = parser.parseValue(); + regexp::RegExp re = alib::StringDataFactory::fromString<regexp::RegExp>(input); CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re)); } { std::string input = "( a* )( a* )"; - std::stringstream inputs(input); - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp re = parser.parseValue(); + regexp::RegExp re = alib::StringDataFactory::fromString<regexp::RegExp>(input); CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re)); } { std::string input = "a + #0"; - std::stringstream inputs(input); - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp re = parser.parseValue(); + regexp::RegExp re = alib::StringDataFactory::fromString<regexp::RegExp>(input); CPPUNIT_ASSERT(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(re)); } { std::string input = "#E + a #E + a*"; - std::stringstream inputs(input); - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp re = parser.parseValue(); + regexp::RegExp re = alib::StringDataFactory::fromString<regexp::RegExp>(input); CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re)); } { std::string input = "a* a*"; - std::stringstream inputs(input); - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp re = parser.parseValue(); + regexp::RegExp re = alib::StringDataFactory::fromString<regexp::RegExp>(input); CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re)); } { std::string input = "a s d #E + #E #0"; - std::stringstream inputs(input); - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp re = parser.parseValue(); + regexp::RegExp re = alib::StringDataFactory::fromString<regexp::RegExp>(input); CPPUNIT_ASSERT(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(re)); } { std::string input = "a + #0"; - std::stringstream inputs(input); - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp re = parser.parseValue(); + regexp::RegExp re = alib::StringDataFactory::fromString<regexp::RegExp>(input); CPPUNIT_ASSERT(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(re)); } diff --git a/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp b/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp index 41c7be67a9..ce170128e8 100644 --- a/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp +++ b/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp @@ -2,10 +2,11 @@ #include "RegExpOptimizeTest.h" #include "regexp/unbounded/UnboundedRegExp.h" -#include "regexp/RegExpFromStringParser.h" #include "regexp/simplify/RegExpOptimize.h" +#include <factory/StringDataFactory.hpp> + #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) #define CPPUNIT_EXCLUSIVE_OR(x, y) CPPUNIT_ASSERT((!(x) && (y)) || ((x) && !(y))) @@ -20,19 +21,13 @@ void RegExpOptimizeTest::tearDown() { void RegExpOptimizeTest::testOptimize() { { std::string input = "(a+a)b + (#0 b + (#0 a + (#0 b + a)))"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) ); + regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) ); regexp::UnboundedRegExp res = regexp::simplify::RegExpOptimize::optimize(regexp); } { std::string input = "a+a* (b+a)* c"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) ); + regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) ); } diff --git a/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp b/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp index f02d812edb..9ad8525789 100644 --- a/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp +++ b/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp @@ -11,10 +11,10 @@ #include "automaton/simplify/EpsilonRemoverOutgoing.h" #include "regexp/unbounded/UnboundedRegExp.h" -#include "regexp/RegExpFromStringParser.h" #include "automaton/FSM/NFA.h" #include <factory/DataFactory.hpp> +#include <factory/StringDataFactory.hpp> CPPUNIT_TEST_SUITE_REGISTRATION( re2faTest ); @@ -26,10 +26,7 @@ void re2faTest::tearDown() { void re2faTest::testThompson() { std::string input = "a+a* b*"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp regexp1( parser.parseValue() ); + regexp::RegExp regexp1 = alib::StringDataFactory::fromString<regexp::RegExp>(input); automaton::Automaton enfa1 = regexp::convert::ToAutomatonThompson::convert(regexp1); @@ -51,10 +48,7 @@ void re2faTest::testThompson() { void re2faTest::testGlushkov() { std::string input = "a+a* b*"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::UnboundedRegExp regexp1( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) ); + regexp::UnboundedRegExp regexp1( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) ); automaton::NFA nfa1 = regexp::convert::ToAutomatonGlushkov::convert(regexp1); @@ -73,10 +67,7 @@ void re2faTest::testGlushkov() { void re2faTest::testBrzozowski() { std::string input = "a+a* b*"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp regexp1( parser.parseValue() ); + regexp::RegExp regexp1 = alib::StringDataFactory::fromString<regexp::RegExp>(input); automaton::Automaton nfa1 = regexp::convert::ToAutomatonDerivation::convert(regexp1); diff --git a/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp b/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp index 0f2441f469..53779010c7 100644 --- a/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp +++ b/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp @@ -2,10 +2,9 @@ #include "regexp/transform/RegExpConcatenate.h" -#include <sstream> #include <regexp/RegExp.h> -#include <regexp/RegExpFromStringParser.h> -#include "std/set.hpp" + +#include <factory/StringDataFactory.hpp> CPPUNIT_TEST_SUITE_REGISTRATION( RegExpConcatenateTest ); @@ -18,55 +17,41 @@ void RegExpConcatenateTest::tearDown() { void RegExpConcatenateTest::testRegExpConcatenate() { { std::string input1 = "(#E a b)"; - std::stringstream inputs1(input1); - regexp::RegExpFromStringParser parser1(inputs1); - regexp::RegExp re1 = parser1.parseValue(); + regexp::RegExp re1 = alib::StringDataFactory::fromString<regexp::RegExp>(input1); std::string input2 = "(#E a c)"; - std::stringstream inputs2(input2); - regexp::RegExpFromStringParser parser2(inputs2); - regexp::RegExp re2 = parser2.parseValue(); + regexp::RegExp re2 = alib::StringDataFactory::fromString<regexp::RegExp>(input2); regexp::RegExp re = regexp::RegExpConcatenate::concatenate(re1, re2); std::string inputr = "(#E a b)(#E a c)"; - std::stringstream inputsr(inputr); - regexp::RegExpFromStringParser parserr(inputsr); - regexp::RegExp rer = parserr.parseValue(); + regexp::RegExp rer = alib::StringDataFactory::fromString<regexp::RegExp>(inputr); CPPUNIT_ASSERT(re == rer); } { std::string input1 = "(#E a b)"; - std::stringstream inputs1(input1); - regexp::RegExpFromStringParser parser1(inputs1); - regexp::RegExp re1 = parser1.parseValue(); + regexp::RegExp re1 = alib::StringDataFactory::fromString<regexp::RegExp>(input1); regexp::RegExp re2(regexp::FormalRegExp(regexp::FormalRegExpConcatenation(regexp::FormalRegExpEmpty {}, regexp::FormalRegExpEpsilon {}))); regexp::RegExp re = regexp::RegExpConcatenate::concatenate(re1, re2); std::string inputr = "(#E a b)(#0 #E )"; - std::stringstream inputsr(inputr); - regexp::RegExpFromStringParser parserr(inputsr); - regexp::RegExp rer = parserr.parseValue(); + regexp::RegExp rer = alib::StringDataFactory::fromString<regexp::RegExp>(inputr); CPPUNIT_ASSERT(re == rer); } { regexp::RegExp re1(regexp::FormalRegExp(regexp::FormalRegExpConcatenation(regexp::FormalRegExpEmpty {}, regexp::FormalRegExpEpsilon {}))); - std::string input1 = "(#E a b)"; - std::stringstream inputs1(input1); - regexp::RegExpFromStringParser parser1(inputs1); - regexp::RegExp re2 = parser1.parseValue(); + std::string input2 = "(#E a b)"; + regexp::RegExp re2 = alib::StringDataFactory::fromString<regexp::RegExp>(input2); regexp::RegExp re = regexp::RegExpConcatenate::concatenate(re1, re2); std::string inputr = "(#0 #E )(#E a b)"; - std::stringstream inputsr(inputr); - regexp::RegExpFromStringParser parserr(inputsr); - regexp::RegExp tmp = parserr.parseValue(); + regexp::RegExp tmp = alib::StringDataFactory::fromString<regexp::RegExp>(inputr); regexp::RegExp rer(regexp::FormalRegExp(static_cast<const regexp::UnboundedRegExp&>(tmp.getData()))); std::cout << (static_cast<const regexp::UnboundedRegExp&>(tmp.getData())).getAlphabet() << std::endl; diff --git a/alib2algo/test-src/regexp/transform/RegExpDerivationTest.cpp b/alib2algo/test-src/regexp/transform/RegExpDerivationTest.cpp index 268a9e20f9..e569d06b69 100644 --- a/alib2algo/test-src/regexp/transform/RegExpDerivationTest.cpp +++ b/alib2algo/test-src/regexp/transform/RegExpDerivationTest.cpp @@ -1,12 +1,8 @@ -#include <sstream> - #include "RegExpDerivationTest.h" #include "regexp/transform/RegExpDerivation.h" -#include <regexp/RegExpFromStringParser.h> -#include <regexp/RegExpToStringComposer.h> -#include <string/StringFromStringParser.h> +#include <factory/StringDataFactory.hpp> #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) @@ -34,17 +30,11 @@ void RegExpDerivationTest::testRegExpDerivation() { } void RegExpDerivationTest::ExecSingleTest(std::string regexp_str, std::string string_str, std::string result) { - std::stringstream regexp_ss(regexp_str); - regexp::RegExpFromStringParser regexp_parser(regexp_ss); - regexp::RegExp regexp = regexp_parser.parseValue(); + regexp::RegExp regexp = alib::StringDataFactory::fromString<regexp::RegExp>(regexp_str); - std::stringstream string_ss("\"" + string_str + "\""); - string::StringFromStringParser string_parser(string_ss); - string::String string = string_parser.parseValue(); + string::String string = alib::StringDataFactory::fromString<string::String>("\"" + string_str + "\""); regexp::RegExpDerivation d; - regexp::RegExpToStringComposer regexp_composer; - // TODO - // CPPUNIT_ASSERT(regexp_composer.compose(d.derivation(regexp, string)) == result); + // CPPUNIT_ASSERT(alib::StringDataFactory::toString<regexp::RegExp>(d.derivation(regexp, string)) == result); } diff --git a/alib2algo/test-src/regexp/transform/RegExpIntegralTest.cpp b/alib2algo/test-src/regexp/transform/RegExpIntegralTest.cpp index a4ec1514ee..41c55c5d5a 100644 --- a/alib2algo/test-src/regexp/transform/RegExpIntegralTest.cpp +++ b/alib2algo/test-src/regexp/transform/RegExpIntegralTest.cpp @@ -1,12 +1,8 @@ -#include <sstream> - #include "RegExpIntegralTest.h" #include "regexp/transform/RegExpIntegral.h" -#include <regexp/RegExpFromStringParser.h> -#include <regexp/RegExpToStringComposer.h> -#include <string/StringFromStringParser.h> +#include <factory/StringDataFactory.hpp> #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) @@ -26,17 +22,12 @@ void RegExpIntegralTest::testRegExpIntegral() { } void RegExpIntegralTest::ExecSingleTest(std::string regexp_str, std::string string_str, std::string result) { - std::stringstream regexp_ss(regexp_str); - regexp::RegExpFromStringParser regexp_parser(regexp_ss); - regexp::RegExp regexp = regexp_parser.parseValue(); + regexp::RegExp regexp = alib::StringDataFactory::fromString<regexp::RegExp>(regexp_str); - std::stringstream string_ss("\"" + string_str + "\""); - string::StringFromStringParser string_parser(string_ss); - string::String string = string_parser.parseValue(); + string::String string = alib::StringDataFactory::fromString<string::String>("\"" + string_str + "\""); regexp::RegExpIntegral i; - regexp::RegExpToStringComposer regexp_composer; // TODO - // CPPUNIT_ASSERT(regexp_composer.compose(i.integral(regexp, string)) == result); + // CPPUNIT_ASSERT(alib::StringDataFactory::toString<regexp::RegExp>(i.integral(regexp, string)) == result); } diff --git a/alib2data/src/FromStringParser.hpp b/alib2data/src/FromStringParser.hpp deleted file mode 100644 index b8b295700a..0000000000 --- a/alib2data/src/FromStringParser.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * FromStringParser.h - * - * Created on: Nov 23, 2013 - * Author: Jan Travnicek - */ - -#ifndef FROM_STRING_PARSER_H_ -#define FROM_STRING_PARSER_H_ - -#include <set> -#include "exception/AlibException.h" - -namespace alib { - -template<class T, class F> -class FromStringParser { - virtual T parse() = 0; - virtual T parse(const std::set<F>& features) = 0; - virtual bool last() = 0; -public: - virtual bool first() = 0; - T* parsePointer() { - if(first()) { - return new T(parse()); - } else { - return NULL; - } - } - - T parseValue() { - first(); - T res = parse(); - - if(last()) { - return std::move(res); - } else { - throw exception::AlibException(); - } - } -}; - -} /* namespace alib */ - -#endif /* FROM_STRING_PARSER_H_ */ diff --git a/alib2data/src/StringApi.cpp b/alib2data/src/StringApi.cpp new file mode 100644 index 0000000000..cadca5b6ab --- /dev/null +++ b/alib2data/src/StringApi.cpp @@ -0,0 +1,88 @@ +/* + * StringApi.cpp + * + * Created on: Apr 1, 2013 + * Author: Jan Travnicek + */ + +#include "StringApi.hpp" + +#include "exception/AlibException.h" + +namespace alib { + +const label::LabelFromStringParser FromStringParsers::labelParser; +const alphabet::SymbolFromStringParser FromStringParsers::symbolParser; +const regexp::RegExpFromStringParser FromStringParsers::regexpParser; +const string::StringFromStringParser FromStringParsers::stringParser; +const automaton::FiniteAutomatonFromStringParser FromStringParsers::automatonParser; +const grammar::GrammarFromStringParser FromStringParsers::grammarParser; +const primitive::PrimitiveFromStringParser FromStringParsers::primitiveParser; + +const label::LabelToStringComposer ToStringComposers::labelComposer; +const alphabet::SymbolToStringComposer ToStringComposers::symbolComposer; +const regexp::RegExpToStringComposer ToStringComposers::regexpComposer; +const string::StringToStringComposer ToStringComposers::stringComposer; +const automaton::FiniteAutomatonToStringComposer ToStringComposers::automatonComposer; +const grammar::GrammarToStringComposer ToStringComposers::grammarComposer; +const primitive::PrimitiveToStringComposer ToStringComposers::primitiveComposer; + +alphabet::Symbol stringApi<alphabet::Symbol>::parse(std::istream& input) { + return FromStringParsers::symbolParser.parseSymbol(input); +} + +void stringApi<alphabet::Symbol>::compose(std::ostream& output, const alphabet::Symbol& data) { + return ToStringComposers::symbolComposer.compose(output, data); +} + + +automaton::Automaton stringApi<automaton::Automaton>::parse(std::istream& input) { + return FromStringParsers::automatonParser.parseAutomaton(input); +} + +void stringApi<automaton::Automaton>::compose(std::ostream& output, const automaton::Automaton& data) { + return ToStringComposers::automatonComposer.compose(output, data); +} + +grammar::Grammar stringApi<grammar::Grammar>::parse(std::istream& input) { + return FromStringParsers::grammarParser.parseGrammar(input); +} + +void stringApi<grammar::Grammar>::compose(std::ostream& output, const grammar::Grammar& data) { + return ToStringComposers::grammarComposer.compose(output, data); +} + +label::Label stringApi<label::Label>::parse(std::istream& input) { + return FromStringParsers::labelParser.parseLabel(input); +} + +void stringApi<label::Label>::compose(std::ostream& output, const label::Label& data) { + return ToStringComposers::labelComposer.compose(output, data); +} + +regexp::RegExp stringApi<regexp::RegExp>::parse(std::istream& input) { + return FromStringParsers::regexpParser.parseRegExp(input); +} + +void stringApi<regexp::RegExp>::compose(std::ostream& output, const regexp::RegExp& data) { + return ToStringComposers::regexpComposer.compose(output, data); +} + +string::String stringApi<string::String>::parse(std::istream& input) { + return FromStringParsers::stringParser.parseString(input); +} + +void stringApi<string::String>::compose(std::ostream& output, const string::String& data) { + return ToStringComposers::stringComposer.compose(output, data); +} + + +primitive::Primitive stringApi<primitive::Primitive>::parse(std::istream& input) { + return FromStringParsers::primitiveParser.parsePrimitive(input); +} + +void stringApi<primitive::Primitive>::compose(std::ostream& output, const primitive::Primitive& data) { + return ToStringComposers::primitiveComposer.compose(output, data); +} + +} /* namespace alib */ diff --git a/alib2data/src/StringApi.hpp b/alib2data/src/StringApi.hpp new file mode 100644 index 0000000000..5b5009ccee --- /dev/null +++ b/alib2data/src/StringApi.hpp @@ -0,0 +1,105 @@ +/* + * StringApi.hpp + * + * Created on: Dec 27, 2014 + * Author: Jan Travnicek + */ + +#ifndef STRING_API_HPP_ +#define STRING_API_HPP_ + +#include "label/LabelFromStringParser.h" +#include "alphabet/SymbolFromStringParser.h" +#include "regexp/RegExpFromStringParser.h" +#include "string/StringFromStringParser.h" +#include "automaton/FSM/FiniteAutomatonFromStringParser.h" +#include "grammar/GrammarFromStringParser.h" +#include "primitive/PrimitiveFromStringParser.h" + +#include "label/LabelToStringComposer.h" +#include "alphabet/SymbolToStringComposer.h" +#include "regexp/RegExpToStringComposer.h" +#include "string/StringToStringComposer.h" +#include "automaton/FSM/FiniteAutomatonToStringComposer.h" +#include "grammar/GrammarToStringComposer.h" +#include "primitive/PrimitiveToStringComposer.h" + +#include "object/ObjectBase.h" + +namespace alib { + +template<typename T> +struct stringApi { + static T parse(std::istream& input); + static void compose(std::ostream& output, const T& data); +}; + +template<> +struct stringApi<alphabet::Symbol> { + static alphabet::Symbol parse(std::istream& input); + static void compose(std::ostream& output, const alphabet::Symbol& data); +}; + + +template<> +struct stringApi<automaton::Automaton> { + static automaton::Automaton parse(std::istream& input); + static void compose(std::ostream& output, const automaton::Automaton& data); +}; + +template<> +struct stringApi<grammar::Grammar> { + static grammar::Grammar parse(std::istream& input); + static void compose(std::ostream& output, const grammar::Grammar& data); +}; + +template<> +struct stringApi<label::Label> { + static label::Label parse(std::istream& input); + static void compose(std::ostream& output, const label::Label& data); +}; + +template<> +struct stringApi<regexp::RegExp> { + static regexp::RegExp parse(std::istream& input); + static void compose(std::ostream& output, const regexp::RegExp& data); +}; + +template<> +struct stringApi<string::String> { + static string::String parse(std::istream& input); + static void compose(std::ostream& output, const string::String& data); +}; + +template<> +struct stringApi<primitive::Primitive> { + static primitive::Primitive parse(std::istream& input); + static void compose(std::ostream& output, const primitive::Primitive& data); +}; + +class FromStringParsers { +public: + static const label::LabelFromStringParser labelParser; + static const alphabet::SymbolFromStringParser symbolParser; + static const regexp::RegExpFromStringParser regexpParser; + static const string::StringFromStringParser stringParser; + static const automaton::FiniteAutomatonFromStringParser automatonParser; + static const grammar::GrammarFromStringParser grammarParser; + static const primitive::PrimitiveFromStringParser primitiveParser; + +}; + +class ToStringComposers { +public: + static const label::LabelToStringComposer labelComposer; + static const alphabet::SymbolToStringComposer symbolComposer; + static const regexp::RegExpToStringComposer regexpComposer; + static const string::StringToStringComposer stringComposer; + static const automaton::FiniteAutomatonToStringComposer automatonComposer; + static const grammar::GrammarToStringComposer grammarComposer; + static const primitive::PrimitiveToStringComposer primitiveComposer; +}; + +} /* namespace alib */ + +#endif /* STRING_API_HPP_ */ diff --git a/alib2data/src/alphabet/SymbolFromStringLexer.cpp b/alib2data/src/alphabet/SymbolFromStringLexer.cpp index 4494bdc9b3..7336722182 100644 --- a/alib2data/src/alphabet/SymbolFromStringLexer.cpp +++ b/alib2data/src/alphabet/SymbolFromStringLexer.cpp @@ -10,66 +10,65 @@ namespace alphabet { -SymbolFromStringLexer::SymbolFromStringLexer(std::istream& in) : m_In(in) { - m_Current.type = TokenType::ERROR; - m_Current.value = ""; -} - -SymbolFromStringLexer& SymbolFromStringLexer::next() { - if(m_Current.type == TokenType::TEOF) return *this; +SymbolFromStringLexer::Token SymbolFromStringLexer::next(std::istream& in) const { + SymbolFromStringLexer::Token token; + token.type = TokenType::ERROR; + token.value = ""; + token.raw = ""; char character; - m_Current.value = ""; L0: - character = m_In.get(); - if(m_In.eof()) { - m_Current.type = TokenType::TEOF; - return *this; + character = in.get(); + if(in.eof()) { + token.type = TokenType::TEOF; + return token; } else if(character == ' ' || character == '\n' || character == '\t') { + token.raw += character; goto L0; } else if(character == '#') { + token.raw += character; goto L1; } else { - m_In.putback(character); - while(!m_Current.value.empty()) { - m_In.putback(m_Current.value.back()); - m_Current.value.pop_back(); - } - m_In.clear(); - m_Current.type = TokenType::ERROR; - return *this; + in.putback(character); + putback(in, std::move(token)); + token.type = TokenType::ERROR; + return token; } L1: - character = m_In.get(); - if(m_In.eof()) { - m_Current.type = TokenType::TEOF; - return *this; + character = in.get(); + if(in.eof()) { + token.type = TokenType::TEOF; + return token; } else if(character == 'B') { - m_Current.type = TokenType::BLANK; - return *this; + token.type = TokenType::BLANK; + token.raw += character; + return token; } else if(character == 'Z') { - m_Current.type = TokenType::BOTTOM; - return *this; + token.type = TokenType::BOTTOM; + token.raw += character; + return token; } else if(character == 'E') { - m_Current.type = TokenType::END; - return *this; + token.type = TokenType::END; + token.raw += character; + return token; } else if(character == 'S') { - m_Current.type = TokenType::START; - return *this; + token.type = TokenType::START; + token.raw += character; + return token; } else { - m_In.putback(character); - while(!m_Current.value.empty()) { - m_In.putback(m_Current.value.back()); - m_Current.value.pop_back(); - } - m_In.clear(); - m_Current.type = TokenType::ERROR; - return *this; + in.putback(character); + putback(in, std::move(token)); + token.type = TokenType::ERROR; + return token; } } -SymbolFromStringLexer::Token SymbolFromStringLexer::token() { - return m_Current; +void SymbolFromStringLexer::putback(std::istream& in, SymbolFromStringLexer::Token token) const { + while(!token.raw.empty()) { + in.putback(token.raw.back()); + token.raw.pop_back(); + } + in.clear(); } } /* namespace alphabet */ diff --git a/alib2data/src/alphabet/SymbolFromStringLexer.h b/alib2data/src/alphabet/SymbolFromStringLexer.h index 0b6adeea1e..49f080924a 100644 --- a/alib2data/src/alphabet/SymbolFromStringLexer.h +++ b/alib2data/src/alphabet/SymbolFromStringLexer.h @@ -25,17 +25,13 @@ public: }; struct Token { - TokenType type; - std::string value; + TokenType type; + std::string value; + std::string raw; }; -private: - std::istream& m_In; - Token m_Current; -public: - SymbolFromStringLexer(std::istream&); - SymbolFromStringLexer& next(); - Token token(); + Token next(std::istream& input) const; + void putback(std::istream&, Token token) const; }; } /* namespace alphabet */ diff --git a/alib2data/src/alphabet/SymbolFromStringParser.cpp b/alib2data/src/alphabet/SymbolFromStringParser.cpp index bbdcb72f6e..4bccee507d 100644 --- a/alib2data/src/alphabet/SymbolFromStringParser.cpp +++ b/alib2data/src/alphabet/SymbolFromStringParser.cpp @@ -13,18 +13,18 @@ #include "StartSymbol.h" #include "LabeledSymbol.h" -namespace alphabet { +#include "../label/Label.h" -SymbolFromStringParser::SymbolFromStringParser(std::istream& input) : m_SymbolLexer(input), m_LabelParser(input) { +#include "../StringApi.hpp" -} +namespace alphabet { -Symbol SymbolFromStringParser::parse() { - return parse(std::set<FEATURES>({FEATURES::LABELED, FEATURES::BLANK, FEATURES::BOTTOM, FEATURES::END, FEATURES::BAR, FEATURES::SUBTREE_WILDCARD, FEATURES::START})); +Symbol SymbolFromStringParser::parseSymbol(std::istream& input) const { + return parseSymbol(input, std::set<FEATURES>({FEATURES::LABELED, FEATURES::BLANK, FEATURES::BOTTOM, FEATURES::END, FEATURES::BAR, FEATURES::SUBTREE_WILDCARD, FEATURES::START})); } -Symbol SymbolFromStringParser::parse(const std::set<FEATURES>& features) { - SymbolFromStringLexer::Token token = m_SymbolLexer.token(); +Symbol SymbolFromStringParser::parseSymbol(std::istream& input, const std::set<FEATURES>& features) const { + SymbolFromStringLexer::Token token = m_SymbolLexer.next(input); switch(token.type) { case SymbolFromStringLexer::TokenType::BLANK: if(!features.count(FEATURES::BLANK)) throw exception::AlibException(); @@ -40,38 +40,12 @@ Symbol SymbolFromStringParser::parse(const std::set<FEATURES>& features) { return Symbol(StartSymbol()); case SymbolFromStringLexer::TokenType::ERROR: if(!features.count(FEATURES::LABELED)) throw exception::AlibException(); - return Symbol(LabeledSymbol(m_LabelParser.parse())); + m_SymbolLexer.putback(input, token); + return Symbol(LabeledSymbol(alib::stringApi<label::Label>::parse(input))); case SymbolFromStringLexer::TokenType::TEOF: throw exception::AlibException("Unexpected end of file"); } throw exception::AlibException(); } -bool SymbolFromStringParser::next() { - SymbolFromStringLexer::Token token = m_SymbolLexer.next().token(); - if(token.type == SymbolFromStringLexer::TokenType::BLANK || token.type == SymbolFromStringLexer::TokenType::BOTTOM || token.type == SymbolFromStringLexer::TokenType::END) { - return true; - } else { - return false; - } -} - -bool SymbolFromStringParser::first() { - SymbolFromStringLexer::Token token = m_SymbolLexer.next().token(); - if(token.type == SymbolFromStringLexer::TokenType::BLANK || token.type == SymbolFromStringLexer::TokenType::BOTTOM || token.type == SymbolFromStringLexer::TokenType::END) { - return true; - } else { - return token.type == SymbolFromStringLexer::TokenType::ERROR && m_LabelParser.first(); - } -} - -bool SymbolFromStringParser::last() { - SymbolFromStringLexer::Token token = m_SymbolLexer.next().token(); - if(token.type == SymbolFromStringLexer::TokenType::TEOF) { - return true; - } else { - return false; - } -} - } /* namespace alphabet */ diff --git a/alib2data/src/alphabet/SymbolFromStringParser.h b/alib2data/src/alphabet/SymbolFromStringParser.h index 111b56c533..32d9c65530 100644 --- a/alib2data/src/alphabet/SymbolFromStringParser.h +++ b/alib2data/src/alphabet/SymbolFromStringParser.h @@ -9,55 +9,25 @@ #define SYMBOL_FROM_STRING_PARSER_H_ #include "Symbol.h" -#include <vector> - #include "SymbolFromStringLexer.h" -#include "../label/LabelFromStringParser.h" #include "SymbolFeatures.h" -#include "../FromStringParser.hpp" - -namespace string { - -class StringFromStringParser; - -} /* namespace alphabet */ - -namespace regexp { - -class RegExpFromStringParser; -} /* namespace regexp */ +namespace alib { -namespace automaton { +template<typename T> +struct stringApi; -class FiniteAutomatonFromStringParser; - -} /* namespace automaton */ - -namespace grammar { - -class GrammarFromStringParser; - -} /* namespace grammar */ +} /* namespace alib */ namespace alphabet { -class SymbolFromStringParser : public alib::FromStringParser<Symbol, FEATURES> { - LabeledSymbol parseContent(); - +class SymbolFromStringParser { SymbolFromStringLexer m_SymbolLexer; - label::LabelFromStringParser m_LabelParser; - virtual Symbol parse(); - virtual Symbol parse(const std::set<FEATURES>& features); - bool next(); - virtual bool last(); -public: - virtual bool first(); - SymbolFromStringParser(std::istream&); - friend class string::StringFromStringParser; - friend class regexp::RegExpFromStringParser; - friend class automaton::FiniteAutomatonFromStringParser; - friend class grammar::GrammarFromStringParser; + + Symbol parseSymbol(std::istream&, const std::set<FEATURES>& features) const; + Symbol parseSymbol(std::istream&) const; + + template<typename T> friend class alib::stringApi; }; } /* namespace alphabet */ diff --git a/alib2data/src/alphabet/SymbolToStringComposer.cpp b/alib2data/src/alphabet/SymbolToStringComposer.cpp index eba1947156..9203f88505 100644 --- a/alib2data/src/alphabet/SymbolToStringComposer.cpp +++ b/alib2data/src/alphabet/SymbolToStringComposer.cpp @@ -6,9 +6,6 @@ */ #include "SymbolToStringComposer.h" -#include "../label/LabelToStringComposer.h" -#include "../primitive/PrimitiveToStringComposer.h" -#include <algorithm> #include "LabeledSymbol.h" #include "RankedSymbol.h" #include "RankedBarSymbol.h" @@ -16,70 +13,68 @@ #include "SymbolSetSymbol.h" #include "UniqueSymbol.h" +#include "../StringApi.hpp" + namespace alphabet { -void SymbolToStringComposer::Visit(void* userData, const LabeledSymbol& symbol) { - std::stringstream &out = *((std::stringstream*) userData); +void SymbolToStringComposer::Visit(void* userData, const LabeledSymbol& symbol) const { + std::ostream &out = *((std::ostream*) userData); - label::LabelToStringComposer composer; - out << composer.compose(symbol.getLabel()); + alib::stringApi<label::Label>::compose(out, symbol.getLabel()); } -void SymbolToStringComposer::Visit(void* userData, const BlankSymbol&) { - std::stringstream &out = *((std::stringstream*) userData); +void SymbolToStringComposer::Visit(void* userData, const BlankSymbol&) const { + std::ostream &out = *((std::ostream*) userData); out << "#B"; } -void SymbolToStringComposer::Visit(void* userData, const BottomOfTheStackSymbol&) { - std::stringstream &out = *((std::stringstream*) userData); +void SymbolToStringComposer::Visit(void* userData, const BottomOfTheStackSymbol&) const { + std::ostream &out = *((std::ostream*) userData); out << "#T"; } -void SymbolToStringComposer::Visit(void* userData, const EndSymbol&) { - std::stringstream &out = *((std::stringstream*) userData); +void SymbolToStringComposer::Visit(void* userData, const EndSymbol&) const { + std::ostream &out = *((std::ostream*) userData); out << "#$"; } -void SymbolToStringComposer::Visit(void* userData, const StartSymbol&) { - std::stringstream &out = *((std::stringstream*) userData); +void SymbolToStringComposer::Visit(void* userData, const StartSymbol&) const { + std::ostream &out = *((std::ostream*) userData); out << "#S"; } -void SymbolToStringComposer::Visit(void* userData, const RankedSymbol& symbol) { - std::stringstream &out = *((std::stringstream*) userData); +void SymbolToStringComposer::Visit(void* userData, const RankedSymbol& symbol) const { + std::ostream &out = *((std::ostream*) userData); - label::LabelToStringComposer composer1; - out << composer1.compose(symbol.getLabel()); - primitive::PrimitiveToStringComposer composer2; - out << composer2.compose(primitive::Primitive(symbol.getRank())); + alib::stringApi<label::Label>::compose(out, symbol.getLabel()); + alib::stringApi<primitive::Primitive>::compose(out, primitive::Primitive(symbol.getRank())); } -void SymbolToStringComposer::Visit(void* userData, const BarSymbol&) { - std::stringstream &out = *((std::stringstream*) userData); +void SymbolToStringComposer::Visit(void* userData, const BarSymbol&) const { + std::ostream &out = *((std::ostream*) userData); out << "#|"; } -void SymbolToStringComposer::Visit(void* userData, const RankedBarSymbol& symbol) { - std::stringstream &out = *((std::stringstream*) userData); +void SymbolToStringComposer::Visit(void* userData, const RankedBarSymbol& symbol) const { + std::ostream &out = *((std::ostream*) userData); out << "#|"; - primitive::PrimitiveToStringComposer composer2; - out << composer2.compose(primitive::Primitive(symbol.getRank())); + alib::stringApi<primitive::Primitive>::compose(out, primitive::Primitive(symbol.getRank())); } -void SymbolToStringComposer::Visit(void* userData, const SubtreeWildcardSymbol&) { - std::stringstream &out = *((std::stringstream*) userData); +void SymbolToStringComposer::Visit(void* userData, const SubtreeWildcardSymbol&) const { + std::ostream &out = *((std::ostream*) userData); out << "#S"; } -void SymbolToStringComposer::Visit(void* userData, const SymbolSetSymbol& symbol) { - std::stringstream &out = *((std::stringstream*) userData); +void SymbolToStringComposer::Visit(void* userData, const SymbolSetSymbol& symbol) const { + std::ostream &out = *((std::ostream*) userData); out << '['; bool first = true; @@ -93,8 +88,8 @@ void SymbolToStringComposer::Visit(void* userData, const SymbolSetSymbol& symbol out << ']'; } -void SymbolToStringComposer::Visit(void* userData, const SymbolPairSymbol& symbol) { - std::stringstream &out = *((std::stringstream*) userData); +void SymbolToStringComposer::Visit(void* userData, const SymbolPairSymbol& symbol) const { + std::ostream &out = *((std::ostream*) userData); out << '<'; symbol.getData().first.getData().Accept(userData, *this); @@ -103,21 +98,18 @@ void SymbolToStringComposer::Visit(void* userData, const SymbolPairSymbol& symbo out << '>'; } -void SymbolToStringComposer::Visit(void* userData, const UniqueSymbol& symbol) { - std::stringstream &out = *((std::stringstream*) userData); +void SymbolToStringComposer::Visit(void* userData, const UniqueSymbol& symbol) const { + std::ostream &out = *((std::ostream*) userData); out << '<'; symbol.getSymbol().getData().Accept(userData, *this); out << ", "; - primitive::PrimitiveToStringComposer composer; - symbol.getId().Accept(userData, composer); + alib::stringApi<primitive::Primitive>::compose(out, primitive::Primitive(symbol.getId())); out << '>'; } -std::string SymbolToStringComposer::compose(const Symbol& symbol) { - std::stringstream out; +void SymbolToStringComposer::compose(std::ostream& out, const Symbol& symbol) const { symbol.getData().Accept((void*) &out, *this); - return std::move(out).str(); } } /* namespace alphabet */ diff --git a/alib2data/src/alphabet/SymbolToStringComposer.h b/alib2data/src/alphabet/SymbolToStringComposer.h index 549e6137f0..d4e652f6cf 100644 --- a/alib2data/src/alphabet/SymbolToStringComposer.h +++ b/alib2data/src/alphabet/SymbolToStringComposer.h @@ -8,29 +8,27 @@ #ifndef SYMBOL_TO_STRING_COMPOSER_H_ #define SYMBOL_TO_STRING_COMPOSER_H_ -#include <sstream> +#include <ostream> #include "Symbol.h" -#include "../sax/Token.h" -#include "../label/Label.h" namespace alphabet { /** * This class contains methods to print XML representation of string to the output stream. */ -class SymbolToStringComposer : public VisitableSymbolBase::visitor_type { - void Visit(void*, const LabeledSymbol& symbol); - void Visit(void*, const BlankSymbol& symbol); - void Visit(void*, const BottomOfTheStackSymbol& symbol); - void Visit(void*, const EndSymbol& symbol); - void Visit(void*, const StartSymbol& symbol); - void Visit(void*, const RankedSymbol& symbol); - void Visit(void*, const BarSymbol& symbol); - void Visit(void*, const RankedBarSymbol& symbol); - void Visit(void*, const SubtreeWildcardSymbol& symbol); - void Visit(void*, const SymbolPairSymbol& symbol); - void Visit(void*, const SymbolSetSymbol& symbol); - void Visit(void*, const UniqueSymbol& symbol); +class SymbolToStringComposer : public VisitableSymbolBase::const_visitor_type { + void Visit(void*, const LabeledSymbol& symbol) const; + void Visit(void*, const BlankSymbol& symbol) const; + void Visit(void*, const BottomOfTheStackSymbol& symbol) const; + void Visit(void*, const EndSymbol& symbol) const; + void Visit(void*, const StartSymbol& symbol) const; + void Visit(void*, const RankedSymbol& symbol) const; + void Visit(void*, const BarSymbol& symbol) const; + void Visit(void*, const RankedBarSymbol& symbol) const; + void Visit(void*, const SubtreeWildcardSymbol& symbol) const; + void Visit(void*, const SymbolPairSymbol& symbol) const; + void Visit(void*, const SymbolSetSymbol& symbol) const; + void Visit(void*, const UniqueSymbol& symbol) const; public: /** @@ -38,7 +36,7 @@ public: * @param string String to print * @param out output stream to which print the String */ - std::string compose(const Symbol& string); + void compose(std::ostream& output, const Symbol& string) const; }; } /* namespace alphabet */ diff --git a/alib2data/src/automaton/FSM/FiniteAutomatonFromStringLexer.cpp b/alib2data/src/automaton/FSM/FiniteAutomatonFromStringLexer.cpp index dd0cecd7f8..b0d149c410 100644 --- a/alib2data/src/automaton/FSM/FiniteAutomatonFromStringLexer.cpp +++ b/alib2data/src/automaton/FSM/FiniteAutomatonFromStringLexer.cpp @@ -6,99 +6,104 @@ */ #include "FiniteAutomatonFromStringLexer.h" +#include "../../std/istream.h" namespace automaton { -FiniteAutomatonFromStringLexer::FiniteAutomatonFromStringLexer(std::istream& in) : m_In(in) { - m_Current.type = TokenType::ERROR; - m_Current.value = ""; -} - -FiniteAutomatonFromStringLexer& FiniteAutomatonFromStringLexer::next() { - if(m_Current.type == TokenType::TEOF) return *this; +FiniteAutomatonFromStringLexer::Token FiniteAutomatonFromStringLexer::next(std::istream& in) const { + FiniteAutomatonFromStringLexer::Token token; + token.type = TokenType::ERROR; + token.value = ""; + token.raw = ""; char character; - m_Current.value = ""; L0: - character = m_In.get(); - if(m_In.eof()) { - m_Current.type = TokenType::TEOF; - return *this; + character = in.get(); + if(in.eof()) { + token.type = TokenType::TEOF; + return token; } else if(character == ' ' || character == '\t') { + token.raw += character; goto L0; } else if(character == '\n') { - m_Current.type = TokenType::NEW_LINE; - m_Current.value += character; - return *this; + token.type = TokenType::NEW_LINE; + token.value += character; + token.raw += character; + return token; } else if(character == '<') { - m_Current.type = TokenType::OUT; - m_Current.value += character; - return *this; + token.type = TokenType::OUT; + token.value += character; + token.raw += character; + return token; } else if(character == '>') { - m_Current.type = TokenType::IN; - m_Current.value += character; - return *this; + token.type = TokenType::IN; + token.value += character; + token.raw += character; + return token; } else if(character == '|') { - m_Current.type = TokenType::SEPARATOR; - m_Current.value += character; - return *this; + token.type = TokenType::SEPARATOR; + token.value += character; + token.raw += character; + return token; } else if(character == '-') { - m_Current.type = TokenType::NONE; - m_Current.value += character; - return *this; + token.type = TokenType::NONE; + token.value += character; + token.raw += character; + return token; } else if(character == '#') { - m_Current.value += character; + token.value += character; + token.raw += character; goto L1; - } else if(m_In.unget(), m_In >> "MISNFA") { - m_Current.type = TokenType::MULTI_INITIAL_STATE_NFA; - m_Current.value = "MISNFA"; - return *this; - } else if(m_In.clear(), m_In >> "ENFA") { - m_Current.type = TokenType::EPSILON_NFA; - m_Current.value = "ENFA"; - return *this; - } else if(m_In.clear(), m_In >> "NFA") { - m_Current.type = TokenType::NFA; - m_Current.value = "NFA"; - return *this; - } else if(m_In.clear(), m_In >> "DFA") { - m_Current.type = TokenType::DFA; - m_Current.value = "DFA"; - return *this; + } else if(in.unget(), in >> "MISNFA") { + token.type = TokenType::MULTI_INITIAL_STATE_NFA; + token.value = "MISNFA"; + token.raw = "MISNFA"; + return token; + } else if(in.clear(), in >> "ENFA") { + token.type = TokenType::EPSILON_NFA; + token.value = "ENFA"; + token.raw = "ENFA"; + return token; + } else if(in.clear(), in >> "NFA") { + token.type = TokenType::NFA; + token.value = "NFA"; + token.raw = "NFA"; + return token; + } else if(in.clear(), in >> "DFA") { + token.type = TokenType::DFA; + token.value = "DFA"; + token.raw = "DFA"; + return token; } else { - m_In.putback(character); - while(!m_Current.value.empty()) { - m_In.putback(m_Current.value.back()); - m_In.clear(); - m_Current.value.pop_back(); - } - m_In.clear(); - m_Current.type = TokenType::ERROR; - return *this; + in.putback(character); + putback(in, std::move(token)); + token.type = TokenType::ERROR; + return token; } L1: - character = m_In.get(); - if(m_In.eof()) { - m_Current.type = TokenType::TEOF; - return *this; + character = in.get(); + if(in.eof()) { + token.type = TokenType::TEOF; + return token; } else if(character == 'E') { - m_Current.value += character; - m_Current.type = TokenType::EPSILON; - return *this; + token.type = TokenType::EPSILON; + token.value += character; + token.raw += character; + return token; } else { - m_In.putback(character); - while(!m_Current.value.empty()) { - m_In.putback(m_Current.value.back()); - m_Current.value.pop_back(); - } - m_In.clear(); - m_Current.type = TokenType::ERROR; - return *this; + in.putback(character); + putback(in, std::move(token)); + token.type = TokenType::ERROR; + return token; } } -FiniteAutomatonFromStringLexer::Token FiniteAutomatonFromStringLexer::token() { - return m_Current; +void FiniteAutomatonFromStringLexer::putback(std::istream& in, FiniteAutomatonFromStringLexer::Token token) const { + while(!token.raw.empty()) { + in.putback(token.raw.back()); + token.raw.pop_back(); + } + in.clear(); } } /* namespace automaton */ diff --git a/alib2data/src/automaton/FSM/FiniteAutomatonFromStringLexer.h b/alib2data/src/automaton/FSM/FiniteAutomatonFromStringLexer.h index 514a67ed4a..e171295f88 100644 --- a/alib2data/src/automaton/FSM/FiniteAutomatonFromStringLexer.h +++ b/alib2data/src/automaton/FSM/FiniteAutomatonFromStringLexer.h @@ -10,7 +10,6 @@ #include <string> #include <sstream> -#include "../../std/istream.h" namespace automaton { @@ -34,15 +33,11 @@ public: struct Token { TokenType type; std::string value; + std::string raw; }; -private: - std::istream& m_In; - Token m_Current; -public: - FiniteAutomatonFromStringLexer(std::istream&); - FiniteAutomatonFromStringLexer& next(); - Token token(); + Token next(std::istream& input) const; + void putback(std::istream&, Token token) const; }; } /* namepsace automaton */ diff --git a/alib2data/src/automaton/FSM/FiniteAutomatonFromStringParser.cpp b/alib2data/src/automaton/FSM/FiniteAutomatonFromStringParser.cpp index 732f3c600c..b665c74fc2 100644 --- a/alib2data/src/automaton/FSM/FiniteAutomatonFromStringParser.cpp +++ b/alib2data/src/automaton/FSM/FiniteAutomatonFromStringParser.cpp @@ -14,74 +14,49 @@ #include "NFA.h" #include "DFA.h" -namespace automaton { - -FiniteAutomatonFromStringParser::FiniteAutomatonFromStringParser(std::istream& input) : m_FiniteAutomatonLexer(input), m_SymbolParser(input), m_LabelParser(input) { +#include "../../StringApi.hpp" -} +namespace automaton { -Automaton FiniteAutomatonFromStringParser::parse() { - return parse(std::set<FEATURES>({FEATURES::EPSILON_NFA, FEATURES::MULTI_INITIAL_STATE_NFA, FEATURES::NFA, FEATURES::DFA})); +Automaton FiniteAutomatonFromStringParser::parseAutomaton(std::istream& input) const { + return parseAutomaton(input, std::set<FEATURES>({FEATURES::EPSILON_NFA, FEATURES::MULTI_INITIAL_STATE_NFA, FEATURES::NFA, FEATURES::DFA})); } -Automaton FiniteAutomatonFromStringParser::parse(const std::set<FEATURES>& features) { - FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.token(); +Automaton FiniteAutomatonFromStringParser::parseAutomaton(std::istream& input, const std::set<FEATURES>& features) const { + FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.next(input); if(token.type == FiniteAutomatonFromStringLexer::TokenType::EPSILON_NFA) { if(!features.count(FEATURES::EPSILON_NFA)) throw exception::AlibException("Disabled formalism EpsilonNFA"); - return Automaton(parseEpsilonNFA()); + m_FiniteAutomatonLexer.putback(input, token); + return Automaton(parseEpsilonNFA(input)); } else if(token.type == FiniteAutomatonFromStringLexer::TokenType::MULTI_INITIAL_STATE_NFA) { if(!features.count(FEATURES::MULTI_INITIAL_STATE_NFA)) throw exception::AlibException("Disabled Formalism MultiInitialStateNFA"); - return Automaton(parseMultiInitialStateNFA()); + m_FiniteAutomatonLexer.putback(input, token); + return Automaton(parseMultiInitialStateNFA(input)); } else if(token.type == FiniteAutomatonFromStringLexer::TokenType::NFA) { if(!features.count(FEATURES::NFA)) throw exception::AlibException("Disabled formalism NFA"); - return Automaton(parseNFA()); + m_FiniteAutomatonLexer.putback(input, token); + return Automaton(parseNFA(input)); } else if(token.type == FiniteAutomatonFromStringLexer::TokenType::DFA) { if(!features.count(FEATURES::DFA)) throw exception::AlibException("Disabled formalism DFA"); - return Automaton(parseDFA()); + m_FiniteAutomatonLexer.putback(input, token); + return Automaton(parseDFA(input)); } else { throw exception::AlibException("Formalism not recognised (token = \"" + token.value + "\")"); } } -bool FiniteAutomatonFromStringParser::first() { - FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.next().token(); - if(token.type == FiniteAutomatonFromStringLexer::TokenType::EPSILON_NFA || token.type == FiniteAutomatonFromStringLexer::TokenType::NFA || token.type == FiniteAutomatonFromStringLexer::TokenType::DFA) { - return true; - } else { - return false; - } -} - -bool FiniteAutomatonFromStringParser::next() { - FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.next().token(); - if(token.type == FiniteAutomatonFromStringLexer::TokenType::EPSILON_NFA || token.type == FiniteAutomatonFromStringLexer::TokenType::NFA || token.type == FiniteAutomatonFromStringLexer::TokenType::DFA || token.type == FiniteAutomatonFromStringLexer::TokenType::OUT || token.type == FiniteAutomatonFromStringLexer::TokenType::IN || token.type == FiniteAutomatonFromStringLexer::TokenType::EPSILON || token.type == FiniteAutomatonFromStringLexer::TokenType::SEPARATOR || token.type == FiniteAutomatonFromStringLexer::TokenType::NONE || token.type == FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { - return true; - } else { - return false; - } -} - -bool FiniteAutomatonFromStringParser::last() { - FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.next().token(); - if(token.type == FiniteAutomatonFromStringLexer::TokenType::TEOF) { - return true; - } else { - return false; - } -} - -EpsilonNFA FiniteAutomatonFromStringParser::parseEpsilonNFA() { - FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.token(); +EpsilonNFA FiniteAutomatonFromStringParser::parseEpsilonNFA(std::istream& input) const { + FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.next(input); if(token.type != FiniteAutomatonFromStringLexer::TokenType::EPSILON_NFA) { throw exception::AlibException("Unrecognised ENFA token."); } std::vector<std::variant<string::Epsilon, alphabet::Symbol> > symbols; - next() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); while(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { if(token.type == FiniteAutomatonFromStringLexer::TokenType::ERROR) { - alphabet::Symbol symbol = m_SymbolParser.parse(); + m_FiniteAutomatonLexer.putback(input, token); + alphabet::Symbol symbol = alib::stringApi<alphabet::Symbol>::parse(input); std::variant<string::Epsilon, alphabet::Symbol> symbolVariant(symbol); symbols.push_back(symbolVariant); @@ -89,29 +64,26 @@ EpsilonNFA FiniteAutomatonFromStringParser::parseEpsilonNFA() { symbols.push_back(std::variant<string::Epsilon, alphabet::Symbol>(string::Epsilon::EPSILON)); } - next() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); } - token = m_FiniteAutomatonLexer.token(); - if(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) throw exception::AlibException("Expected newline."); - State* initialState = NULL; std::set<State> finalStates; std::set<State> states; std::set<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, State>> transitionFunction; - - next() || m_LabelParser.first(); - parseEpsilonNFATransition(states, symbols, initialState, finalStates, transitionFunction); - token = m_FiniteAutomatonLexer.token(); - while(token.type == FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { - next() || m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); - if(token.type == FiniteAutomatonFromStringLexer::TokenType::TEOF) break; + parseEpsilonNFATransition(input, states, symbols, initialState, finalStates, transitionFunction); + token = m_FiniteAutomatonLexer.next(input); - parseEpsilonNFATransition(states, symbols, initialState, finalStates, transitionFunction); - token = m_FiniteAutomatonLexer.token(); + while(token.type == FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { + token = m_FiniteAutomatonLexer.next(input); + if(token.type == FiniteAutomatonFromStringLexer::TokenType::TEOF) + break; + else + m_FiniteAutomatonLexer.putback(input, token); + + parseEpsilonNFATransition(input, states, symbols, initialState, finalStates, transitionFunction); + token = m_FiniteAutomatonLexer.next(input); } if(initialState == NULL) throw exception::AlibException("No initial state recognised."); @@ -132,82 +104,75 @@ EpsilonNFA FiniteAutomatonFromStringParser::parseEpsilonNFA() { return res; } -MultiInitialStateNFA FiniteAutomatonFromStringParser::parseMultiInitialStateNFA() { +MultiInitialStateNFA FiniteAutomatonFromStringParser::parseMultiInitialStateNFA(std::istream& input) const { MultiInitialStateNFA res; - FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.token(); + FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.next(input); if(token.type != FiniteAutomatonFromStringLexer::TokenType::MULTI_INITIAL_STATE_NFA) { throw exception::AlibException("Unrecognised MISNFA token."); } std::vector<alphabet::Symbol> symbols; - next() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); while(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { - alphabet::Symbol symbol = m_SymbolParser.parse(); + m_FiniteAutomatonLexer.putback(input, token); + alphabet::Symbol symbol = alib::stringApi<alphabet::Symbol>::parse(input); res.addInputSymbol(symbol); symbols.push_back(symbol); - next() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); } - token = m_FiniteAutomatonLexer.token(); - if(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) throw exception::AlibException("Expected newline."); - - next() || m_LabelParser.first(); - parseMultiInitialStateNFATransition(res, symbols); - token = m_FiniteAutomatonLexer.token(); + parseMultiInitialStateNFATransition(input, res, symbols); + token = m_FiniteAutomatonLexer.next(input); while(token.type == FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { - next() || m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); - if(token.type == FiniteAutomatonFromStringLexer::TokenType::TEOF) break; - - parseMultiInitialStateNFATransition(res, symbols); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); + if(token.type == FiniteAutomatonFromStringLexer::TokenType::TEOF) + break; + else + m_FiniteAutomatonLexer.putback(input, token); + + parseMultiInitialStateNFATransition(input, res, symbols); + token = m_FiniteAutomatonLexer.next(input); } return res; } -NFA FiniteAutomatonFromStringParser::parseNFA() { - - FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.token(); +NFA FiniteAutomatonFromStringParser::parseNFA(std::istream& input) const { + FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.next(input); if(token.type != FiniteAutomatonFromStringLexer::TokenType::NFA) { throw exception::AlibException("Unrecognised NFA token."); } std::vector<alphabet::Symbol> symbols; - next() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); while(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { - alphabet::Symbol symbol = m_SymbolParser.parse(); + m_FiniteAutomatonLexer.putback(input, token); + alphabet::Symbol symbol = alib::stringApi<alphabet::Symbol>::parse(input); symbols.push_back(symbol); - next() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); } - token = m_FiniteAutomatonLexer.token(); - if(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) throw exception::AlibException("Expected newline."); - State* initialState = NULL; std::set<State> finalStates; std::set<State> states; std::set<std::tuple<State, alphabet::Symbol, State>> transitionFunction; - - next() || m_LabelParser.first(); - parseNFATransition(states, symbols, initialState, finalStates, transitionFunction); - token = m_FiniteAutomatonLexer.token(); - while(token.type == FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { - next() || m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); - if(token.type == FiniteAutomatonFromStringLexer::TokenType::TEOF) break; + parseNFATransition(input, states, symbols, initialState, finalStates, transitionFunction); + token = m_FiniteAutomatonLexer.next(input); - parseNFATransition(states, symbols, initialState, finalStates, transitionFunction); - token = m_FiniteAutomatonLexer.token(); + while(token.type == FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { + token = m_FiniteAutomatonLexer.next(input); + if(token.type == FiniteAutomatonFromStringLexer::TokenType::TEOF) + break; + else + m_FiniteAutomatonLexer.putback(input, token); + + parseNFATransition(input, states, symbols, initialState, finalStates, transitionFunction); + token = m_FiniteAutomatonLexer.next(input); } if(initialState == NULL) throw exception::AlibException("No initial state recognised."); @@ -225,43 +190,39 @@ NFA FiniteAutomatonFromStringParser::parseNFA() { return res; } -DFA FiniteAutomatonFromStringParser::parseDFA() { - - FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.token(); +DFA FiniteAutomatonFromStringParser::parseDFA(std::istream& input) const { + FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.next(input); if(token.type != FiniteAutomatonFromStringLexer::TokenType::DFA) { throw exception::AlibException("Unrecognised DFA token."); } std::vector<alphabet::Symbol> symbols; - next() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); while(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { - alphabet::Symbol symbol = m_SymbolParser.parse(); + m_FiniteAutomatonLexer.putback(input, token); + alphabet::Symbol symbol = alib::stringApi<alphabet::Symbol>::parse(input); symbols.push_back(symbol); - next() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); } - token = m_FiniteAutomatonLexer.token(); - if(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) throw exception::AlibException("Expected newline."); - State* initialState = NULL; std::set<State> finalStates; std::set<State> states; std::set<std::tuple<State, alphabet::Symbol, State>> transitionFunction; - - next() || m_LabelParser.first(); - parseDFATransition(states, symbols, initialState, finalStates, transitionFunction); - token = m_FiniteAutomatonLexer.token(); - while(token.type == FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { - next() || m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); - if(token.type == FiniteAutomatonFromStringLexer::TokenType::TEOF) break; + parseDFATransition(input, states, symbols, initialState, finalStates, transitionFunction); + token = m_FiniteAutomatonLexer.next(input); - parseDFATransition(states, symbols, initialState, finalStates, transitionFunction); - token = m_FiniteAutomatonLexer.token(); + while(token.type == FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { + token = m_FiniteAutomatonLexer.next(input); + if(token.type == FiniteAutomatonFromStringLexer::TokenType::TEOF) + break; + else + m_FiniteAutomatonLexer.putback(input, token); + + parseDFATransition(input, states, symbols, initialState, finalStates, transitionFunction); + token = m_FiniteAutomatonLexer.next(input); } if(initialState == NULL) throw exception::AlibException("No initial state recognised."); @@ -278,41 +239,43 @@ DFA FiniteAutomatonFromStringParser::parseDFA() { return res; } - -void FiniteAutomatonFromStringParser::initialFinalState(bool& initial, bool& final) { + +void FiniteAutomatonFromStringParser::initialFinalState(std::istream& input, bool& initial, bool& final) const { initial = false; final = false; - FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.token(); + FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.next(input); if(token.type == FiniteAutomatonFromStringLexer::TokenType::IN) { initial = true; - next() || m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); if(token.type == FiniteAutomatonFromStringLexer::TokenType::OUT) { final = true; - next() || m_LabelParser.first(); + } else { + m_FiniteAutomatonLexer.putback(input, token); } } else if(token.type == FiniteAutomatonFromStringLexer::TokenType::OUT) { final = true; - next() || m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); if(token.type == FiniteAutomatonFromStringLexer::TokenType::IN) { initial = true; - next() || m_LabelParser.first(); + } else { + m_FiniteAutomatonLexer.putback(input, token); } + } else { + m_FiniteAutomatonLexer.putback(input, token); } } -void FiniteAutomatonFromStringParser::parseEpsilonNFATransition(std::set<State>& states, const std::vector<std::variant<string::Epsilon, alphabet::Symbol>>& symbols, State*& initialState, std::set<State>& finalStates, std::set<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, State>>& transitionFunction) { +void FiniteAutomatonFromStringParser::parseEpsilonNFATransition(std::istream& input, std::set<State>& states, const std::vector<std::variant<string::Epsilon, alphabet::Symbol>>& symbols, State*& initialState, std::set<State>& finalStates, std::set<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, State>>& transitionFunction) const { bool initial = false; bool final = false; - initialFinalState(initial, final); + initialFinalState(input, initial, final); - State from(m_LabelParser.parse()); + State from(alib::stringApi<label::Label>::parse(input)); states.insert(from); if(initial) { if(initialState != NULL) throw exception::AlibException("Multiple initial states are not avaiable for NFA type"); @@ -320,84 +283,76 @@ void FiniteAutomatonFromStringParser::parseEpsilonNFATransition(std::set<State>& } if(final) finalStates.insert(from); - next() || m_LabelParser.first(); - - FiniteAutomatonFromStringLexer::Token token; + FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.next(input); std::vector<std::variant<string::Epsilon, alphabet::Symbol>>::const_iterator iter = symbols.begin(); - do { + + while(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { if(iter == symbols.end()) throw exception::AlibException("Invalid line format"); - token = m_FiniteAutomatonLexer.token(); if(token.type != FiniteAutomatonFromStringLexer::TokenType::NONE) { - + m_FiniteAutomatonLexer.putback(input, token); do { - State to(m_LabelParser.parse()); + State to(alib::stringApi<label::Label>::parse(input)); states.insert(to); transitionFunction.insert(std::make_tuple(from, *iter, to)); - next() || m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); if(token.type != FiniteAutomatonFromStringLexer::TokenType::SEPARATOR) break; - - next() || m_LabelParser.first(); } while(true); } else { - next() || m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); } iter++; - } while(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE); + } + m_FiniteAutomatonLexer.putback(input, token); + if(iter != symbols.end()) throw exception::AlibException("Invalid line format"); } -void FiniteAutomatonFromStringParser::parseMultiInitialStateNFATransition(MultiInitialStateNFA& res, const std::vector<alphabet::Symbol>& symbols) { +void FiniteAutomatonFromStringParser::parseMultiInitialStateNFATransition(std::istream& input, MultiInitialStateNFA& res, const std::vector<alphabet::Symbol>& symbols) const { bool initial = false; bool final = false; - initialFinalState(initial, final); + initialFinalState(input, initial, final); - State from(m_LabelParser.parse()); + State from(alib::stringApi<label::Label>::parse(input)); res.addState(from); if(initial) res.addInitialState(from); if(final) res.addFinalState(from); - next() || m_LabelParser.first(); - - FiniteAutomatonFromStringLexer::Token token; + FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.next(input); std::vector<alphabet::Symbol>::const_iterator iter = symbols.begin(); - do { + + while(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { if(iter == symbols.end()) throw exception::AlibException("Invalid line format"); - token = m_FiniteAutomatonLexer.token(); if(token.type != FiniteAutomatonFromStringLexer::TokenType::NONE) { - + m_FiniteAutomatonLexer.putback(input, token); do { - State to(m_LabelParser.parse()); + State to(alib::stringApi<label::Label>::parse(input)); res.addState(to); res.addTransition(from, *iter, to); - next() || m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); if(token.type != FiniteAutomatonFromStringLexer::TokenType::SEPARATOR) break; - - next() || m_LabelParser.first(); } while(true); } else { - next() || m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); } iter++; - } while(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE); + } + m_FiniteAutomatonLexer.putback(input, token); + if(iter != symbols.end()) throw exception::AlibException("Invalid line format"); } -void FiniteAutomatonFromStringParser::parseNFATransition(std::set<State>& states, const std::vector<alphabet::Symbol>& symbols, State*& initialState, std::set<State>& finalStates, std::set<std::tuple<State, alphabet::Symbol, State>>& transitionFunction) { +void FiniteAutomatonFromStringParser::parseNFATransition(std::istream& input, std::set<State>& states, const std::vector<alphabet::Symbol>& symbols, State*& initialState, std::set<State>& finalStates, std::set<std::tuple<State, alphabet::Symbol, State>>& transitionFunction) const { bool initial = false; bool final = false; - initialFinalState(initial, final); + initialFinalState(input, initial, final); - State from(m_LabelParser.parse()); + State from(alib::stringApi<label::Label>::parse(input)); states.insert(from); if(initial) { if(initialState != NULL) throw exception::AlibException("Multiple initial states are not avaiable for NFA type"); @@ -405,43 +360,39 @@ void FiniteAutomatonFromStringParser::parseNFATransition(std::set<State>& states } if(final) finalStates.insert(from); - next() || m_LabelParser.first(); - - FiniteAutomatonFromStringLexer::Token token; + FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.next(input); std::vector<alphabet::Symbol>::const_iterator iter = symbols.begin(); - do { + + while(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { if(iter == symbols.end()) throw exception::AlibException("Invalid line format"); - token = m_FiniteAutomatonLexer.token(); if(token.type != FiniteAutomatonFromStringLexer::TokenType::NONE) { - + m_FiniteAutomatonLexer.putback(input, token); do { - State to(m_LabelParser.parse()); + State to(alib::stringApi<label::Label>::parse(input)); states.insert(to); transitionFunction.insert(std::make_tuple(from, *iter, to)); - next() || m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); if(token.type != FiniteAutomatonFromStringLexer::TokenType::SEPARATOR) break; - - next() || m_LabelParser.first(); } while(true); } else { - next() || m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); } iter++; - } while(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE); + } + m_FiniteAutomatonLexer.putback(input, token); + if(iter != symbols.end()) throw exception::AlibException("Invalid line format"); } -void FiniteAutomatonFromStringParser::parseDFATransition(std::set<State>& states, const std::vector<alphabet::Symbol>& symbols, State*& initialState, std::set<State>& finalStates, std::set<std::tuple<State, alphabet::Symbol, State>>& transitionFunction) { +void FiniteAutomatonFromStringParser::parseDFATransition(std::istream& input, std::set<State>& states, const std::vector<alphabet::Symbol>& symbols, State*& initialState, std::set<State>& finalStates, std::set<std::tuple<State, alphabet::Symbol, State>>& transitionFunction) const { bool initial = false; bool final = false; - initialFinalState(initial, final); + initialFinalState(input, initial, final); - State from(m_LabelParser.parse()); + State from(alib::stringApi<label::Label>::parse(input)); states.insert(from); if(initial) { if(initialState != NULL) throw exception::AlibException("Multiple initial states are not avaiable for NFA type"); @@ -449,33 +400,26 @@ void FiniteAutomatonFromStringParser::parseDFATransition(std::set<State>& states } if(final) finalStates.insert(from); - next() || m_LabelParser.first(); - - FiniteAutomatonFromStringLexer::Token token; + FiniteAutomatonFromStringLexer::Token token = m_FiniteAutomatonLexer.next(input); std::vector<alphabet::Symbol>::const_iterator iter = symbols.begin(); - do { + + while(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE) { if(iter == symbols.end()) throw exception::AlibException("Invalid line format"); - token = m_FiniteAutomatonLexer.token(); if(token.type != FiniteAutomatonFromStringLexer::TokenType::NONE) { - - do { - State to(m_LabelParser.parse()); - states.insert(to); - transitionFunction.insert(std::make_tuple(from, *iter, to)); - - next() || m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); - if(token.type != FiniteAutomatonFromStringLexer::TokenType::SEPARATOR) break; + m_FiniteAutomatonLexer.putback(input, token); + State to(alib::stringApi<label::Label>::parse(input)); + states.insert(to); + transitionFunction.insert(std::make_tuple(from, *iter, to)); - next() || m_LabelParser.first(); - } while(true); + token = m_FiniteAutomatonLexer.next(input); } else { - next() || m_LabelParser.first(); - token = m_FiniteAutomatonLexer.token(); + token = m_FiniteAutomatonLexer.next(input); } iter++; - } while(token.type != FiniteAutomatonFromStringLexer::TokenType::NEW_LINE); + } + m_FiniteAutomatonLexer.putback(input, token); + if(iter != symbols.end()) throw exception::AlibException("Invalid line format"); } diff --git a/alib2data/src/automaton/FSM/FiniteAutomatonFromStringParser.h b/alib2data/src/automaton/FSM/FiniteAutomatonFromStringParser.h index 3ee0445bc9..c2b1ae1735 100644 --- a/alib2data/src/automaton/FSM/FiniteAutomatonFromStringParser.h +++ b/alib2data/src/automaton/FSM/FiniteAutomatonFromStringParser.h @@ -9,48 +9,43 @@ #define FINITE_AUTOMATON_FROM_STRING_PARSER_H_ #include "FiniteAutomatonFromStringLexer.h" -#include "../../alphabet/SymbolFromStringParser.h" -#include "../../label/LabelFromStringParser.h" -#include "../../FromStringParser.hpp" - -#include <tuple> #include "../Automaton.h" #include "../AutomatonFeatures.h" - #include "../common/State.h" +#include <tuple> #include "../../std/variant.hpp" - #include "../../string/Epsilon.h" +namespace alib { + +template<typename T> +struct stringApi; + +} /* namespace alib */ + namespace automaton { -class FiniteAutomatonFromStringParser : public alib::FromStringParser<Automaton, FEATURES> { +class FiniteAutomatonFromStringParser { FiniteAutomatonFromStringLexer m_FiniteAutomatonLexer; - alphabet::SymbolFromStringParser m_SymbolParser; - label::LabelFromStringParser m_LabelParser; - void initialFinalState(bool& initial, bool& final); + void initialFinalState(std::istream& input, bool& initial, bool& final) const; - EpsilonNFA parseEpsilonNFA(); - NFA parseNFA(); - MultiInitialStateNFA parseMultiInitialStateNFA(); - DFA parseDFA(); - void parseEpsilonNFATransition(std::set<State>& states, const std::vector<std::variant<string::Epsilon, alphabet::Symbol>>& symbols, State*& initialState, std::set<State>& finalStates, std::set<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, State>>& transitionFunction); - void parseMultiInitialStateNFATransition(MultiInitialStateNFA& res, const std::vector<alphabet::Symbol>& symbols); - void parseNFATransition(std::set<State>& states, const std::vector<alphabet::Symbol>& symbols, State*& initialState, std::set<State>& finalStates, std::set<std::tuple<State, alphabet::Symbol, State>>& transitionFunction); - void parseDFATransition(std::set<State>& states, const std::vector<alphabet::Symbol>& symbols, State*& initialState, std::set<State>& finalStates, std::set<std::tuple<State, alphabet::Symbol, State>>& transitionFunction); - virtual bool last(); - Automaton parse(); - Automaton parse(const std::set<FEATURES>& features); - bool next(); + void parseEpsilonNFATransition(std::istream& input, std::set<State>& states, const std::vector<std::variant<string::Epsilon, alphabet::Symbol>>& symbols, State*& initialState, std::set<State>& finalStates, std::set<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, State>>& transitionFunction) const; + void parseMultiInitialStateNFATransition(std::istream& input, MultiInitialStateNFA& res, const std::vector<alphabet::Symbol>& symbols) const; + void parseNFATransition(std::istream& input, std::set<State>& states, const std::vector<alphabet::Symbol>& symbols, State*& initialState, std::set<State>& finalStates, std::set<std::tuple<State, alphabet::Symbol, State>>& transitionFunction) const; + void parseDFATransition(std::istream& input, std::set<State>& states, const std::vector<alphabet::Symbol>& symbols, State*& initialState, std::set<State>& finalStates, std::set<std::tuple<State, alphabet::Symbol, State>>& transitionFunction) const; -public: - FiniteAutomatonFromStringParser(std::istream& input); + Automaton parseAutomaton(std::istream& input) const; + Automaton parseAutomaton(std::istream& input, const std::set<FEATURES>& features) const; - bool first(); + EpsilonNFA parseEpsilonNFA(std::istream& input) const; + NFA parseNFA(std::istream& input) const; + MultiInitialStateNFA parseMultiInitialStateNFA(std::istream& input) const; + DFA parseDFA(std::istream& input) const; + template<typename T> friend class alib::stringApi; }; } /* namespace automaton */ diff --git a/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp b/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp index c769edf590..f9456785c9 100644 --- a/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp +++ b/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp @@ -1,12 +1,18 @@ +/* + * FiniteAutomatonToStringComposer.cpp + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + #include "FiniteAutomatonToStringComposer.h" #include "../../exception/AlibException.h" -#include "../../alphabet/SymbolToStringComposer.h" -#include "../../label/LabelToStringComposer.h" +#include "../../StringApi.hpp" namespace automaton { -void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::stringstream& out, const DFA& automaton, const State& from) const { +void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, const DFA& automaton, const State& from) const { std::map<std::pair<State, alphabet::Symbol>, State> symbolTransitionsFromState = automaton.getTransitionsFromState(from); for(const alphabet::Symbol& inputSymbol : automaton.getInputAlphabet()) { @@ -14,13 +20,13 @@ void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::stringstr if(toStates == symbolTransitionsFromState.end()) { out << " -"; } else { - label::LabelToStringComposer composer; - out << " " << composer.compose(toStates->second.getName()); + out << " "; + alib::stringApi<label::Label>::compose(out, toStates->second.getName()); } } } -void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::stringstream& out, const NFA& automaton, const State& from) const { +void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, const NFA& automaton, const State& from) const { std::map<std::pair<State, alphabet::Symbol>, std::set<State> > symbolTransitionsFromState = automaton.getTransitionsFromState(from); for(const alphabet::Symbol& inputSymbol : automaton.getInputAlphabet()) { @@ -30,15 +36,15 @@ void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::stringstr } else { bool sign = false; for(const State& to : toStates->second) { - label::LabelToStringComposer composer; - out << (sign ? "|" : " ") << composer.compose(to.getName()); + out << (sign ? "|" : " "); + alib::stringApi<label::Label>::compose(out, to.getName()); sign = true; } } } } -void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::stringstream& out, const MultiInitialStateNFA& automaton, const State& from) const { +void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, const MultiInitialStateNFA& automaton, const State& from) const { std::map<std::pair<State, alphabet::Symbol>, std::set<State> > symbolTransitionsFromState = automaton.getTransitionsFromState(from); for(const alphabet::Symbol& inputSymbol : automaton.getInputAlphabet()) { @@ -48,15 +54,15 @@ void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::stringstr } else { bool sign = false; for(const State& to : toStates->second) { - label::LabelToStringComposer composer; - out << (sign ? "|" : " ") << composer.compose(to.getName()); + out << (sign ? "|" : " "); + alib::stringApi<label::Label>::compose(out, to.getName()); sign = true; } } } } -void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::stringstream& out, const EpsilonNFA& automaton, const State& from) const { +void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, const EpsilonNFA& automaton, const State& from) const { std::map<std::pair<State, alphabet::Symbol>, std::set<State> > symbolTransitionsFromState = automaton.getSymbolTransitionsFromState(from); for(const alphabet::Symbol& inputSymbol : automaton.getInputAlphabet()) { @@ -66,8 +72,8 @@ void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::stringstr } else { bool sign = false; for(const State& to : toStates->second) { - label::LabelToStringComposer composer; - out << (sign ? "|" : " ") << composer.compose(to.getName()); + out << (sign ? "|" : " "); + alib::stringApi<label::Label>::compose(out, to.getName()); sign = true; } } @@ -79,150 +85,128 @@ void FiniteAutomatonToStringComposer::composeTransitionsFromState(std::stringstr } else { bool sign = false; for(const State& to : epsilonTransitionsFromState.begin()->second) { - label::LabelToStringComposer composer; - out << (sign ? "|" : " ") << composer.compose(to.getName()); + out << (sign ? "|" : " "); + alib::stringApi<label::Label>::compose(out, to.getName()); sign = true; } } } -std::string FiniteAutomatonToStringComposer::compose(const DFA& automaton) const { - std::stringstream out; - +void FiniteAutomatonToStringComposer::compose(std::ostream& out, const DFA& automaton) const { out << "DFA"; - for(auto iterSymbol = automaton.getInputAlphabet().begin(); iterSymbol != automaton.getInputAlphabet().end(); iterSymbol++) { - alphabet::SymbolToStringComposer composer; - out << " " << composer.compose(*iterSymbol); + for(const auto& symbol : automaton.getInputAlphabet()) { + out << " "; + alib::stringApi<alphabet::Symbol>::compose(out, symbol); } out << std::endl; - for(auto iterState = automaton.getStates().begin(); iterState != automaton.getStates().end(); iterState++) { - if(automaton.getInitialState() == *iterState) { + for(const auto& state : automaton.getStates()) { + if(automaton.getInitialState() == state) { out << ">"; } - if(automaton.getFinalStates().find(*iterState) != automaton.getFinalStates().end()) { + if(automaton.getFinalStates().find(state) != automaton.getFinalStates().end()) { out << "<"; } - label::LabelToStringComposer composer; - out << composer.compose(iterState->getName()); + alib::stringApi<label::Label>::compose(out, state.getName()); - composeTransitionsFromState(out, automaton, *iterState); + composeTransitionsFromState(out, automaton, state); out << std::endl; } - - return out.str(); } -std::string FiniteAutomatonToStringComposer::compose(const NFA& automaton) const { - std::stringstream out; - +void FiniteAutomatonToStringComposer::compose(std::ostream& out, const NFA& automaton) const { out << "NFA"; - for(auto iterSymbol = automaton.getInputAlphabet().begin(); iterSymbol != automaton.getInputAlphabet().end(); iterSymbol++) { - alphabet::SymbolToStringComposer composer; - out << " " << composer.compose(*iterSymbol); + for(const auto& symbol : automaton.getInputAlphabet()) { + out << " "; + alib::stringApi<alphabet::Symbol>::compose(out, symbol); } out << std::endl; - for(auto iterState = automaton.getStates().begin(); iterState != automaton.getStates().end(); iterState++) { - if(automaton.getInitialState() == *iterState) { + for(const auto& state : automaton.getStates()) { + if(automaton.getInitialState() == state) { out << ">"; } - if(automaton.getFinalStates().find(*iterState) != automaton.getFinalStates().end()) { + if(automaton.getFinalStates().find(state) != automaton.getFinalStates().end()) { out << "<"; } - label::LabelToStringComposer composer; - out << composer.compose(iterState->getName()); + alib::stringApi<label::Label>::compose(out, state.getName()); - composeTransitionsFromState(out, automaton, *iterState); + composeTransitionsFromState(out, automaton, state); out << std::endl; } - - return out.str(); } -std::string FiniteAutomatonToStringComposer::compose(const MultiInitialStateNFA& automaton) const { - std::stringstream out; - +void FiniteAutomatonToStringComposer::compose(std::ostream& out, const MultiInitialStateNFA& automaton) const { out << "MISNFA"; - for(auto iterSymbol = automaton.getInputAlphabet().begin(); iterSymbol != automaton.getInputAlphabet().end(); iterSymbol++) { - alphabet::SymbolToStringComposer composer; - out << " " << composer.compose(*iterSymbol); + for(const auto& symbol : automaton.getInputAlphabet()) { + out << " "; + alib::stringApi<alphabet::Symbol>::compose(out, symbol); } out << std::endl; - for(auto iterState = automaton.getStates().begin(); iterState != automaton.getStates().end(); iterState++) { - if(automaton.getInitialStates().find(*iterState) != automaton.getInitialStates().end()) { + for(const auto& state : automaton.getStates()) { + if(automaton.getInitialStates().find(state) != automaton.getInitialStates().end()) { out << ">"; } - if(automaton.getFinalStates().find(*iterState) != automaton.getFinalStates().end()) { + if(automaton.getFinalStates().find(state) != automaton.getFinalStates().end()) { out << "<"; } - label::LabelToStringComposer composer; - out << composer.compose(iterState->getName()); + alib::stringApi<label::Label>::compose(out, state.getName()); - composeTransitionsFromState(out, automaton, *iterState); + composeTransitionsFromState(out, automaton, state); out << std::endl; } - - return out.str(); } -std::string FiniteAutomatonToStringComposer::compose(const EpsilonNFA& automaton) const { - std::stringstream out; - +void FiniteAutomatonToStringComposer::compose(std::ostream& out, const EpsilonNFA& automaton) const { out << "ENFA"; - for(auto iterSymbol = automaton.getInputAlphabet().begin(); iterSymbol != automaton.getInputAlphabet().end(); iterSymbol++) { - alphabet::SymbolToStringComposer composer; - out << " " << composer.compose(*iterSymbol); + for(const auto& symbol : automaton.getInputAlphabet()) { + out << " "; + alib::stringApi<alphabet::Symbol>::compose(out, symbol); } out << " #E"; out << std::endl; - for(auto iterState = automaton.getStates().begin(); iterState != automaton.getStates().end(); iterState++) { - if(automaton.getInitialState() == *iterState) { + for(const auto& state : automaton.getStates()) { + if(automaton.getInitialState() == state) { out << ">"; } - if(automaton.getFinalStates().find(*iterState) != automaton.getFinalStates().end()) { + if(automaton.getFinalStates().find(state) != automaton.getFinalStates().end()) { out << "<"; } - label::LabelToStringComposer composer; - out << composer.compose(iterState->getName()); + alib::stringApi<label::Label>::compose(out, state.getName()); - composeTransitionsFromState(out, automaton, *iterState); + composeTransitionsFromState(out, automaton, state); out << std::endl; } - - return out.str(); } -std::string FiniteAutomatonToStringComposer::compose(const Automaton& automaton) const { - std::stringstream out; - automaton.getData().Accept((void*) &out, *this); - return out.str(); +void FiniteAutomatonToStringComposer::compose(std::ostream& output, const Automaton& automaton) const { + automaton.getData().Accept((void*) &output, *this); } void FiniteAutomatonToStringComposer::Visit(void* data, const EpsilonNFA& automaton) const { - *((std::stringstream*) data) << this->compose(automaton); + this->compose(*((std::ostream*) data), automaton); } void FiniteAutomatonToStringComposer::Visit(void* data, const MultiInitialStateNFA& automaton) const { - *((std::stringstream*) data) << this->compose(automaton); + this->compose(*((std::ostream*) data), automaton); } void FiniteAutomatonToStringComposer::Visit(void* data, const NFA& automaton) const { - *((std::stringstream*) data) << this->compose(automaton); + this->compose(*((std::ostream*) data), automaton); } void FiniteAutomatonToStringComposer::Visit(void* data, const DFA& automaton) const { - *((std::stringstream*) data) << this->compose(automaton); + this->compose(*((std::ostream*) data), automaton); } void FiniteAutomatonToStringComposer::Visit(void*, const ExtendedNFA&) const { diff --git a/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.h b/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.h index 02026ace9a..e16b9dd80f 100644 --- a/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.h +++ b/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.h @@ -1,3 +1,10 @@ +/* + * FiniteAutomatonToStringComposer.cpp + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + #ifndef AUTOMATON_PRINTER_H_ #define AUTOMATON_PRINTER_H_ @@ -28,10 +35,10 @@ class FiniteAutomatonToStringComposer : public VisitableAutomatonBase::const_vis void Visit(void*, const SinglePopNPDA& automaton) const; void Visit(void*, const OneTapeDTM& automaton) const; - void composeTransitionsFromState(std::stringstream& out, const DFA& automaton, const State& from) const; - void composeTransitionsFromState(std::stringstream& out, const NFA& automaton, const State& from) const; - void composeTransitionsFromState(std::stringstream& out, const MultiInitialStateNFA& automaton, const State& from) const; - void composeTransitionsFromState(std::stringstream& out, const EpsilonNFA& automaton, const State& from) const; + void composeTransitionsFromState(std::ostream& out, const DFA& automaton, const State& from) const; + void composeTransitionsFromState(std::ostream& out, const NFA& automaton, const State& from) const; + void composeTransitionsFromState(std::ostream& out, const MultiInitialStateNFA& automaton, const State& from) const; + void composeTransitionsFromState(std::ostream& out, const EpsilonNFA& automaton, const State& from) const; public: /** @@ -39,14 +46,14 @@ public: * @param automaton automaton to print * @return list of xml tokens representing the automaton */ - std::string compose(const AutomatonBase& automaton) const; - - std::string compose(const Automaton& automaton) const; - - std::string compose(const DFA& automaton) const; - std::string compose(const NFA& automaton) const; - std::string compose(const MultiInitialStateNFA& automaton) const; - std::string compose(const EpsilonNFA& automaton) const; + void compose(std::ostream& output, const AutomatonBase& automaton) const; + + void compose(std::ostream& output, const Automaton& automaton) const; + + void compose(std::ostream& output, const DFA& automaton) const; + void compose(std::ostream& output, const NFA& automaton) const; + void compose(std::ostream& output, const MultiInitialStateNFA& automaton) const; + void compose(std::ostream& output, const EpsilonNFA& automaton) const; }; } /* namespace automaton */ diff --git a/alib2data/src/factory/StringDataFactory.hpp b/alib2data/src/factory/StringDataFactory.hpp new file mode 100644 index 0000000000..862276bf21 --- /dev/null +++ b/alib2data/src/factory/StringDataFactory.hpp @@ -0,0 +1,75 @@ +/* + * StringDataFactory.h + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#ifndef STRING_DATA_FACTORY +#define STRING_DATA_FACTORY + +#include <set> +#include "../exception/AlibException.h" +#include "../StringApi.hpp" +#include <cctype> + +namespace alib { + +class StringDataFactory { +public: + + template<class T> + static T fromFile(const std::string& filename) { + std::ifstream fileStream(filename); + return fromStream<T>(fileStream); + } + + template<class T> + static T fromString(const std::string& str) { + std::stringstream stringStream(str); + return fromStream<T>(stringStream); + } + + template<class T> + static T fromStdin() { + return fromStream<T>(std::cin); + } + + template<class T> + static T fromStream(std::istream& in) { + if(in.peek() == EOF) throw exception::AlibException("Empty stream"); + + T res = alib::stringApi<T>::parse(in); + + while(isspace(in.peek())) in.get(); + if(in.peek() != EOF) throw exception::AlibException("Unexpected characters at the end of the stream"); + return res; + } + + template<class T> + static void toFile(const T& data, const std::string& filename) { + std::ofstream fileStream(filename); + toStream<T>(data, fileStream); + } + + template<class T> + static std::string toString(const T& data) { + std::stringstream stringStream; + toStream<T>(data, stringStream); + return stringStream.str(); + } + + template<class T> + static void toStdout(const T& data) { + toStream<T>(data, std::cout); + } + + template<class T> + static void toStream(const T& data, std::ostream& out) { + alib::stringApi<T>::compose(out, data); + } +}; + +} /* namespace alib */ + +#endif /* STRING_DATA_FACTORY */ diff --git a/alib2data/src/grammar/GrammarFromStringLexer.cpp b/alib2data/src/grammar/GrammarFromStringLexer.cpp index 57e9406323..bf516057a4 100644 --- a/alib2data/src/grammar/GrammarFromStringLexer.cpp +++ b/alib2data/src/grammar/GrammarFromStringLexer.cpp @@ -9,105 +9,105 @@ namespace grammar { -GrammarFromStringLexer::GrammarFromStringLexer(std::istream& in) : m_In(in) { - m_Current.type = TokenType::ERROR; - m_Current.value = ""; -} - -GrammarFromStringLexer& GrammarFromStringLexer::next() { - if(m_Current.type == TokenType::TEOF) return *this; +GrammarFromStringLexer::Token GrammarFromStringLexer::next(std::istream& in) const { + GrammarFromStringLexer::Token token; + token.type = TokenType::ERROR; + token.value = ""; + token.raw = ""; char character; - m_Current.value = ""; L0: - character = m_In.get(); - if(m_In.eof()) { - m_Current.type = TokenType::TEOF; - return *this; + character = in.get(); + if(in.eof()) { + token.type = TokenType::TEOF; + return token; } else if(character == ' ' || character == '\t' || character == '\n') { + token.raw += character; goto L0; } else if(character == '|') { - m_Current.type = TokenType::SEPARATOR; - m_Current.value += character; - return *this; + token.type = TokenType::SEPARATOR; + token.value += character; + token.raw += character; + return token; } else if(character == '{') { - m_Current.type = TokenType::SET_BEGIN; - m_Current.value += character; - return *this; + token.type = TokenType::SET_BEGIN; + token.value += character; + token.raw += character; + return token; } else if(character == '}') { - m_Current.type = TokenType::SET_END; - m_Current.value += character; - return *this; + token.type = TokenType::SET_END; + token.value += character; + token.raw += character; + return token; } else if(character == '(') { - m_Current.type = TokenType::TUPLE_BEGIN; - m_Current.value += character; - return *this; + token.type = TokenType::TUPLE_BEGIN; + token.value += character; + token.raw += character; + return token; } else if(character == ')') { - m_Current.type = TokenType::TUPLE_END; - m_Current.value += character; - return *this; + token.type = TokenType::TUPLE_END; + token.value += character; + token.raw += character; + return token; } else if(character == ',') { - m_Current.type = TokenType::COMMA; - m_Current.value += character; - return *this; + token.type = TokenType::COMMA; + token.value += character; + token.raw += character; + return token; } else if(character == '-') { - m_Current.value += character; + token.value += character; + token.raw += character; goto L2; } else if(character == '#') { - m_Current.value += character; + token.value += character; + token.raw += character; goto L1; } else { - m_In.putback(character); - while(!m_Current.value.empty()) { - m_In.putback(m_Current.value.back()); - m_Current.value.pop_back(); - } - m_In.clear(); - m_Current.type = TokenType::ERROR; - return *this; + in.putback(character); + putback(in, std::move(token)); + token.type = TokenType::ERROR; + return token; } L1: - character = m_In.get(); - if(m_In.eof()) { - m_Current.type = TokenType::TEOF; - return *this; + character = in.get(); + if(in.eof()) { + token.type = TokenType::TEOF; + return token; } else if(character == 'E') { - m_Current.value += character; - m_Current.type = TokenType::EPSILON; - return *this; + token.value += character; + token.raw += character; + token.type = TokenType::EPSILON; + return token; } else { - m_In.putback(character); - while(!m_Current.value.empty()) { - m_In.putback(m_Current.value.back()); - m_Current.value.pop_back(); - } - m_In.clear(); - m_Current.type = TokenType::ERROR; - return *this; + in.putback(character); + putback(in, std::move(token)); + token.type = TokenType::ERROR; + return token; } L2: - character = m_In.get(); - if(m_In.eof()) { - m_Current.type = TokenType::TEOF; - return *this; + character = in.get(); + if(in.eof()) { + token.type = TokenType::TEOF; + return token; } else if(character == '>') { - m_Current.value += character; - m_Current.type = TokenType::MAPS_TO; - return *this; + token.value += character; + token.raw += character; + token.type = TokenType::MAPS_TO; + return token; } else { - m_In.putback(character); - while(!m_Current.value.empty()) { - m_In.putback(m_Current.value.back()); - m_Current.value.pop_back(); - } - m_In.clear(); - m_Current.type = TokenType::ERROR; - return *this; + in.putback(character); + putback(in, std::move(token)); + token.type = TokenType::ERROR; + return token; } } -GrammarFromStringLexer::Token GrammarFromStringLexer::token() { - return m_Current; +void GrammarFromStringLexer::putback(std::istream& in, GrammarFromStringLexer::Token token) const { + while(!token.raw.empty()) { + in.putback(token.raw.back()); + token.raw.pop_back(); + } + in.clear(); } } /* namespace grammar */ diff --git a/alib2data/src/grammar/GrammarFromStringLexer.h b/alib2data/src/grammar/GrammarFromStringLexer.h index f706087a7b..98f0f41b14 100644 --- a/alib2data/src/grammar/GrammarFromStringLexer.h +++ b/alib2data/src/grammar/GrammarFromStringLexer.h @@ -31,15 +31,11 @@ public: struct Token { TokenType type; std::string value; + std::string raw; }; -private: - std::istream& m_In; - Token m_Current; -public: - GrammarFromStringLexer(std::istream&); - GrammarFromStringLexer& next(); - Token token(); + Token next(std::istream& input) const; + void putback(std::istream&, Token token) const; }; } /* namepsace grammar */ diff --git a/alib2data/src/grammar/GrammarFromStringParser.cpp b/alib2data/src/grammar/GrammarFromStringParser.cpp index 434630a419..94128b7969 100644 --- a/alib2data/src/grammar/GrammarFromStringParser.cpp +++ b/alib2data/src/grammar/GrammarFromStringParser.cpp @@ -9,74 +9,44 @@ #include "../exception/AlibException.h" +#include "../StringApi.hpp" namespace grammar { -GrammarFromStringParser::GrammarFromStringParser(std::istream& input) : m_GrammarLexer(input), m_SymbolParser(input) { - -} - -Grammar GrammarFromStringParser::parse() { - return parse(std::set<FEATURES>({})); +Grammar GrammarFromStringParser::parseGrammar(std::istream& input) const { + return parseGrammar(input, std::set<FEATURES>({})); } -Grammar GrammarFromStringParser::parse(const std::set<FEATURES>& features) { +Grammar GrammarFromStringParser::parseGrammar(std::istream& input, const std::set<FEATURES>& features) const { throw exception::AlibException(); } -bool GrammarFromStringParser::first() { - GrammarFromStringLexer::Token token = m_GrammarLexer.next().token(); - if(token.type == GrammarFromStringLexer::TokenType::TUPLE_BEGIN) { - return true; - } else { - return false; - } -} - -bool GrammarFromStringParser::next() { - GrammarFromStringLexer::Token token = m_GrammarLexer.next().token(); - if(token.type == GrammarFromStringLexer::TokenType::COMMA || token.type == GrammarFromStringLexer::TokenType::SEPARATOR || token.type == GrammarFromStringLexer::TokenType::SET_BEGIN || token.type == GrammarFromStringLexer::TokenType::SET_END || token.type == GrammarFromStringLexer::TokenType::TUPLE_BEGIN || token.type == GrammarFromStringLexer::TokenType::TUPLE_END || token.type == GrammarFromStringLexer::TokenType::EPSILON || token.type == GrammarFromStringLexer::TokenType::MAPS_TO) { - return true; - } else { - return false; - } -} - -bool GrammarFromStringParser::last() { - GrammarFromStringLexer::Token token = m_GrammarLexer.next().token(); - if(token.type == GrammarFromStringLexer::TokenType::TEOF) { - return true; - } else { - return false; - } -} - -std::set<alphabet::Symbol> GrammarFromStringParser::parseSet() { +std::set<alphabet::Symbol> GrammarFromStringParser::parseSet(std::istream& input) const { std::set<alphabet::Symbol> res; - GrammarFromStringLexer::Token token = m_GrammarLexer.token(); + GrammarFromStringLexer::Token token = m_GrammarLexer.next(input); if(token.type != GrammarFromStringLexer::TokenType::SET_BEGIN) { throw exception::AlibException(); } - next() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first(); - token = m_GrammarLexer.token(); + token = m_GrammarLexer.next(input); if(token.type != GrammarFromStringLexer::TokenType::SET_END) while(true) { - alphabet::Symbol symbol = m_SymbolParser.parse(); + m_GrammarLexer.putback(input, token); + alphabet::Symbol symbol = alib::stringApi<alphabet::Symbol>::parse(input); res.insert(symbol); - next(); - token = m_GrammarLexer.token(); - if(token.type != GrammarFromStringLexer::TokenType::COMMA) { + token = m_GrammarLexer.next(input); + if(token.type != GrammarFromStringLexer::TokenType::SET_END) { break; } - next() || m_SymbolParser.first() || m_SymbolParser.m_LabelParser.first(); + if(token.type != GrammarFromStringLexer::TokenType::COMMA) { + throw exception::AlibException("Expected SET_END or COMMA token"); + } } - + if(token.type != GrammarFromStringLexer::TokenType::SET_END) { - throw exception::AlibException(); + throw exception::AlibException("Expected SET_END token"); } - next(); return res; } diff --git a/alib2data/src/grammar/GrammarFromStringParser.h b/alib2data/src/grammar/GrammarFromStringParser.h index fd441cdfa5..95bc75547b 100644 --- a/alib2data/src/grammar/GrammarFromStringParser.h +++ b/alib2data/src/grammar/GrammarFromStringParser.h @@ -9,28 +9,28 @@ #define GRAMMAR_FROM_STRING_PARSER_H_ #include "GrammarFromStringLexer.h" -#include "../alphabet/SymbolFromStringParser.h" - #include "Grammar.h" #include "GrammarFeatures.h" +#include "../alphabet/Symbol.h" + +namespace alib { + +template<typename T> +struct stringApi; + +} /* namespace alib */ namespace grammar { -class GrammarFromStringParser : public alib::FromStringParser<Grammar, FEATURES> { +class GrammarFromStringParser { GrammarFromStringLexer m_GrammarLexer; - alphabet::SymbolFromStringParser m_SymbolParser; - - std::set<alphabet::Symbol> parseSet(); - virtual bool last(); - Grammar parse(); - Grammar parse(const std::set<FEATURES>& features); - bool next(); + std::set<alphabet::Symbol> parseSet(std::istream& input) const; -public: - GrammarFromStringParser(std::istream& input); + Grammar parseGrammar(std::istream& input) const; + Grammar parseGrammar(std::istream& input, const std::set<FEATURES>& features) const; - bool first(); + template<typename T> friend class alib::stringApi; }; } /* namespace grammar */ diff --git a/alib2data/src/grammar/GrammarToStringComposer.cpp b/alib2data/src/grammar/GrammarToStringComposer.cpp index 00a6165758..d71393cb8e 100644 --- a/alib2data/src/grammar/GrammarToStringComposer.cpp +++ b/alib2data/src/grammar/GrammarToStringComposer.cpp @@ -1,185 +1,165 @@ #include "GrammarToStringComposer.h" -#include "../alphabet/SymbolToStringComposer.h" #include <sstream> #include "ContextFree/CNF.h" -namespace grammar { +#include "../StringApi.hpp" -std::string GrammarToStringComposer::compose(const GrammarBase& grammar) const { - std::stringstream out; - grammar.Accept((void*) &out, *this); - return out.str(); -} +namespace grammar { -std::string GrammarToStringComposer::compose(const Grammar& grammar) const { - std::stringstream out; - grammar.getData().Accept((void*) &out, *this); - return out.str(); +void GrammarToStringComposer::compose(std::ostream& output, const Grammar& grammar) const { + grammar.getData().Accept((void*) &output, *this); } -std::string GrammarToStringComposer::compose(const LeftLG& grammar) const { +void GrammarToStringComposer::compose(std::ostream& output, const LeftLG& grammar) const { // TODO - return "todo"; } -std::string GrammarToStringComposer::compose(const LeftRG& grammar) const { +void GrammarToStringComposer::compose(std::ostream& output, const LeftRG& grammar) const { // TODO - return "todo"; } -std::string GrammarToStringComposer::compose(const RightLG& grammar) const { +void GrammarToStringComposer::compose(std::ostream& output, const RightLG& grammar) const { // TODO - return "todo"; } -std::string GrammarToStringComposer::compose(const RightRG& grammar) const { +void GrammarToStringComposer::compose(std::ostream& output, const RightRG& grammar) const { // TODO - return "todo"; } -std::string GrammarToStringComposer::compose(const LG& grammar) const { +void GrammarToStringComposer::compose(std::ostream& output, const LG& grammar) const { // TODO - return "todo"; } -std::string GrammarToStringComposer::compose(const CFG& grammar) const { +void GrammarToStringComposer::compose(std::ostream& output, const CFG& grammar) const { // TODO - return "todo"; } -std::string GrammarToStringComposer::compose(const EpsilonFreeCFG& grammar) const { +void GrammarToStringComposer::compose(std::ostream& output, const EpsilonFreeCFG& grammar) const { // TODO - return "todo"; } -std::string GrammarToStringComposer::compose(const CNF& grammar) const { - alphabet::SymbolToStringComposer sscomp; - std::stringstream ss; +void GrammarToStringComposer::compose(std::ostream& output, const CNF& grammar) const { bool first; - ss << "(CNF," << std::endl; + output << "(CNF," << std::endl; - ss << "{"; + output << "{"; first = false; for(const auto& symbol : grammar.getNonterminalAlphabet() ) { if(first) - ss << ", "; + output << ", "; else first = true; - ss << sscomp.compose(symbol); + alib::stringApi<alphabet::Symbol>::compose(output, symbol); } - ss << "}," << std::endl; - ss << "{"; + output << "}," << std::endl; + output << "{"; first = false; for(const auto& symbol : grammar.getTerminalAlphabet() ) { if(first) - ss << ", "; + output << ", "; else first = true; - ss << sscomp.compose(symbol); + alib::stringApi<alphabet::Symbol>::compose(output, symbol); } - ss << "}," << std::endl; - ss << "{ "; + output << "}," << std::endl; + output << "{ "; first = false; for(const auto& rule : grammar.getRawRules() ) { if(first) - ss << ", " << std::endl << " "; + output << ", " << std::endl << " "; else first = true; - ss << sscomp.compose(rule.first); - ss << " -> "; + alib::stringApi<alphabet::Symbol>::compose(output, rule.first); + output << " -> "; bool innerFirst = false; for(const auto& rhs : rule.second) { if(innerFirst) - ss << " | "; + output << " | "; else innerFirst = true; - for(const auto& symbol : rhs) - ss << sscomp.compose(symbol) << " "; + for(const auto& symbol : rhs) { + alib::stringApi<alphabet::Symbol>::compose(output, symbol); + output << " "; + } } } - ss << "}," << std::endl; - ss << sscomp.compose(grammar.getInitialSymbol()) << std::endl; - ss << ")" << std::endl; - - return std::move(ss).str(); + output << "}," << std::endl; + alib::stringApi<alphabet::Symbol>::compose(output, grammar.getInitialSymbol()); + output << std::endl; + output << ")" << std::endl; } -std::string GrammarToStringComposer::compose(const GNF& grammar) const { +void GrammarToStringComposer::compose(std::ostream& output, const GNF& grammar) const { // TODO - return "todo"; } -std::string GrammarToStringComposer::compose(const CSG& grammar) const { +void GrammarToStringComposer::compose(std::ostream& output, const CSG& grammar) const { // TODO - return "todo"; } -std::string GrammarToStringComposer::compose(const NonContractingGrammar& grammar) const { +void GrammarToStringComposer::compose(std::ostream& output, const NonContractingGrammar& grammar) const { // TODO - return "todo"; } -std::string GrammarToStringComposer::compose(const ContextPreservingUnrestrictedGrammar& grammar) const { +void GrammarToStringComposer::compose(std::ostream& output, const ContextPreservingUnrestrictedGrammar& grammar) const { // TODO - return "todo"; } -std::string GrammarToStringComposer::compose(const UnrestrictedGrammar& grammar) const { +void GrammarToStringComposer::compose(std::ostream& output, const UnrestrictedGrammar& grammar) const { // TODO - return "todo"; } void GrammarToStringComposer::Visit(void* data, const LeftLG& grammar) const { - *((std::stringstream*) data) << this->compose(grammar); + this->compose(*((std::ostream*) data), grammar); } void GrammarToStringComposer::Visit(void* data, const LeftRG& grammar) const { - *((std::stringstream*) data) << this->compose(grammar); + this->compose(*((std::ostream*) data), grammar); } void GrammarToStringComposer::Visit(void* data, const RightLG& grammar) const { - *((std::stringstream*) data) << this->compose(grammar); + this->compose(*((std::ostream*) data), grammar); } void GrammarToStringComposer::Visit(void* data, const RightRG& grammar) const { - *((std::stringstream*) data) << this->compose(grammar); + this->compose(*((std::ostream*) data), grammar); } void GrammarToStringComposer::Visit(void* data, const LG& grammar) const { - *((std::stringstream*) data) << this->compose(grammar); + this->compose(*((std::ostream*) data), grammar); } void GrammarToStringComposer::Visit(void* data, const CFG& grammar) const { - *((std::stringstream*) data) << this->compose(grammar); + this->compose(*((std::ostream*) data), grammar); } void GrammarToStringComposer::Visit(void* data, const EpsilonFreeCFG& grammar) const { - *((std::stringstream*) data) << this->compose(grammar); + this->compose(*((std::ostream*) data), grammar); } void GrammarToStringComposer::Visit(void* data, const CNF& grammar) const { - *((std::stringstream*) data) << this->compose(grammar); + this->compose(*((std::ostream*) data), grammar); } void GrammarToStringComposer::Visit(void* data, const GNF& grammar) const { - *((std::stringstream*) data) << this->compose(grammar); + this->compose(*((std::ostream*) data), grammar); } void GrammarToStringComposer::Visit(void* data, const CSG& grammar) const { - *((std::stringstream*) data) << this->compose(grammar); + this->compose(*((std::ostream*) data), grammar); } void GrammarToStringComposer::Visit(void* data, const NonContractingGrammar& grammar) const { - *((std::stringstream*) data) << this->compose(grammar); + this->compose(*((std::ostream*) data), grammar); } void GrammarToStringComposer::Visit(void* data, const ContextPreservingUnrestrictedGrammar& grammar) const { - *((std::stringstream*) data) << this->compose(grammar); + this->compose(*((std::ostream*) data), grammar); } void GrammarToStringComposer::Visit(void* data, const UnrestrictedGrammar& grammar) const { - *((std::stringstream*) data) << this->compose(grammar); + this->compose(*((std::ostream*) data), grammar); } } diff --git a/alib2data/src/grammar/GrammarToStringComposer.h b/alib2data/src/grammar/GrammarToStringComposer.h index de36439b26..6707e0dc8c 100644 --- a/alib2data/src/grammar/GrammarToStringComposer.h +++ b/alib2data/src/grammar/GrammarToStringComposer.h @@ -31,23 +31,21 @@ public: * @param automaton automaton to print * @return list of xml tokens representing the automaton */ - std::string compose(const GrammarBase& grammar) const; - - std::string compose(const Grammar& grammar) const; - - std::string compose(const LeftLG& grammar) const; - std::string compose(const LeftRG& grammar) const; - std::string compose(const RightLG& grammar) const; - std::string compose(const RightRG& grammar) const; - std::string compose(const LG& grammar) const; - std::string compose(const CFG& grammar) const; - std::string compose(const EpsilonFreeCFG& grammar) const; - std::string compose(const CNF& grammar) const; - std::string compose(const GNF& grammar) const; - std::string compose(const CSG& grammar) const; - std::string compose(const NonContractingGrammar& grammar) const; - std::string compose(const ContextPreservingUnrestrictedGrammar& grammar) const; - std::string compose(const UnrestrictedGrammar& grammar) const; + void compose(std::ostream& output, const Grammar& grammar) const; + + void compose(std::ostream& output, const LeftLG& grammar) const; + void compose(std::ostream& output, const LeftRG& grammar) const; + void compose(std::ostream& output, const RightLG& grammar) const; + void compose(std::ostream& output, const RightRG& grammar) const; + void compose(std::ostream& output, const LG& grammar) const; + void compose(std::ostream& output, const CFG& grammar) const; + void compose(std::ostream& output, const EpsilonFreeCFG& grammar) const; + void compose(std::ostream& output, const CNF& grammar) const; + void compose(std::ostream& output, const GNF& grammar) const; + void compose(std::ostream& output, const CSG& grammar) const; + void compose(std::ostream& output, const NonContractingGrammar& grammar) const; + void compose(std::ostream& output, const ContextPreservingUnrestrictedGrammar& grammar) const; + void compose(std::ostream& output, const UnrestrictedGrammar& grammar) const; }; } diff --git a/alib2data/src/label/LabelFromStringLexer.cpp b/alib2data/src/label/LabelFromStringLexer.cpp index 4f51598502..64bd2cc34d 100644 --- a/alib2data/src/label/LabelFromStringLexer.cpp +++ b/alib2data/src/label/LabelFromStringLexer.cpp @@ -6,60 +6,64 @@ */ #include "LabelFromStringLexer.h" +#include <string> namespace label { -LabelFromStringLexer::LabelFromStringLexer(std::istream& in) : m_In(in) { - m_Current.type = TokenType::ERROR; - m_Current.value = ""; -} - -LabelFromStringLexer& LabelFromStringLexer::next() { - if(m_Current.type == TokenType::TEOF) return *this; +LabelFromStringLexer::Token LabelFromStringLexer::next(std::istream& in) const { + LabelFromStringLexer::Token token; + token.type = TokenType::ERROR; + token.value = ""; + token.raw = ""; char character; - m_Current.value = ""; L0: - character = m_In.get(); - if(m_In.eof()) { - m_Current.type = TokenType::TEOF; - return *this; + character = in.get(); + if(in.eof()) { + token.type = TokenType::TEOF; + return token; } else if(character == ' ' || character == '\n' || character == '\t') { + token.raw += character; goto L0; } else if(character == '[') { - m_Current.type = TokenType::SET_BEGIN; - m_Current.value += character; - return *this; + token.type = TokenType::SET_BEGIN; + token.value += character; + token.raw += character; + return token; } else if(character == ']') { - m_Current.type = TokenType::SET_END; - m_Current.value += character; - return *this; + token.type = TokenType::SET_END; + token.value += character; + token.raw += character; + return token; } else if(character == '<') { - m_Current.type = TokenType::PAIR_BEGIN; - m_Current.value += character; - return *this; + token.type = TokenType::PAIR_BEGIN; + token.value += character; + token.raw += character; + return token; } else if(character == '>') { - m_Current.type = TokenType::PAIR_END; - m_Current.value += character; - return *this; + token.type = TokenType::PAIR_END; + token.value += character; + token.raw += character; + return token; } else if(character == ',') { - m_Current.type = TokenType::COMMA; - m_Current.value += character; - return *this; + token.type = TokenType::COMMA; + token.value += character; + token.raw += character; + return token; } else { - m_In.putback(character); - while(!m_Current.value.empty()) { - m_In.putback(m_Current.value.back()); - m_Current.value.pop_back(); - } - m_In.clear(); - m_Current.type = TokenType::ERROR; - return *this; + in.putback(character); + putback(in, std::move(token)); + token.type = TokenType::ERROR; + return token; } } -LabelFromStringLexer::Token LabelFromStringLexer::token() { - return m_Current; +void LabelFromStringLexer::putback(std::istream& in, LabelFromStringLexer::Token token) const { + while(!token.raw.empty()) { + in.putback(token.raw.back()); + token.raw.pop_back(); + } + in.clear(); } } /* namespace label */ diff --git a/alib2data/src/label/LabelFromStringLexer.h b/alib2data/src/label/LabelFromStringLexer.h index ae7f58924d..e1328d65a4 100644 --- a/alib2data/src/label/LabelFromStringLexer.h +++ b/alib2data/src/label/LabelFromStringLexer.h @@ -26,17 +26,13 @@ public: }; struct Token { - TokenType type; - std::string value; + TokenType type; + std::string value; + std::string raw; }; -private: - std::istream& m_In; - Token m_Current; -public: - LabelFromStringLexer(std::istream&); - LabelFromStringLexer& next(); - Token token(); + Token next(std::istream& input) const; + void putback(std::istream& input, Token token) const; }; } /* namespace label */ diff --git a/alib2data/src/label/LabelFromStringParser.cpp b/alib2data/src/label/LabelFromStringParser.cpp index 0fb9f36d32..d5ec9894b9 100644 --- a/alib2data/src/label/LabelFromStringParser.cpp +++ b/alib2data/src/label/LabelFromStringParser.cpp @@ -13,65 +13,55 @@ #include "LabelPairLabel.h" #include <algorithm> -namespace label { - -LabelFromStringParser::LabelFromStringParser(std::istream& input) : m_Lexer(input), m_PrimitiveParser(input) { +#include "../StringApi.hpp" -} +namespace label { -Label LabelFromStringParser::parse() { - return parse(std::set<FEATURES>({FEATURES::PRIMITIVE, FEATURES::HEXAVIGESIMAL, FEATURES::OBJECT, FEATURES::LABEL_SET, FEATURES::LABEL_PAIR, FEATURES::UNIQUE_LABEL})); +Label LabelFromStringParser::parseLabel(std::istream& input) const { + return parseLabel(input, std::set<FEATURES>({FEATURES::PRIMITIVE, FEATURES::HEXAVIGESIMAL, FEATURES::OBJECT, FEATURES::LABEL_SET, FEATURES::LABEL_PAIR, FEATURES::UNIQUE_LABEL})); } -Label LabelFromStringParser::parse(const std::set<FEATURES>& features) { - LabelFromStringLexer::Token token = m_Lexer.token(); +Label LabelFromStringParser::parseLabel(std::istream& input, const std::set<FEATURES>& features) const { + LabelFromStringLexer::Token token = m_Lexer.next(input); switch(token.type) { case LabelFromStringLexer::TokenType::TEOF: throw exception::AlibException("Unexpected end of file"); case LabelFromStringLexer::TokenType::SET_BEGIN: { if(!features.count(FEATURES::LABEL_SET)) throw exception::AlibException(); - next() || m_PrimitiveParser.next(); - token = m_Lexer.token(); + token = m_Lexer.next(input); std::set<Label> labelSet; - while(token.type != LabelFromStringLexer::TokenType::SET_END) { - Label innerLabel = this->parse(); + if(token.type != LabelFromStringLexer::TokenType::SET_END) while(true) { + m_Lexer.putback(input, std::move(token)); + Label innerLabel = this->parseLabel(input); labelSet.insert(innerLabel); - next() || m_PrimitiveParser.next(); - token = m_Lexer.token(); - - if(token.type == LabelFromStringLexer::TokenType::COMMA) { - next() || m_PrimitiveParser.next(); - token = m_Lexer.token(); - } else + token = m_Lexer.next(input); + if(token.type != LabelFromStringLexer::TokenType::COMMA) break; + + token = m_Lexer.next(input); } + if(token.type != LabelFromStringLexer::TokenType::SET_END) throw exception::AlibException("Expected SET_END token."); return Label(label::LabelSetLabel(labelSet)); } case LabelFromStringLexer::TokenType::PAIR_BEGIN: { if(!features.count(FEATURES::LABEL_PAIR)) throw exception::AlibException(); - next() || m_PrimitiveParser.next(); - token = m_Lexer.token(); - Label firstLabel = this->parse(); - next() || m_PrimitiveParser.next(); - token = m_Lexer.token(); + Label firstLabel = this->parseLabel(input); - if(token.type == LabelFromStringLexer::TokenType::COMMA) { - next() || m_PrimitiveParser.next(); - token = m_Lexer.token(); - } else + token = m_Lexer.next(input); + if(token.type != LabelFromStringLexer::TokenType::COMMA) throw exception::AlibException("Excepted COMMA token."); - Label secondLabel = this->parse(); - next() || m_PrimitiveParser.next(); - token = m_Lexer.token(); + Label secondLabel = this->parseLabel(input); + token = m_Lexer.next(input); if(token.type != LabelFromStringLexer::TokenType::PAIR_END) throw exception::AlibException("Expected PAIR_END token."); + return Label(label::LabelPairLabel(std::make_pair(firstLabel, secondLabel))); } case LabelFromStringLexer::TokenType::SET_END: @@ -80,36 +70,10 @@ Label LabelFromStringParser::parse(const std::set<FEATURES>& features) { throw exception::AlibException("Unexpected start of Label."); case LabelFromStringLexer::TokenType::ERROR: if(!features.count(FEATURES::PRIMITIVE)) throw exception::AlibException(); - return Label(PrimitiveLabel(m_PrimitiveParser.parse())); + m_Lexer.putback(input, token); + return Label(PrimitiveLabel(alib::stringApi<primitive::Primitive>::parse(input))); } throw exception::AlibException("Unrecognised input \"" + token.value + "\""); } -bool LabelFromStringParser::next() { - LabelFromStringLexer::Token token = m_Lexer.next().token(); - if(token.type == LabelFromStringLexer::TokenType::SET_BEGIN || token.type == LabelFromStringLexer::TokenType::SET_END || token.type == LabelFromStringLexer::TokenType::PAIR_BEGIN || token.type == LabelFromStringLexer::TokenType::PAIR_END || token.type == LabelFromStringLexer::TokenType::COMMA) { - return true; - } else { - return false; - } -} - -bool LabelFromStringParser::first() { - LabelFromStringLexer::Token token = m_Lexer.next().token(); - if(token.type == LabelFromStringLexer::TokenType::SET_BEGIN || token.type == LabelFromStringLexer::TokenType::PAIR_BEGIN) { - return true; - } else { - return token.type == LabelFromStringLexer::TokenType::ERROR && m_PrimitiveParser.first(); - } -} - -bool LabelFromStringParser::last() { - LabelFromStringLexer::Token token = m_Lexer.next().token(); - if(token.type == LabelFromStringLexer::TokenType::TEOF) { - return true; - } else { - return false; - } -} - } /* namespace label */ diff --git a/alib2data/src/label/LabelFromStringParser.h b/alib2data/src/label/LabelFromStringParser.h index 92404a5ba6..01b676ac1f 100644 --- a/alib2data/src/label/LabelFromStringParser.h +++ b/alib2data/src/label/LabelFromStringParser.h @@ -10,55 +10,26 @@ #include "Label.h" #include "LabelFeatures.h" -#include <vector> #include <set> -#include "../FromStringParser.hpp" -#include "../primitive/PrimitiveFromStringParser.h" #include "LabelFromStringLexer.h" -namespace alphabet { +namespace alib { -class SymbolFromStringParser; +template<typename T> +struct stringApi; -} /* namespace alphabet */ - -namespace regexp { - -class RegExpFromStringParser; - -} /* namespace regexp */ - -namespace string { - -class StringFromStringParser; - -} /* namespace string */ - -namespace automaton { - -class FiniteAutomatonFromStringParser; - -} /* namespace automaton */ +} /* namespace alib */ namespace label { -class LabelFromStringParser : public alib::FromStringParser<Label, FEATURES> { +class LabelFromStringParser { LabelFromStringLexer m_Lexer; - primitive::PrimitiveFromStringParser m_PrimitiveParser; - virtual Label parse(const std::set<FEATURES>&); - virtual Label parse(); + Label parseLabel(std::istream&, const std::set<FEATURES>&) const; + Label parseLabel(std::istream&) const; - bool next(); - virtual bool last(); -public: - virtual bool first(); - LabelFromStringParser(std::istream&); - friend class alphabet::SymbolFromStringParser; - friend class regexp::RegExpFromStringParser; - friend class string::StringFromStringParser; - friend class automaton::FiniteAutomatonFromStringParser; + template<typename T> friend class alib::stringApi; }; } /* namespace label */ diff --git a/alib2data/src/label/LabelToStringComposer.cpp b/alib2data/src/label/LabelToStringComposer.cpp index 8995e14b9d..1c7515e954 100644 --- a/alib2data/src/label/LabelToStringComposer.cpp +++ b/alib2data/src/label/LabelToStringComposer.cpp @@ -6,8 +6,6 @@ */ #include "LabelToStringComposer.h" -#include "../primitive/PrimitiveToStringComposer.h" -#include <algorithm> #include "PrimitiveLabel.h" #include "HexavigesimalLabel.h" #include "ObjectLabel.h" @@ -15,30 +13,29 @@ #include "LabelPairLabel.h" #include "UniqueLabel.h" -#include "../exception/AlibException.h" +#include "../StringApi.hpp" namespace label { -void LabelToStringComposer::Visit(void* userData, const PrimitiveLabel& label) { - std::stringstream &out = *((std::stringstream*) userData); +void LabelToStringComposer::Visit(void* userData, const PrimitiveLabel& label) const { + std::ostream &out = *((std::ostream*) userData); - primitive::PrimitiveToStringComposer composer; - out << composer.compose(label.getData()); + alib::stringApi<primitive::Primitive>::compose(out, label.getData()); } -void LabelToStringComposer::Visit(void* userData, const HexavigesimalLabel& label) { - std::stringstream &out = *((std::stringstream*) userData); +void LabelToStringComposer::Visit(void* userData, const HexavigesimalLabel& label) const { + std::ostream &out = *((std::ostream*) userData); out << (std::string) label; } -void LabelToStringComposer::Visit(void* userData, const ObjectLabel& label) { - std::stringstream &out = *((std::stringstream*) userData); +void LabelToStringComposer::Visit(void* userData, const ObjectLabel& label) const { + std::ostream &out = *((std::ostream*) userData); out << (std::string) label; } -void LabelToStringComposer::Visit(void* userData, const LabelSetLabel& label) { - std::stringstream &out = *((std::stringstream*) userData); +void LabelToStringComposer::Visit(void* userData, const LabelSetLabel& label) const { + std::ostream &out = *((std::ostream*) userData); out << '['; bool first = true; @@ -52,8 +49,8 @@ void LabelToStringComposer::Visit(void* userData, const LabelSetLabel& label) { out << ']'; } -void LabelToStringComposer::Visit(void* userData, const LabelPairLabel& label) { - std::stringstream &out = *((std::stringstream*) userData); +void LabelToStringComposer::Visit(void* userData, const LabelPairLabel& label) const { + std::ostream &out = *((std::ostream*) userData); out << '<'; label.getData().first.getData().Accept(userData, *this); @@ -62,8 +59,8 @@ void LabelToStringComposer::Visit(void* userData, const LabelPairLabel& label) { out << '>'; } -void LabelToStringComposer::Visit(void* userData, const UniqueLabel& label) { - std::stringstream &out = *((std::stringstream*) userData); +void LabelToStringComposer::Visit(void* userData, const UniqueLabel& label) const { + std::ostream &out = *((std::ostream*) userData); out << '<'; label.getLabel().getData().Accept(userData, *this); @@ -73,10 +70,8 @@ void LabelToStringComposer::Visit(void* userData, const UniqueLabel& label) { out << '>'; } -std::string LabelToStringComposer::compose(const Label& label) { - std::stringstream out; - label.getData().Accept((void*) &out, *this); - return std::move(out).str(); +void LabelToStringComposer::compose(std::ostream& output, const Label& label) const { + label.getData().Accept((void*) &output, *this); } } /* namespace label */ diff --git a/alib2data/src/label/LabelToStringComposer.h b/alib2data/src/label/LabelToStringComposer.h index 821f794af0..a70d52b61f 100644 --- a/alib2data/src/label/LabelToStringComposer.h +++ b/alib2data/src/label/LabelToStringComposer.h @@ -10,27 +10,26 @@ #include <sstream> #include "Label.h" -#include "../sax/Token.h" namespace label { /** * This class contains methods to print XML representation of string to the output stream. */ -class LabelToStringComposer : public VisitableLabelBase::visitor_type { - void Visit(void*, const PrimitiveLabel& label); - void Visit(void*, const HexavigesimalLabel& label); - void Visit(void*, const ObjectLabel& label); - void Visit(void*, const LabelSetLabel& label); - void Visit(void*, const LabelPairLabel& label); - void Visit(void*, const UniqueLabel& label); +class LabelToStringComposer : public VisitableLabelBase::const_visitor_type { + void Visit(void*, const PrimitiveLabel& label) const; + void Visit(void*, const HexavigesimalLabel& label) const; + void Visit(void*, const ObjectLabel& label) const; + void Visit(void*, const LabelSetLabel& label) const; + void Visit(void*, const LabelPairLabel& label) const; + void Visit(void*, const UniqueLabel& label) const; public: /** * Prints text representation of Label to the output stream. * @param string String to print * @param out output stream to which print the String */ - std::string compose(const Label& string); + void compose(std::ostream& output, const Label& string) const; }; } /* namespace label */ diff --git a/alib2data/src/primitive/PrimitiveFromStringLexer.cpp b/alib2data/src/primitive/PrimitiveFromStringLexer.cpp index e6420dc49a..1efbd67c38 100644 --- a/alib2data/src/primitive/PrimitiveFromStringLexer.cpp +++ b/alib2data/src/primitive/PrimitiveFromStringLexer.cpp @@ -9,90 +9,92 @@ namespace primitive { -PrimitiveFromStringLexer::PrimitiveFromStringLexer(std::istream& in) : m_In(in) { - m_Current.type = TokenType::ERROR; - m_Current.value = ""; -} - -PrimitiveFromStringLexer& PrimitiveFromStringLexer::next() { - if(m_Current.type == TokenType::TEOF) return *this; +PrimitiveFromStringLexer::Token PrimitiveFromStringLexer::next(std::istream& in) const { + PrimitiveFromStringLexer::Token token; + token.type = TokenType::ERROR; + token.value = ""; + token.raw = ""; char character; - m_Current.value = ""; L0: - character = m_In.get(); - if(m_In.eof()) { - m_Current.type = TokenType::TEOF; - return *this; + character = in.get(); + if(in.eof()) { + token.type = TokenType::TEOF; + return token; } else if(character == ' ' || character == '\n' || character == '\t') { + token.raw += character; goto L0; } else if((character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z')) { - m_Current.type = TokenType::CHAR; - m_Current.value += character; - return *this; + token.type = TokenType::CHAR; + token.value += character; + token.raw += character; + return token; } else if(character >= '0' && character <= '9') { - m_Current.type = TokenType::INTEGER; - m_Current.value += character; + token.type = TokenType::INTEGER; + token.value += character; + token.raw += character; goto L1; } else if(character == '\'') { - m_Current.type = TokenType::STRING; + token.type = TokenType::STRING; + token.raw += character; goto L3; } else { - m_In.putback(character); - while(!m_Current.value.empty()) { - m_In.putback(m_Current.value.back()); - m_Current.value.pop_back(); - } - m_In.clear(); - m_Current.type = TokenType::ERROR; - return *this; + in.putback(character); + putback(in, std::move(token)); + token.type = TokenType::ERROR; + return token; } L1: - character = m_In.get(); - if(m_In.eof()) { - return *this; + character = in.get(); + if(in.eof()) { + return token; } else if(character >= '0' && character <= '9') { - m_Current.value += character; + token.value += character; + token.raw += character; goto L1; } else { - m_In.unget(); - return *this; + in.unget(); + return token; } L3: - character = m_In.get(); - if(m_In.eof()) { - m_Current.type = TokenType::TEOF; - return *this; + character = in.get(); + if(in.eof()) { + token.type = TokenType::TEOF; + return token; } else if(character == '\'') { - return *this; + token.raw += character; + return token; } else if(character == '\\') { + token.raw += character; goto L4; } else { - m_Current.value += character; + token.value += character; + token.raw += character; goto L3; } L4: - character = m_In.get(); - if(m_In.eof()) { - m_Current.type = TokenType::TEOF; - return *this; + character = in.get(); + if(in.eof()) { + token.type = TokenType::TEOF; + return token; } else if(character == '\'' || character == '\\') { - m_Current.value += character; + token.value += character; + token.raw += character; goto L3; } else { - m_In.putback(character); - while(!m_Current.value.empty()) { - m_In.putback(m_Current.value.back()); - m_Current.value.pop_back(); - } - m_In.clear(); - m_Current.type = TokenType::ERROR; - return *this; + in.putback(character); + putback(in, std::move(token)); + token.type = TokenType::ERROR; + return token; } } -PrimitiveFromStringLexer::Token PrimitiveFromStringLexer::token() { - return m_Current; +void PrimitiveFromStringLexer::putback(std::istream& in, PrimitiveFromStringLexer::Token token) const { + while(!token.raw.empty()) { + in.putback(token.raw.back()); + token.raw.pop_back(); + } + in.clear(); } } /* namespace primitive */ diff --git a/alib2data/src/primitive/PrimitiveFromStringLexer.h b/alib2data/src/primitive/PrimitiveFromStringLexer.h index 3099bf57b5..035cbed24d 100644 --- a/alib2data/src/primitive/PrimitiveFromStringLexer.h +++ b/alib2data/src/primitive/PrimitiveFromStringLexer.h @@ -24,17 +24,13 @@ public: }; struct Token { - TokenType type; - std::string value; + TokenType type; + std::string value; + std::string raw; }; -private: - std::istream& m_In; - Token m_Current; -public: - PrimitiveFromStringLexer(std::istream&); - PrimitiveFromStringLexer& next(); - Token token(); + Token next(std::istream& input) const; + void putback(std::istream& input, Token token) const; }; } /* namespace primitive */ diff --git a/alib2data/src/primitive/PrimitiveFromStringParser.cpp b/alib2data/src/primitive/PrimitiveFromStringParser.cpp index edf381e18d..5989529167 100644 --- a/alib2data/src/primitive/PrimitiveFromStringParser.cpp +++ b/alib2data/src/primitive/PrimitiveFromStringParser.cpp @@ -14,16 +14,12 @@ namespace primitive { -PrimitiveFromStringParser::PrimitiveFromStringParser(std::istream& input) : m_Lexer(input) { - -} - -Primitive PrimitiveFromStringParser::parse() { - return parse(std::set<FEATURES>({FEATURES::STRING, FEATURES::CHAR, FEATURES::INTEGER})); +Primitive PrimitiveFromStringParser::parsePrimitive(std::istream& input) const { + return parsePrimitive(input, std::set<FEATURES>({FEATURES::STRING, FEATURES::CHAR, FEATURES::INTEGER})); } -Primitive PrimitiveFromStringParser::parse(const std::set<FEATURES>& features) { - PrimitiveFromStringLexer::Token token = m_Lexer.token(); +Primitive PrimitiveFromStringParser::parsePrimitive(std::istream& input, const std::set<FEATURES>& features) const { + PrimitiveFromStringLexer::Token token = m_Lexer.next(input); switch(token.type) { case PrimitiveFromStringLexer::TokenType::TEOF: throw exception::AlibException("Unexpected end of file"); @@ -39,34 +35,7 @@ Primitive PrimitiveFromStringParser::parse(const std::set<FEATURES>& features) { case PrimitiveFromStringLexer::TokenType::ERROR: break; } - throw exception::AlibException("Unrecognised input \"" + token.value + "\""); -} - -bool PrimitiveFromStringParser::next() { - PrimitiveFromStringLexer::Token token = m_Lexer.next().token(); - if(token.type == PrimitiveFromStringLexer::TokenType::STRING || token.type == PrimitiveFromStringLexer::TokenType::CHAR || token.type == PrimitiveFromStringLexer::TokenType::INTEGER) { - return true; - } else { - return false; - } -} - -bool PrimitiveFromStringParser::first() { - PrimitiveFromStringLexer::Token token = m_Lexer.next().token(); - if(token.type == PrimitiveFromStringLexer::TokenType::STRING || token.type == PrimitiveFromStringLexer::TokenType::CHAR || token.type == PrimitiveFromStringLexer::TokenType::INTEGER) { - return true; - } else { - return false; - } -} - -bool PrimitiveFromStringParser::last() { - PrimitiveFromStringLexer::Token token = m_Lexer.next().token(); - if(token.type == PrimitiveFromStringLexer::TokenType::TEOF) { - return true; - } else { - return false; - } + throw exception::AlibException("Unrecognised input \"" + token.value + "...\""); } } /* namespace primitive */ diff --git a/alib2data/src/primitive/PrimitiveFromStringParser.h b/alib2data/src/primitive/PrimitiveFromStringParser.h index 4814eb1933..f81c4b1cbe 100644 --- a/alib2data/src/primitive/PrimitiveFromStringParser.h +++ b/alib2data/src/primitive/PrimitiveFromStringParser.h @@ -11,36 +11,25 @@ #include "Primitive.h" #include "PrimitiveFeatures.h" #include <set> -#include "../FromStringParser.hpp" #include "PrimitiveFromStringLexer.h" -namespace label { +namespace alib { -class LabelFromStringParser; +template<typename T> +struct stringApi; -} /* namespace label */ - -namespace string { - -class StringFromStringParser; - -} /* namespace string */ +} /* namespace alib */ namespace primitive { -class PrimitiveFromStringParser : public alib::FromStringParser<Primitive, FEATURES> { +class PrimitiveFromStringParser { PrimitiveFromStringLexer m_Lexer; - virtual Primitive parse(const std::set<FEATURES>&); - virtual Primitive parse(); - - bool next(); - virtual bool last(); -public: - virtual bool first(); - PrimitiveFromStringParser(std::istream&); - friend class label::LabelFromStringParser; - friend class string::StringFromStringParser; + + Primitive parsePrimitive(std::istream&, const std::set<FEATURES>&) const; + Primitive parsePrimitive(std::istream&) const; + + template<typename T> friend class alib::stringApi; }; } /* namespace primitive */ diff --git a/alib2data/src/primitive/PrimitiveToStringComposer.cpp b/alib2data/src/primitive/PrimitiveToStringComposer.cpp index 7c0bfaa479..abfc428ca9 100644 --- a/alib2data/src/primitive/PrimitiveToStringComposer.cpp +++ b/alib2data/src/primitive/PrimitiveToStringComposer.cpp @@ -6,15 +6,14 @@ */ #include "PrimitiveToStringComposer.h" -#include <algorithm> #include "Integer.h" #include "String.h" #include "Character.h" namespace primitive { -void PrimitiveToStringComposer::Visit(void* userData, const primitive::String& primitive) { - std::stringstream &out = *((std::stringstream*) userData); +void PrimitiveToStringComposer::Visit(void* userData, const primitive::String& primitive) const { + std::ostream &out = *((std::ostream*) userData); auto replace = [](std::string& str, const std::string& what, const std::string& with) { size_t index = 0; @@ -29,22 +28,20 @@ void PrimitiveToStringComposer::Visit(void* userData, const primitive::String& p out << '\'' << tmp << '\''; } -void PrimitiveToStringComposer::Visit(void* userData, const Character& primitive) { - std::stringstream &out = *((std::stringstream*) userData); +void PrimitiveToStringComposer::Visit(void* userData, const Character& primitive) const { + std::ostream &out = *((std::ostream*) userData); out << primitive.getData(); } -void PrimitiveToStringComposer::Visit(void* userData, const Integer& primitive) { - std::stringstream &out = *((std::stringstream*) userData); +void PrimitiveToStringComposer::Visit(void* userData, const Integer& primitive) const { + std::ostream &out = *((std::ostream*) userData); out << primitive.getData(); } -std::string PrimitiveToStringComposer::compose(const Primitive& primitive) { - std::stringstream out; +void PrimitiveToStringComposer::compose(std::ostream& out, const Primitive& primitive) const { primitive.getData().Accept((void*) &out, *this); - return std::move(out).str(); } } /* namespace primitive */ diff --git a/alib2data/src/primitive/PrimitiveToStringComposer.h b/alib2data/src/primitive/PrimitiveToStringComposer.h index 387062009a..ce3106a289 100644 --- a/alib2data/src/primitive/PrimitiveToStringComposer.h +++ b/alib2data/src/primitive/PrimitiveToStringComposer.h @@ -8,26 +8,25 @@ #ifndef PRIMITIVE_TO_STRING_COMPOSER_H_ #define PRIMITIVE_TO_STRING_COMPOSER_H_ -#include <sstream> +#include <ostream> #include "Primitive.h" -#include "../sax/Token.h" namespace primitive { /** * This class contains methods to print XML representation of string to the output stream. */ -class PrimitiveToStringComposer : public VisitablePrimitiveBase::visitor_type { - void Visit(void*, const Integer& primitive); - void Visit(void*, const String& primitive); - void Visit(void*, const Character& primitive); +class PrimitiveToStringComposer : public VisitablePrimitiveBase::const_visitor_type { + void Visit(void*, const Integer& primitive) const; + void Visit(void*, const String& primitive) const; + void Visit(void*, const Character& primitive) const; public: /** * Prints text representation of Primitive to the output stream. * @param string String to print * @param out output stream to which print the String */ - std::string compose(const Primitive& string); + void compose(std::ostream& out, const Primitive& string) const; }; } /* namespace primitive */ diff --git a/alib2data/src/regexp/RegExpFromStringLexer.cpp b/alib2data/src/regexp/RegExpFromStringLexer.cpp index 4adb3c7aa7..a94ae35b53 100644 --- a/alib2data/src/regexp/RegExpFromStringLexer.cpp +++ b/alib2data/src/regexp/RegExpFromStringLexer.cpp @@ -9,79 +9,80 @@ namespace regexp { -RegExpFromStringLexer::RegExpFromStringLexer(std::istream& in) : m_In(in) { - m_Current.type = TokenType::ERROR; - m_Current.value = ""; -} - -RegExpFromStringLexer& RegExpFromStringLexer::next() { - if(m_Current.type == TokenType::TEOF) return *this; +RegExpFromStringLexer::Token RegExpFromStringLexer::next(std::istream& in) const { + RegExpFromStringLexer::Token token; + token.type = TokenType::ERROR; + token.value = ""; + token.raw = ""; char character; - m_Current.value = ""; L0: - character = m_In.get(); - if(m_In.eof()) { - m_Current.type = TokenType::TEOF; - return *this; + character = in.get(); + if(in.eof()) { + token.type = TokenType::TEOF; + return token; } else if(character == ' ' || character == '\n' || character == '\t') { + token.raw += character; goto L0; } else if(character == '(') { - m_Current.type = TokenType::LPAR; - m_Current.value += character; - return *this; + token.type = TokenType::LPAR; + token.value += character; + token.raw += character; + return token; } else if(character == ')') { - m_Current.type = TokenType::RPAR; - m_Current.value += character; - return *this; + token.type = TokenType::RPAR; + token.value += character; + token.raw += character; + return token; } else if(character == '+') { - m_Current.type = TokenType::PLUS; - m_Current.value += character; - return *this; + token.type = TokenType::PLUS; + token.value += character; + token.raw += character; + return token; } else if(character == '*') { - m_Current.type = TokenType::STAR; - m_Current.value += character; - return *this; + token.type = TokenType::STAR; + token.value += character; + token.raw += character; + return token; } else if(character == '#') { - m_Current.value += character; + token.value += character; + token.raw += character; goto L1; } else { - m_In.putback(character); - while(!m_Current.value.empty()) { - m_In.putback(m_Current.value.back()); - m_Current.value.pop_back(); - } - m_In.clear(); - m_Current.type = TokenType::ERROR; - return *this; + in.putback(character); + putback(in, std::move(token)); + token.type = TokenType::ERROR; + return token; } L1: - character = m_In.get(); - if(m_In.eof()) { - m_Current.type = TokenType::TEOF; - return *this; + character = in.get(); + if(in.eof()) { + token.type = TokenType::TEOF; + return token; } else if(character == 'E') { - m_Current.value += character; - m_Current.type = TokenType::EPS; - return *this; + token.type = TokenType::EPS; + token.value += character; + token.raw += character; + return token; } else if(character == '0') { - m_Current.value += character; - m_Current.type = TokenType::EMPTY; - return *this; + token.type = TokenType::EMPTY; + token.value += character; + token.raw += character; + return token; } else { - m_In.putback(character); - while(!m_Current.value.empty()) { - m_In.putback(m_Current.value.back()); - m_Current.value.pop_back(); - } - m_In.clear(); - m_Current.type = TokenType::ERROR; - return *this; + in.putback(character); + putback(in, std::move(token)); + token.type = TokenType::ERROR; + return token; } } -RegExpFromStringLexer::Token RegExpFromStringLexer::token() { - return m_Current; +void RegExpFromStringLexer::putback(std::istream& in, RegExpFromStringLexer::Token token) const { + while(!token.raw.empty()) { + in.putback(token.raw.back()); + token.raw.pop_back(); + } + in.clear(); } } /* namespace regexp */ diff --git a/alib2data/src/regexp/RegExpFromStringLexer.h b/alib2data/src/regexp/RegExpFromStringLexer.h index d6dfdc4fb8..748c3fca7e 100644 --- a/alib2data/src/regexp/RegExpFromStringLexer.h +++ b/alib2data/src/regexp/RegExpFromStringLexer.h @@ -16,28 +16,24 @@ namespace regexp { class RegExpFromStringLexer { public: enum class TokenType { - LPAR, - RPAR, - PLUS, - STAR, - EPS, - EMPTY, - TEOF, - ERROR + LPAR, + RPAR, + PLUS, + STAR, + EPS, + EMPTY, + TEOF, + ERROR }; struct Token { - TokenType type; - std::string value; + TokenType type; + std::string value; + std::string raw; }; -private: - std::istream& m_In; - Token m_Current; -public: - RegExpFromStringLexer(std::istream&); - RegExpFromStringLexer& next(); - Token token(); + Token next(std::istream& input) const; + void putback(std::istream&, Token token) const; }; } /* namespace regexp */ diff --git a/alib2data/src/regexp/RegExpFromStringParser.cpp b/alib2data/src/regexp/RegExpFromStringParser.cpp index 01f2b6fe1e..faa0aae08a 100644 --- a/alib2data/src/regexp/RegExpFromStringParser.cpp +++ b/alib2data/src/regexp/RegExpFromStringParser.cpp @@ -9,181 +9,147 @@ #include "../sax/ParserException.h" #include "../exception/AlibException.h" -namespace regexp { - -RegExpFromStringParser::RegExpFromStringParser(std::istream& input) : m_RegexpLexer(input), m_SymbolParser(input) { +#include "../StringApi.hpp" -} +namespace regexp { -RegExp RegExpFromStringParser::parse() { - return parse(std::set<FEATURES>({FEATURES::FORMAL, FEATURES::UNBOUNDED})); +RegExp RegExpFromStringParser::parseRegExp(std::istream& input) const { + return parseRegExp(input, std::set<FEATURES>({FEATURES::FORMAL, FEATURES::UNBOUNDED})); } -RegExp RegExpFromStringParser::parse(const std::set<FEATURES>& features) { - UnboundedRegExpElement* element = this->alternation(); +RegExp RegExpFromStringParser::parseRegExp(std::istream& input, const std::set<FEATURES>& features) const { + UnboundedRegExpElement* element = this->alternation(input); UnboundedRegExp regexp(std::move(*element)); delete element; if(features.count(FEATURES::UNBOUNDED)) return RegExp{regexp}; if(features.count(FEATURES::FORMAL)) return RegExp{FormalRegExp{regexp}}; - throw exception::AlibException(); + throw exception::AlibException("Invalid input"); } -bool RegExpFromStringParser::first() { - RegExpFromStringLexer::Token token = m_RegexpLexer.next().token(); - if(token.type == RegExpFromStringLexer::TokenType::EMPTY || token.type == RegExpFromStringLexer::TokenType::EPS || token.type == RegExpFromStringLexer::TokenType::LPAR) { - return true; - } else { - return token.type == RegExpFromStringLexer::TokenType::ERROR && m_SymbolParser.first(); - } +UnboundedRegExpElement* RegExpFromStringParser::alternation(std::istream& input) const { + return this->alternationCont(input, this->concatenation(input)); } -bool RegExpFromStringParser::next() { - RegExpFromStringLexer::Token token = m_RegexpLexer.next().token(); - if(token.type == RegExpFromStringLexer::TokenType::EMPTY || token.type == RegExpFromStringLexer::TokenType::EPS || token.type == RegExpFromStringLexer::TokenType::LPAR || token.type == RegExpFromStringLexer::TokenType::STAR || token.type == RegExpFromStringLexer::TokenType::RPAR || token.type == RegExpFromStringLexer::TokenType::PLUS) { - return true; - } else { - return false; - } -} - -bool RegExpFromStringParser::last() { - RegExpFromStringLexer::Token token = m_RegexpLexer.next().token(); - if(token.type == RegExpFromStringLexer::TokenType::TEOF) { - return true; - } else { - return false; - } -} - -UnboundedRegExpElement* RegExpFromStringParser::alternation() { - return this->alternationCont(this->concatenation()); -} - -UnboundedRegExpElement* RegExpFromStringParser::alternationCont(UnboundedRegExpElement* left) { - RegExpFromStringLexer::Token token = m_RegexpLexer.token(); +UnboundedRegExpElement* RegExpFromStringParser::alternationCont(std::istream& input, UnboundedRegExpElement* left) const { + RegExpFromStringLexer::Token token = m_RegexpLexer.next(input); if(token.type == RegExpFromStringLexer::TokenType::PLUS) { - next() || m_SymbolParser.first(); - try { - UnboundedRegExpElement* right = this->concatenation(); + UnboundedRegExpElement* right = this->concatenation(input); UnboundedRegExpAlternation* res = new UnboundedRegExpAlternation(); res->appendElement(std::move(*left)); res->appendElement(std::move(*right)); delete right; delete left; - left = NULL; - return this->alternationContCont(res); + return this->alternationContCont(input, res); } catch (...) { delete left; throw; } } else { + m_RegexpLexer.putback(input, token); return left; } } -UnboundedRegExpElement* RegExpFromStringParser::alternationContCont(UnboundedRegExpAlternation* res) { - RegExpFromStringLexer::Token token = m_RegexpLexer.token(); +UnboundedRegExpElement* RegExpFromStringParser::alternationContCont(std::istream& input, UnboundedRegExpAlternation* res) const { + RegExpFromStringLexer::Token token = m_RegexpLexer.next(input); if(token.type == RegExpFromStringLexer::TokenType::PLUS) { - next() || m_SymbolParser.first(); - try { - UnboundedRegExpElement* next = this->concatenation(); + UnboundedRegExpElement* next = this->concatenation(input); res->appendElement(std::move(*next)); delete next; - return this->alternationContCont(res); + return this->alternationContCont(input, res); } catch (...) { delete res; throw; } } else { + m_RegexpLexer.putback(input, token); return res; } } -UnboundedRegExpElement* RegExpFromStringParser::concatenation() { - return this->concatenationCont(this->factor()); +UnboundedRegExpElement* RegExpFromStringParser::concatenation(std::istream& input) const { + return this->concatenationCont(input, this->factor(input)); } -UnboundedRegExpElement* RegExpFromStringParser::concatenationCont(UnboundedRegExpElement* left) { - RegExpFromStringLexer::Token token = m_RegexpLexer.token(); +UnboundedRegExpElement* RegExpFromStringParser::concatenationCont(std::istream& input, UnboundedRegExpElement* left) const { + RegExpFromStringLexer::Token token = m_RegexpLexer.next(input); if(token.type == RegExpFromStringLexer::TokenType::ERROR || token.type == RegExpFromStringLexer::TokenType::LPAR || token.type == RegExpFromStringLexer::TokenType::EPS || token.type == RegExpFromStringLexer::TokenType::EMPTY) { - try { - UnboundedRegExpElement* right = this->factor(); + m_RegexpLexer.putback(input, token); + UnboundedRegExpElement* right = this->factor(input); UnboundedRegExpConcatenation* res = new UnboundedRegExpConcatenation(); res->appendElement(std::move(*left)); res->appendElement(std::move(*right)); delete right; delete left; - left = NULL; - return this->concatenationContCont(res); + return this->concatenationContCont(input, res); } catch (...) { delete left; throw; } } else { + m_RegexpLexer.putback(input, token); return left; } - throw exception::AlibException("Impossible"); + return NULL; //unreachable but produces warning if not present } -UnboundedRegExpElement* RegExpFromStringParser::concatenationContCont(UnboundedRegExpConcatenation* res) { - RegExpFromStringLexer::Token token = m_RegexpLexer.token(); +UnboundedRegExpElement* RegExpFromStringParser::concatenationContCont(std::istream& input, UnboundedRegExpConcatenation* res) const { + RegExpFromStringLexer::Token token = m_RegexpLexer.next(input); if(token.type == RegExpFromStringLexer::TokenType::ERROR || token.type == RegExpFromStringLexer::TokenType::LPAR || token.type == RegExpFromStringLexer::TokenType::EPS || token.type == RegExpFromStringLexer::TokenType::EMPTY) { - try { - UnboundedRegExpElement* next = this->factor(); + m_RegexpLexer.putback(input, token); + UnboundedRegExpElement* next = this->factor(input); res->appendElement(std::move(*next)); delete next; - return this->concatenationContCont(res); + return this->concatenationContCont(input, res); } catch (...) { delete res; throw; } } else { + m_RegexpLexer.putback(input, token); return res; } - throw exception::AlibException("Imúpssible"); + return NULL; //unreachable but produces warning if not present } -UnboundedRegExpElement* RegExpFromStringParser::factor() { - RegExpFromStringLexer::Token token = m_RegexpLexer.token(); +UnboundedRegExpElement* RegExpFromStringParser::factor(std::istream& input) const { + RegExpFromStringLexer::Token token = m_RegexpLexer.next(input); if(token.type == RegExpFromStringLexer::TokenType::LPAR) { - next() || m_SymbolParser.first(); - - UnboundedRegExpElement* base = this->alternation(); - token = m_RegexpLexer.token(); - if(token.type != RegExpFromStringLexer::TokenType::RPAR) throw exception::AlibException(); - return this->star(base); + UnboundedRegExpElement* base = this->alternation(input); + token = m_RegexpLexer.next(input); + if(token.type != RegExpFromStringLexer::TokenType::RPAR) throw exception::AlibException("Expected RPAR"); + return this->star(input, base); } else if(token.type == RegExpFromStringLexer::TokenType::EPS) { - return this->star(new UnboundedRegExpEpsilon()); + return this->star(input, new UnboundedRegExpEpsilon()); } else if(token.type == RegExpFromStringLexer::TokenType::EMPTY) { - return this->star(new UnboundedRegExpEmpty()); + return this->star(input, new UnboundedRegExpEmpty()); } else if(token.type == RegExpFromStringLexer::TokenType::ERROR) { - UnboundedRegExpSymbol* res = new UnboundedRegExpSymbol(m_SymbolParser.parse()); - return this->star(res); + UnboundedRegExpSymbol* res = new UnboundedRegExpSymbol(alib::stringApi<alphabet::Symbol>::parse(input)); + return this->star(input, res); } else { throw exception::AlibException("Unrecognised token at factor rule"); } } -UnboundedRegExpElement* RegExpFromStringParser::star(UnboundedRegExpElement* elem) { - next() || m_SymbolParser.first(); - - RegExpFromStringLexer::Token token = m_RegexpLexer.token(); +UnboundedRegExpElement* RegExpFromStringParser::star(std::istream& input, UnboundedRegExpElement* elem) const { + RegExpFromStringLexer::Token token = m_RegexpLexer.next(input); if(token.type == RegExpFromStringLexer::TokenType::STAR) { UnboundedRegExpIteration* iter = new UnboundedRegExpIteration(std::move(*elem)); delete elem; - return this->star(iter); + return this->star(input, iter); } else { + m_RegexpLexer.putback(input, token); return elem; } } diff --git a/alib2data/src/regexp/RegExpFromStringParser.h b/alib2data/src/regexp/RegExpFromStringParser.h index d400f0c7e1..c3554ac87c 100644 --- a/alib2data/src/regexp/RegExpFromStringParser.h +++ b/alib2data/src/regexp/RegExpFromStringParser.h @@ -13,35 +13,35 @@ #include "formal/FormalRegExpElements.h" #include "RegExpFromStringLexer.h" -#include "../alphabet/SymbolFromStringParser.h" #include "RegExpFeatures.h" -#include "../FromStringParser.hpp" + +namespace alib { + +template<typename T> +struct stringApi; + +} /* namespace alib */ namespace regexp { -class RegExpFromStringParser : public alib::FromStringParser<RegExp, FEATURES> { - UnboundedRegExpElement* alternation(); - UnboundedRegExpElement* alternationCont(UnboundedRegExpElement* left); - UnboundedRegExpElement* alternationContCont(UnboundedRegExpAlternation* left); - - UnboundedRegExpElement* concatenation(); - UnboundedRegExpElement* concatenationCont(UnboundedRegExpElement* left); - UnboundedRegExpElement* concatenationContCont(UnboundedRegExpConcatenation* left); - - UnboundedRegExpElement* factor(); - UnboundedRegExpElement* star(UnboundedRegExpElement* elem); +class RegExpFromStringParser { + UnboundedRegExpElement* alternation(std::istream& input) const; + UnboundedRegExpElement* alternationCont(std::istream& input, UnboundedRegExpElement* left) const; + UnboundedRegExpElement* alternationContCont(std::istream& input, UnboundedRegExpAlternation* left) const; + + UnboundedRegExpElement* concatenation(std::istream& input) const; + UnboundedRegExpElement* concatenationCont(std::istream& input, UnboundedRegExpElement* left) const; + UnboundedRegExpElement* concatenationContCont(std::istream& input, UnboundedRegExpConcatenation* left) const; + + UnboundedRegExpElement* factor(std::istream& input) const; + UnboundedRegExpElement* star(std::istream& input, UnboundedRegExpElement* elem) const; RegExpFromStringLexer m_RegexpLexer; - alphabet::SymbolFromStringParser m_SymbolParser; - virtual RegExp parse(); - virtual RegExp parse(const std::set<FEATURES>& features); - bool next(); - virtual bool last(); -public: - virtual bool first(); - RegExpFromStringParser(std::istream&); + RegExp parseRegExp(std::istream& input) const; + RegExp parseRegExp(std::istream& input, const std::set<FEATURES>& features) const; + template<typename T> friend class alib::stringApi; }; } /* namespace regexp */ diff --git a/alib2data/src/regexp/RegExpToStringComposer.cpp b/alib2data/src/regexp/RegExpToStringComposer.cpp index 90ab9a633d..48c7398d7b 100644 --- a/alib2data/src/regexp/RegExpToStringComposer.cpp +++ b/alib2data/src/regexp/RegExpToStringComposer.cpp @@ -5,107 +5,105 @@ * Author: Martin Zak */ -#include <sstream> #include <algorithm> #include "RegExpToStringComposer.h" -#include "../alphabet/SymbolToStringComposer.h" +#include "../StringApi.hpp" namespace regexp { -void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExp& regexp) { +void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExp& regexp) const { regexp.getRegExp().Accept(userData, *this); } -void RegExpToStringComposer::Visit(void* userData, const FormalRegExp& regexp) { +void RegExpToStringComposer::Visit(void* userData, const FormalRegExp& regexp) const { regexp.getRegExp().Accept(userData, *this); } -void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpAlternation& alternation) { - std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); +void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpAlternation& alternation) const { + std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); if(alternation.getElements().size() == 0) { - out.second << "#0"; + std::get<1>(out) << "#0"; } else if(alternation.getElements().size() == 1) { const auto& element = alternation.getElements()[0]; const UnboundedRegExpElement& object = static_cast<const UnboundedRegExpElement&>(*element); object.Accept(userData, *this); } else { - Priority outerPriorityMinimum = out.first; - if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) out.second << '('; + Priority outerPriorityMinimum = std::get<0>(out); + if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << '('; bool first = true; for (const auto& element : alternation.getElements()) { if(first) { first = false; } else { - out.second << '+'; + std::get<1>(out) << '+'; } const UnboundedRegExpElement& object = static_cast<const UnboundedRegExpElement&>(*element); - out.first = Priority::ALTERNATION; + std::get<0>(out) = Priority::ALTERNATION; object.Accept(userData, *this); } - if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) out.second << ')'; + if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << ')'; } } -void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpConcatenation& concatenation) { - std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); +void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpConcatenation& concatenation) const { + std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); - Priority outerPriorityMinimum = out.first; + Priority outerPriorityMinimum = std::get<0>(out); if(concatenation.getElements().size() == 0) { - out.second << "#E"; + std::get<1>(out) << "#E"; } else if(concatenation.getElements().size() == 1) { const auto& element = concatenation.getElements()[0]; const UnboundedRegExpElement& object = static_cast<const UnboundedRegExpElement&>(*element); object.Accept(userData, *this); } else { - if(outerPriorityMinimum == Priority::FACTOR) out.second << '('; + if(outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << '('; bool first = true; for (auto element : concatenation.getElements()) { if(first) first = false; else - out.second << ' '; + std::get<1>(out) << ' '; const UnboundedRegExpElement& object = static_cast<const UnboundedRegExpElement&>(*element); - out.first = Priority::CONCATENATION; + std::get<0>(out) = Priority::CONCATENATION; object.Accept(userData, *this); } - if(outerPriorityMinimum == Priority::FACTOR) out.second << ')'; + if(outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << ')'; } } -void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpIteration& iteration) { - std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); +void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpIteration& iteration) const { + std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); const UnboundedRegExpElement& object = static_cast<const UnboundedRegExpElement&>(iteration.getElement()); - out.first = Priority::FACTOR; + std::get<0>(out) = Priority::FACTOR; object.Accept(userData, *this); - out.second << "*"; + std::get<1>(out) << "*"; } -void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpSymbol& symbol) { - std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); - - alphabet::SymbolToStringComposer composer; - out.second << composer.compose(symbol.getSymbol()); +void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpSymbol& symbol) const { + std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); + + alib::stringApi<alphabet::Symbol>::compose(std::get<1>(out), symbol.getSymbol()); } -void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpEpsilon&) { - std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); - out.second << "#E"; +void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpEpsilon&) const { + std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); + std::get<1>(out) << "#E"; } -void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpEmpty&) { - std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); - out.second << "#0"; +void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpEmpty&) const { + std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); + std::get<1>(out) << "#0"; } -void RegExpToStringComposer::Visit(void* userData, const FormalRegExpAlternation& alternation) { - std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); +void RegExpToStringComposer::Visit(void* userData, const FormalRegExpAlternation& alternation) const { + std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); - Priority outerPriorityMinimum = out.first; - if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) out.second << '('; + Priority outerPriorityMinimum = std::get<0>(out); + if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << '('; - out.first = Priority::ALTERNATION; + std::get<0>(out) = Priority::ALTERNATION; { const auto& element = alternation.getLeftElement(); @@ -113,7 +111,7 @@ void RegExpToStringComposer::Visit(void* userData, const FormalRegExpAlternation object.Accept(userData, *this); } - out.second << '+'; + std::get<1>(out) << '+'; { const auto& element = alternation.getRightElement(); @@ -121,16 +119,16 @@ void RegExpToStringComposer::Visit(void* userData, const FormalRegExpAlternation object.Accept(userData, *this); } - if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) out.second << ')'; + if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << ')'; } -void RegExpToStringComposer::Visit(void* userData, const FormalRegExpConcatenation& concatenation) { - std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); +void RegExpToStringComposer::Visit(void* userData, const FormalRegExpConcatenation& concatenation) const { + std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); - Priority outerPriorityMinimum = out.first; - if(outerPriorityMinimum == Priority::FACTOR) out.second << '('; + Priority outerPriorityMinimum = std::get<0>(out); + if(outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << '('; - out.first = Priority::CONCATENATION; + std::get<0>(out) = Priority::CONCATENATION; { const auto& element = concatenation.getLeftElement(); @@ -138,7 +136,7 @@ void RegExpToStringComposer::Visit(void* userData, const FormalRegExpConcatenati object.Accept(userData, *this); } - out.second << ' '; + std::get<1>(out) << ' '; { const auto& element = concatenation.getRightElement(); @@ -146,40 +144,38 @@ void RegExpToStringComposer::Visit(void* userData, const FormalRegExpConcatenati object.Accept(userData, *this); } - if(outerPriorityMinimum == Priority::FACTOR) out.second << ')'; + if(outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << ')'; } -void RegExpToStringComposer::Visit(void* userData, const FormalRegExpIteration& iteration) { - std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); +void RegExpToStringComposer::Visit(void* userData, const FormalRegExpIteration& iteration) const { + std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); const FormalRegExpElement& object = static_cast<const FormalRegExpElement&>(iteration.getElement()); - out.first = Priority::FACTOR; + std::get<0>(out) = Priority::FACTOR; object.Accept(userData, *this); - out.second << "*"; + std::get<1>(out) << "*"; } -void RegExpToStringComposer::Visit(void* userData, const FormalRegExpSymbol& symbol) { - std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); - - alphabet::SymbolToStringComposer composer; - out.second << composer.compose(symbol.getSymbol()); +void RegExpToStringComposer::Visit(void* userData, const FormalRegExpSymbol& symbol) const { + std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); + + alib::stringApi<alphabet::Symbol>::compose(std::get<1>(out), symbol.getSymbol()); } -void RegExpToStringComposer::Visit(void* userData, const FormalRegExpEpsilon&) { - std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); - out.second << "#E"; +void RegExpToStringComposer::Visit(void* userData, const FormalRegExpEpsilon&) const { + std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); + std::get<1>(out) << "#E"; } -void RegExpToStringComposer::Visit(void* userData, const FormalRegExpEmpty&) { - std::pair<Priority, std::stringstream> &out = *((std::pair<Priority, std::stringstream>*) userData); - out.second << "#0"; +void RegExpToStringComposer::Visit(void* userData, const FormalRegExpEmpty&) const { + std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); + std::get<1>(out) << "#0"; } -std::string RegExpToStringComposer::compose(const RegExp& regexp) { - std::pair<Priority, std::stringstream> out; - out.first = Priority::ALTERNATION; +void RegExpToStringComposer::compose(std::ostream& output, const RegExp& regexp) const { + Priority tmp = Priority::ALTERNATION; + std::tuple<Priority&, std::ostream&> out = std::tie(tmp, output); regexp.getData().Accept((void*) &out, *this); - return std::move(out.second).str(); } } /* namespace regexp */ diff --git a/alib2data/src/regexp/RegExpToStringComposer.h b/alib2data/src/regexp/RegExpToStringComposer.h index 104f049881..1bcee37647 100644 --- a/alib2data/src/regexp/RegExpToStringComposer.h +++ b/alib2data/src/regexp/RegExpToStringComposer.h @@ -15,25 +15,25 @@ namespace regexp { -class RegExpToStringComposer : public VisitableRegExpBase::visitor_type, UnboundedRegExpElement::visitor_type, FormalRegExpElement::visitor_type { - void Visit(void*, const UnboundedRegExpAlternation& alternation); - void Visit(void*, const UnboundedRegExpConcatenation& concatenation); - void Visit(void*, const UnboundedRegExpIteration& iteration); - void Visit(void*, const UnboundedRegExpSymbol& symbol); - void Visit(void*, const UnboundedRegExpEpsilon& epsilon); - void Visit(void*, const UnboundedRegExpEmpty& empty); +class RegExpToStringComposer : public VisitableRegExpBase::const_visitor_type, UnboundedRegExpElement::const_visitor_type, FormalRegExpElement::const_visitor_type { + void Visit(void*, const UnboundedRegExpAlternation& alternation) const; + void Visit(void*, const UnboundedRegExpConcatenation& concatenation) const; + void Visit(void*, const UnboundedRegExpIteration& iteration) const; + void Visit(void*, const UnboundedRegExpSymbol& symbol) const; + void Visit(void*, const UnboundedRegExpEpsilon& epsilon) const; + void Visit(void*, const UnboundedRegExpEmpty& empty) const; - void Visit(void*, const FormalRegExpAlternation& alternation); - void Visit(void*, const FormalRegExpConcatenation& concatenation); - void Visit(void*, const FormalRegExpIteration& iteration); - void Visit(void*, const FormalRegExpSymbol& symbol); - void Visit(void*, const FormalRegExpEpsilon& epsilon); - void Visit(void*, const FormalRegExpEmpty& empty); + void Visit(void*, const FormalRegExpAlternation& alternation) const; + void Visit(void*, const FormalRegExpConcatenation& concatenation) const; + void Visit(void*, const FormalRegExpIteration& iteration) const; + void Visit(void*, const FormalRegExpSymbol& symbol) const; + void Visit(void*, const FormalRegExpEpsilon& epsilon) const; + void Visit(void*, const FormalRegExpEmpty& empty) const; - void Visit(void*, const UnboundedRegExp& empty); - void Visit(void*, const FormalRegExp& empty); + void Visit(void*, const UnboundedRegExp& empty) const; + void Visit(void*, const FormalRegExp& empty) const; enum class Priority { @@ -47,7 +47,7 @@ public: * @param regexp RegExp to print * @returns string representation of regexp */ - std::string compose(const RegExp& regexp); + void compose(std::ostream& out, const RegExp& regexp) const; }; } /* namespace regexp */ diff --git a/alib2data/src/string/StringFromStringLexer.cpp b/alib2data/src/string/StringFromStringLexer.cpp index c2a21e5817..956d5a3a55 100644 --- a/alib2data/src/string/StringFromStringLexer.cpp +++ b/alib2data/src/string/StringFromStringLexer.cpp @@ -9,71 +9,71 @@ namespace string { -StringFromStringLexer::StringFromStringLexer(std::istream& in) : m_In(in) { - m_Current.type = TokenType::ERROR; - m_Current.value = ""; -} - -StringFromStringLexer& StringFromStringLexer::next() { - if(m_Current.type == TokenType::TEOF) return *this; +StringFromStringLexer::Token StringFromStringLexer::next(std::istream& in) const { + StringFromStringLexer::Token token; + token.type = TokenType::ERROR; + token.value = ""; + token.raw = ""; char character; - m_Current.value = ""; L0: - character = m_In.get(); - if(m_In.eof()) { - m_Current.type = TokenType::TEOF; - return *this; + character = in.get(); + if(in.eof()) { + token.type = TokenType::TEOF; + return token; } else if(character == ' ' || character == '\n' || character == '\t') { + token.raw += character; goto L0; } else if(character == '<') { - m_Current.type = TokenType::LESS; - m_Current.value += character; - return *this; + token.type = TokenType::LESS; + token.value += character; + token.raw += character; + return token; } else if(character == '>') { - m_Current.type = TokenType::GREATER; - m_Current.value += character; - return *this; + token.type = TokenType::GREATER; + token.value += character; + token.raw += character; + return token; } else if(character == '"') { - m_Current.type = TokenType::QUOTE; - m_Current.value += character; - return *this; + token.type = TokenType::QUOTE; + token.value += character; + token.raw += character; + return token; } else if(character == '#') { - m_Current.value += character; + token.value += character; + token.raw += character; goto L1; } else { - m_In.putback(character); - while(!m_Current.value.empty()) { - m_In.putback(m_Current.value.back()); - m_Current.value.pop_back(); - } - m_In.clear(); - m_Current.type = TokenType::ERROR; - return *this; + in.putback(character); + putback(in, std::move(token)); + in.clear(); + token.type = TokenType::ERROR; + return token; } L1: - character = m_In.get(); - if(m_In.eof()) { - m_Current.type = TokenType::TEOF; - return *this; + character = in.get(); + if(in.eof()) { + token.type = TokenType::TEOF; + return token; } else if(character == 'E') { - m_Current.value += character; - m_Current.type = TokenType::EPSILON; - return *this; + token.type = TokenType::EPSILON; + token.value += character; + token.raw += character; + return token; } else { - m_In.putback(character); - while(!m_Current.value.empty()) { - m_In.putback(m_Current.value.back()); - m_Current.value.pop_back(); - } - m_In.clear(); - m_Current.type = TokenType::ERROR; - return *this; + in.putback(character); + putback(in, std::move(token)); + token.type = TokenType::ERROR; + return token; } } -StringFromStringLexer::Token StringFromStringLexer::token() { - return m_Current; +void StringFromStringLexer::putback(std::istream& in, StringFromStringLexer::Token token) const { + while(!token.raw.empty()) { + in.putback(token.raw.back()); + token.raw.pop_back(); + } + in.clear(); } } /* namespace string */ diff --git a/alib2data/src/string/StringFromStringLexer.h b/alib2data/src/string/StringFromStringLexer.h index 9b870c8908..da069f2995 100644 --- a/alib2data/src/string/StringFromStringLexer.h +++ b/alib2data/src/string/StringFromStringLexer.h @@ -10,7 +10,6 @@ #include <string> #include <sstream> -#include "../label/LabelFromStringLexer.h" namespace string { @@ -26,17 +25,13 @@ public: }; struct Token { - TokenType type; - std::string value; + TokenType type; + std::string value; + std::string raw; }; -private: - std::istream& m_In; - Token m_Current; -public: - - StringFromStringLexer(std::istream&); - StringFromStringLexer& next(); - Token token(); + + Token next(std::istream& input) const; + void putback(std::istream&, Token token) const; }; } /* namespace string */ diff --git a/alib2data/src/string/StringFromStringParser.cpp b/alib2data/src/string/StringFromStringParser.cpp index d0b5bdcfc8..a86d81be4c 100644 --- a/alib2data/src/string/StringFromStringParser.cpp +++ b/alib2data/src/string/StringFromStringParser.cpp @@ -10,80 +10,55 @@ #include "Epsilon.h" #include "LinearString.h" #include "CyclicString.h" +#include <vector> -namespace string { - -StringFromStringParser::StringFromStringParser(std::istream& input) : m_StringLexer(input), m_SymbolParser(input) { +#include "../StringApi.hpp" -} +namespace string { -String StringFromStringParser::parse() { - return parse(std::set<FEATURES>({FEATURES::LINEAR, FEATURES::CYCLIC, FEATURES::EPSILON})); +String StringFromStringParser::parseString(std::istream& input) const { + return parseString(input, std::set<FEATURES>({FEATURES::LINEAR, FEATURES::CYCLIC, FEATURES::EPSILON})); } -String StringFromStringParser::parse(const std::set<FEATURES>& features) { - StringFromStringLexer::Token token = m_StringLexer.token(); +String StringFromStringParser::parseString(std::istream& input, const std::set<FEATURES>& features) const { + StringFromStringLexer::Token token = m_StringLexer.next(input); if(token.type == StringFromStringLexer::TokenType::EPSILON) { if(!features.count(FEATURES::EPSILON)) throw exception::AlibException(); return String(Epsilon()); } else if(token.type == StringFromStringLexer::TokenType::LESS) { if(!features.count(FEATURES::CYCLIC)) throw exception::AlibException(); - std::vector<alphabet::Symbol> data = parseContent(); + std::vector<alphabet::Symbol> data = parseContent(input); + token = m_StringLexer.next(input); if(token.type == StringFromStringLexer::TokenType::GREATER) { return String(CyclicString(data)); } else { - throw exception::AlibException(); + throw exception::AlibException("Invalid cyclic string terminating character"); } } else if(token.type == StringFromStringLexer::TokenType::QUOTE) { if(!features.count(FEATURES::LINEAR)) throw exception::AlibException(); - std::vector<alphabet::Symbol> data = parseContent(); + std::vector<alphabet::Symbol> data = parseContent(input); + token = m_StringLexer.next(input); if(token.type == StringFromStringLexer::TokenType::QUOTE) { return String(LinearString(data)); } else { - throw exception::AlibException(); + throw exception::AlibException("Invalid liner string terminating character"); } } else { throw exception::AlibException(); } } -bool StringFromStringParser::first() { - StringFromStringLexer::Token token = m_StringLexer.next().token(); - if(token.type == StringFromStringLexer::TokenType::EPSILON || token.type == StringFromStringLexer::TokenType::LESS || token.type == StringFromStringLexer::TokenType::QUOTE) { - return true; - } else { - return false; - } -} - -bool StringFromStringParser::next() { - StringFromStringLexer::Token token = m_StringLexer.next().token(); - if(token.type == StringFromStringLexer::TokenType::EPSILON || token.type == StringFromStringLexer::TokenType::LESS || token.type == StringFromStringLexer::TokenType::QUOTE || token.type == StringFromStringLexer::TokenType::GREATER) { - return true; - } else { - return false; - } -} - -bool StringFromStringParser::last() { - StringFromStringLexer::Token token = m_StringLexer.next().token(); - if(token.type == StringFromStringLexer::TokenType::TEOF) { - return true; - } else { - return false; - } -} - -std::vector<alphabet::Symbol> StringFromStringParser::parseContent() { +std::vector<alphabet::Symbol> StringFromStringParser::parseContent(std::istream& input) const { std::vector<alphabet::Symbol> data; - do { - next() || m_SymbolParser.next() || m_SymbolParser.m_LabelParser.next() || m_SymbolParser.m_LabelParser.m_PrimitiveParser.next(); + StringFromStringLexer::Token token = m_StringLexer.next(input); + while(token.type != StringFromStringLexer::TokenType::GREATER && token.type != StringFromStringLexer::TokenType::QUOTE) { + m_StringLexer.putback(input, token); + data.push_back(alib::stringApi<alphabet::Symbol>::parse(input)); - StringFromStringLexer::Token token = m_StringLexer.token(); - if(token.type == StringFromStringLexer::TokenType::GREATER || token.type == StringFromStringLexer::TokenType::QUOTE) - return data; - data.push_back(m_SymbolParser.parse()); - } while(true); + token = m_StringLexer.next(input); + } + m_StringLexer.putback(input, token); + return data; } } /* namespace string */ diff --git a/alib2data/src/string/StringFromStringParser.h b/alib2data/src/string/StringFromStringParser.h index 3d6c446a76..46e35acacc 100644 --- a/alib2data/src/string/StringFromStringParser.h +++ b/alib2data/src/string/StringFromStringParser.h @@ -10,29 +10,26 @@ #include "String.h" #include "StringFeatures.h" -#include <vector> -#include "../alphabet/Symbol.h" - #include "StringFromStringLexer.h" -#include "../alphabet/SymbolFromStringParser.h" -#include "../FromStringParser.hpp" + +namespace alib { + +template<typename T> +struct stringApi; + +} /* namespace alib */ namespace string { -class StringFromStringParser : public alib::FromStringParser<String, FEATURES> { - std::vector<alphabet::Symbol> parseContent(); - +class StringFromStringParser { + std::vector<alphabet::Symbol> parseContent(std::istream&) const; + StringFromStringLexer m_StringLexer; - alphabet::SymbolFromStringParser m_SymbolParser; - virtual String parse(); - virtual String parse(const std::set<FEATURES>& features); - bool next(); - virtual bool last(); -public: - virtual bool first(); - StringFromStringParser(std::istream&); + String parseString(std::istream&) const; + String parseString(std::istream&, const std::set<FEATURES>& features) const; + template<typename T> friend class alib::stringApi; }; } /* namespace string */ diff --git a/alib2data/src/string/StringToStringComposer.cpp b/alib2data/src/string/StringToStringComposer.cpp index 0d16950c4f..e4e63edfeb 100644 --- a/alib2data/src/string/StringToStringComposer.cpp +++ b/alib2data/src/string/StringToStringComposer.cpp @@ -6,46 +6,41 @@ */ #include "StringToStringComposer.h" -#include <algorithm> -#include "../alphabet/Symbol.h" -#include "../alphabet/SymbolToStringComposer.h" #include "CyclicString.h" #include "LinearString.h" +#include "../StringApi.hpp" + namespace string { -void StringToStringComposer::Visit(void* userData, const CyclicString& string) { - std::stringstream &out = *((std::stringstream*) userData); +void StringToStringComposer::Visit(void* userData, const CyclicString& string) const { + std::ostream &out = *((std::ostream*) userData); out << "<"; for(const auto& symbol : string.getContent()) { - alphabet::SymbolToStringComposer composer; - out << composer.compose(symbol); + alib::stringApi<alphabet::Symbol>::compose(out, symbol); } out << ">"; } -void StringToStringComposer::Visit(void* userData, const LinearString& string) { - std::stringstream &out = *((std::stringstream*) userData); +void StringToStringComposer::Visit(void* userData, const LinearString& string) const { + std::ostream &out = *((std::ostream*) userData); out << "\""; for(const auto& symbol : string.getContent()) { - alphabet::SymbolToStringComposer composer; - out << composer.compose(symbol); + alib::stringApi<alphabet::Symbol>::compose(out, symbol); } out << "\""; } -void StringToStringComposer::Visit(void* userData, const Epsilon&) { - std::stringstream &out = *((std::stringstream*) userData); +void StringToStringComposer::Visit(void* userData, const Epsilon&) const { + std::ostream &out = *((std::ostream*) userData); out << "#E"; } -std::string StringToStringComposer::compose(const String& string) { - std::stringstream out; +void StringToStringComposer::compose(std::ostream& out, const String& string) const { string.getData().Accept((void*) &out, *this); - return std::move(out).str(); } } /* namespace string */ diff --git a/alib2data/src/string/StringToStringComposer.h b/alib2data/src/string/StringToStringComposer.h index 41c1b9e081..ee6e929bcd 100644 --- a/alib2data/src/string/StringToStringComposer.h +++ b/alib2data/src/string/StringToStringComposer.h @@ -8,27 +8,25 @@ #ifndef STRING_TO_STRING_COMPOSER_H_ #define STRING_TO_STRING_COMPOSER_H_ -#include <sstream> +#include <ostream> #include "String.h" -#include "../sax/Token.h" -#include "../alphabet/Symbol.h" namespace string { /** * This class contains methods to print XML representation of string to the output stream. */ -class StringToStringComposer : public VisitableStringBase::visitor_type { - void Visit(void*, const LinearString& string); - void Visit(void*, const CyclicString& string); - void Visit(void*, const Epsilon& string); +class StringToStringComposer : public VisitableStringBase::const_visitor_type { + void Visit(void*, const LinearString& string) const; + void Visit(void*, const CyclicString& string) const; + void Visit(void*, const Epsilon& string) const; public: /** * Prints XML representation of String to the output stream. * @param string String to print * @param out output stream to which print the String */ - std::string compose(const String& string); + void compose(std::ostream& output, const String& string) const; }; } /* namespace string */ diff --git a/alib2data/test-src/alphabet/SymbolTest.cpp b/alib2data/test-src/alphabet/SymbolTest.cpp index cc991b1314..5c5ba508a9 100644 --- a/alib2data/test-src/alphabet/SymbolTest.cpp +++ b/alib2data/test-src/alphabet/SymbolTest.cpp @@ -7,12 +7,9 @@ #include "alphabet/Symbol.h" #include "alphabet/LabeledSymbol.h" #include "alphabet/BlankSymbol.h" -#include "alphabet/SymbolFromStringParser.h" -#include "alphabet/SymbolToStringComposer.h" -#include "alphabet/SymbolFromXMLParser.h" -#include "alphabet/SymbolToXMLComposer.h" #include "factory/DataFactory.hpp" +#include "factory/StringDataFactory.hpp" #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) #define CPPUNIT_EXCLUSIVE_OR(x, y) CPPUNIT_ASSERT((!(x) && (y)) || ((x) && !(y))) @@ -40,55 +37,37 @@ void SymbolTest::testCopyConstruct() { void SymbolTest::testEqual() { { std::string input = "a"; - std::stringstream inputs(input); + alphabet::Symbol symbol = alib::StringDataFactory::fromString<alphabet::Symbol>(input); - alphabet::SymbolFromStringParser parser(inputs); - alphabet::Symbol symbol = parser.parseValue(); - - alphabet::SymbolToStringComposer composer; - std::string output = composer.compose(symbol); - std::stringstream outputs(output); + std::string output = alib::StringDataFactory::toString(symbol); CPPUNIT_ASSERT( input == output ); - alphabet::SymbolFromStringParser parser2(outputs); - alphabet::Symbol symbol2 = parser2.parseValue(); + alphabet::Symbol symbol2 = alib::StringDataFactory::fromString<alphabet::Symbol>(output); CPPUNIT_ASSERT( symbol == symbol2 ); } { std::string input = "'aaaa'"; - std::stringstream inputs(input); - - alphabet::SymbolFromStringParser parser(inputs); - alphabet::Symbol symbol = parser.parseValue(); + alphabet::Symbol symbol = alib::StringDataFactory::fromString<alphabet::Symbol>(input); - alphabet::SymbolToStringComposer composer; - std::string output = composer.compose(symbol); - std::stringstream outputs(output); + std::string output = alib::StringDataFactory::toString(symbol); CPPUNIT_ASSERT( input == output ); - alphabet::SymbolFromStringParser parser2(outputs); - alphabet::Symbol symbol2 = parser2.parseValue(); + alphabet::Symbol symbol2 = alib::StringDataFactory::fromString<alphabet::Symbol>(output); CPPUNIT_ASSERT( symbol == symbol2 ); } { std::string input = "#B"; - std::stringstream inputs(input); - - alphabet::SymbolFromStringParser parser(inputs); - alphabet::Symbol symbol = parser.parseValue(); + alphabet::Symbol symbol = alib::StringDataFactory::fromString<alphabet::Symbol>(input); - alphabet::SymbolToStringComposer composer; - std::string output = composer.compose(symbol); - std::stringstream outputs(output); + std::string output = alib::StringDataFactory::toString(symbol); CPPUNIT_ASSERT( input == output ); - alphabet::SymbolFromStringParser parser2(outputs); - alphabet::Symbol symbol2 = parser2.parseValue(); + alphabet::Symbol symbol2 = alib::StringDataFactory::fromString<alphabet::Symbol>(output); CPPUNIT_ASSERT( symbol == symbol2 ); } diff --git a/alib2data/test-src/automaton/AutomatonTest.cpp b/alib2data/test-src/automaton/AutomatonTest.cpp index d243e543dc..666dd62ae4 100644 --- a/alib2data/test-src/automaton/AutomatonTest.cpp +++ b/alib2data/test-src/automaton/AutomatonTest.cpp @@ -8,12 +8,11 @@ #include "automaton/FSM/ExtendedNFA.h" #include "automaton/PDA/SinglePopDPDA.h" #include "automaton/PDA/DPDA.h" -#include "automaton/AutomatonFromXMLParser.h" -#include "automaton/AutomatonToXMLComposer.h" #include "automaton/AutomatonException.h" #include "factory/DataFactory.hpp" +#include "factory/StringDataFactory.hpp" #include "alphabet/LabeledSymbol.h" @@ -21,9 +20,6 @@ #include "regexp/unbounded/UnboundedRegExp.h" #include "regexp/unbounded/UnboundedRegExpElements.h" -#include "automaton/FSM/FiniteAutomatonFromStringParser.h" -#include "automaton/FSM/FiniteAutomatonToStringComposer.h" - #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) CPPUNIT_TEST_SUITE_REGISTRATION( AutomatonTest ); @@ -71,19 +67,31 @@ void AutomatonTest::FSMStringParserTest() { "3 - - 4 - -\n" "4 - 5 - - 5\n" "<5 - - - - 3\n"; - std::stringstream inputs(input); + automaton::Automaton automaton = alib::StringDataFactory::fromString<automaton::Automaton>(input); + + std::string output = alib::StringDataFactory::toString(automaton); - automaton::FiniteAutomatonFromStringParser parser(inputs); - automaton::Automaton automaton = parser.parseValue(); + CPPUNIT_ASSERT( input == output ); - automaton::FiniteAutomatonToStringComposer composer; - std::string output = composer.compose(automaton); - std::stringstream outputs(output); + automaton::Automaton automaton2 = alib::StringDataFactory::fromString<automaton::Automaton>(output); + + CPPUNIT_ASSERT( automaton == automaton2 ); + } + { + std::string input = "MISNFA a b c d\n" + ">0 3|4 5 1|3|4 -\n" + "1 2 - - -\n" + "2 3 - - -\n" + ">3 - - 4 -\n" + "4 - 5 - -\n" + "<5 - - - 3\n"; + automaton::Automaton automaton = alib::StringDataFactory::fromString<automaton::Automaton>(input); + + std::string output = alib::StringDataFactory::toString(automaton); CPPUNIT_ASSERT( input == output ); - automaton::FiniteAutomatonFromStringParser parser2(outputs); - automaton::Automaton automaton2 = parser2.parseValue(); + automaton::Automaton automaton2 = alib::StringDataFactory::fromString<automaton::Automaton>(output); CPPUNIT_ASSERT( automaton == automaton2 ); } @@ -95,19 +103,13 @@ void AutomatonTest::FSMStringParserTest() { "3 - - 4 -\n" "4 - 5 - -\n" "<5 - - - 3\n"; - std::stringstream inputs(input); - - automaton::FiniteAutomatonFromStringParser parser(inputs); - automaton::Automaton automaton = parser.parseValue(); + automaton::Automaton automaton = alib::StringDataFactory::fromString<automaton::Automaton>(input); - automaton::FiniteAutomatonToStringComposer composer; - std::string output = composer.compose(automaton); - std::stringstream outputs(output); + std::string output = alib::StringDataFactory::toString(automaton); CPPUNIT_ASSERT( input == output ); - automaton::FiniteAutomatonFromStringParser parser2(outputs); - automaton::Automaton automaton2 = parser2.parseValue(); + automaton::Automaton automaton2 = alib::StringDataFactory::fromString<automaton::Automaton>(output); CPPUNIT_ASSERT( automaton == automaton2 ); } @@ -119,19 +121,13 @@ void AutomatonTest::FSMStringParserTest() { "3 - - 4 -\n" "4 - 5 - -\n" "<5 - - - 3\n"; - std::stringstream inputs(input); - - automaton::FiniteAutomatonFromStringParser parser(inputs); - automaton::Automaton automaton = parser.parseValue(); + automaton::Automaton automaton = alib::StringDataFactory::fromString<automaton::Automaton>(input); - automaton::FiniteAutomatonToStringComposer composer; - std::string output = composer.compose(automaton); - std::stringstream outputs(output); + std::string output = alib::StringDataFactory::toString(automaton); CPPUNIT_ASSERT( input == output ); - automaton::FiniteAutomatonFromStringParser parser2(outputs); - automaton::Automaton automaton2 = parser2.parseValue(); + automaton::Automaton automaton2 = alib::StringDataFactory::fromString<automaton::Automaton>(output); CPPUNIT_ASSERT( automaton == automaton2 ); } diff --git a/alib2data/test-src/grammar/GrammarTest.cpp b/alib2data/test-src/grammar/GrammarTest.cpp index 14381991b1..66b0c2c9f3 100644 --- a/alib2data/test-src/grammar/GrammarTest.cpp +++ b/alib2data/test-src/grammar/GrammarTest.cpp @@ -5,16 +5,11 @@ #include "sax/SaxComposeInterface.h" #include "grammar/Unrestricted/UnrestrictedGrammar.h" -#include "grammar/GrammarFromXMLParser.h" -#include "grammar/GrammarToXMLComposer.h" #include "factory/DataFactory.hpp" #include "alphabet/LabeledSymbol.h" -#include "grammar/GrammarFromStringParser.h" -#include "grammar/GrammarToStringComposer.h" - #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) CPPUNIT_TEST_SUITE_REGISTRATION( GrammarTest ); diff --git a/alib2data/test-src/label/LabelTest.cpp b/alib2data/test-src/label/LabelTest.cpp index 45680f3128..3e9fcb426c 100644 --- a/alib2data/test-src/label/LabelTest.cpp +++ b/alib2data/test-src/label/LabelTest.cpp @@ -6,16 +6,13 @@ #include "label/Label.h" #include "label/PrimitiveLabel.h" -#include "label/LabelFromStringParser.h" -#include "label/LabelToStringComposer.h" -#include "label/LabelFromXMLParser.h" -#include "label/LabelToXMLComposer.h" #include "primitive/Integer.h" #include "primitive/Character.h" #include "primitive/String.h" #include "factory/DataFactory.hpp" +#include "factory/StringDataFactory.hpp" #include <algorithm> #define CPPUNIT_EXCLUSIVE_OR(x, y) CPPUNIT_ASSERT((!(x) && (y)) || ((x) && !(y))) @@ -43,73 +40,49 @@ void LabelTest::testCopyConstruct() { void LabelTest::testEqual() { { std::string input = "1"; - std::stringstream inputs(input); + label::Label label = alib::StringDataFactory::fromString<label::Label>(input); - label::LabelFromStringParser parser(inputs); - label::Label label = parser.parseValue(); - - label::LabelToStringComposer composer; - std::string output = composer.compose(label); - std::stringstream outputs(output); + std::string output = alib::StringDataFactory::toString(label); CPPUNIT_ASSERT( input == output ); - label::LabelFromStringParser parser2(outputs); - label::Label label2 = parser2.parseValue(); + label::Label label2 = alib::StringDataFactory::fromString<label::Label>(output); CPPUNIT_ASSERT( label == label2 ); } { std::string input = "'aaaa'"; - std::stringstream inputs(input); - - label::LabelFromStringParser parser(inputs); - label::Label label = parser.parseValue(); + label::Label label = alib::StringDataFactory::fromString<label::Label>(input); - label::LabelToStringComposer composer; - std::string output = composer.compose(label); - std::stringstream outputs(output); + std::string output = alib::StringDataFactory::toString(label); CPPUNIT_ASSERT( input == output ); - label::LabelFromStringParser parser2(outputs); - label::Label label2 = parser2.parseValue(); + label::Label label2 = alib::StringDataFactory::fromString<label::Label>(output); CPPUNIT_ASSERT( label == label2 ); } { std::string input = "[1, 2, 3]"; - std::stringstream inputs(input); + label::Label label = alib::StringDataFactory::fromString<label::Label>(input); - label::LabelFromStringParser parser(inputs); - label::Label label = parser.parseValue(); - - label::LabelToStringComposer composer; - std::string output = composer.compose(label); - std::stringstream outputs(output); + std::string output = alib::StringDataFactory::toString(label); CPPUNIT_ASSERT( input == output ); - label::LabelFromStringParser parser2(outputs); - label::Label label2 = parser2.parseValue(); + label::Label label2 = alib::StringDataFactory::fromString<label::Label>(output); CPPUNIT_ASSERT( label == label2 ); } { std::string input = "<1, 2>"; - std::stringstream inputs(input); - - label::LabelFromStringParser parser(inputs); - label::Label label = parser.parseValue(); + label::Label label = alib::StringDataFactory::fromString<label::Label>(input); - label::LabelToStringComposer composer; - std::string output = composer.compose(label); - std::stringstream outputs(output); + std::string output = alib::StringDataFactory::toString(label); CPPUNIT_ASSERT( input == output ); - label::LabelFromStringParser parser2(outputs); - label::Label label2 = parser2.parseValue(); + label::Label label2 = alib::StringDataFactory::fromString<label::Label>(output); CPPUNIT_ASSERT( label == label2 ); } diff --git a/alib2data/test-src/regexp/RegExpTest.cpp b/alib2data/test-src/regexp/RegExpTest.cpp index 3fafc00927..06dcc5f7e9 100644 --- a/alib2data/test-src/regexp/RegExpTest.cpp +++ b/alib2data/test-src/regexp/RegExpTest.cpp @@ -5,12 +5,9 @@ #include "sax/SaxComposeInterface.h" #include "regexp/unbounded/UnboundedRegExp.h" -#include "regexp/RegExpFromStringParser.h" -#include "regexp/RegExpToStringComposer.h" -#include "regexp/RegExpFromXMLParser.h" -#include "regexp/RegExpToXMLComposer.h" #include "factory/DataFactory.hpp" +#include "factory/StringDataFactory.hpp" #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) #define CPPUNIT_EXCLUSIVE_OR(x, y) CPPUNIT_ASSERT((!(x) && (y)) || ((x) && !(y))) @@ -77,55 +74,38 @@ void RegExpTest::testCopyConstruct() { void RegExpTest::testEqual() { { std::string input = "#E* #0*"; - std::stringstream inputs(input); + regexp::RegExp regexp = alib::StringDataFactory::fromString<regexp::RegExp>(input); - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp regexp = parser.parseValue(); - - regexp::RegExpToStringComposer composer; - std::string output = composer.compose(regexp); - std::stringstream outputs(output); + std::string output = alib::StringDataFactory::toString(regexp); CPPUNIT_ASSERT( input == output ); - regexp::RegExpFromStringParser parser2(outputs); - regexp::RegExp regexp2 = parser2.parseValue(); + regexp::RegExp regexp2 = alib::StringDataFactory::fromString<regexp::RegExp>(output); CPPUNIT_ASSERT( regexp == regexp2 ); } { std::string input = "a+a"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp regexp = parser.parseValue(); + regexp::RegExp regexp = alib::StringDataFactory::fromString<regexp::RegExp>(input); - regexp::RegExpToStringComposer composer; - std::string output = composer.compose(regexp); - std::stringstream outputs(output); + std::string output = alib::StringDataFactory::toString(regexp); CPPUNIT_ASSERT( input == output ); - regexp::RegExpFromStringParser parser2(outputs); - regexp::RegExp regexp2 = parser2.parseValue(); + regexp::RegExp regexp2 = alib::StringDataFactory::fromString<regexp::RegExp>(output); CPPUNIT_ASSERT( regexp == regexp2 ); } { std::string input = "a+a (b+a)*"; - std::stringstream inputs(input); - - regexp::RegExpFromStringParser parser(inputs); - regexp::RegExp regexp = parser.parseValue(); + regexp::RegExp regexp = alib::StringDataFactory::fromString<regexp::RegExp>(input); - regexp::RegExpToStringComposer composer; - std::string output = composer.compose(regexp); - std::stringstream outputs(output); + std::string output = alib::StringDataFactory::toString(regexp); CPPUNIT_ASSERT( input == output ); + std::cout << output << std::endl; - regexp::RegExpFromStringParser parser2(outputs); - regexp::RegExp regexp2 = parser2.parseValue(); + regexp::RegExp regexp2 = alib::StringDataFactory::fromString<regexp::RegExp>(output); CPPUNIT_ASSERT( regexp == regexp2 ); } diff --git a/alib2data/test-src/string/StringTest.cpp b/alib2data/test-src/string/StringTest.cpp index dfe0f6b401..bb8e086564 100644 --- a/alib2data/test-src/string/StringTest.cpp +++ b/alib2data/test-src/string/StringTest.cpp @@ -8,12 +8,9 @@ #include "string/LinearString.h" #include "string/CyclicString.h" #include "string/Epsilon.h" -#include "string/StringFromStringParser.h" -#include "string/StringToStringComposer.h" -#include "string/StringFromXMLParser.h" -#include "string/StringToXMLComposer.h" #include "factory/DataFactory.hpp" +#include "factory/StringDataFactory.hpp" #include "alphabet/Symbol.h" #include "alphabet/LabeledSymbol.h" @@ -46,55 +43,37 @@ void StringTest::testCopyConstruct() { void StringTest::testEqual() { { std::string input = "\"aa\""; - std::stringstream inputs(input); + string::String string = alib::StringDataFactory::fromString<string::String>(input); - string::StringFromStringParser parser(inputs); - string::String string = parser.parseValue(); - - string::StringToStringComposer composer; - std::string output = composer.compose(string); - std::stringstream outputs(output); + std::string output = alib::StringDataFactory::toString(string); CPPUNIT_ASSERT( input == output ); - string::StringFromStringParser parser2(outputs); - string::String string2 = parser2.parseValue(); + string::String string2 = alib::StringDataFactory::fromString<string::String>(output); CPPUNIT_ASSERT( string == string2 ); } { std::string input = "\"'aaaa''aaa'\""; - std::stringstream inputs(input); - - string::StringFromStringParser parser(inputs); - string::String string = parser.parseValue(); + string::String string = alib::StringDataFactory::fromString<string::String>(input); - string::StringToStringComposer composer; - std::string output = composer.compose(string); - std::stringstream outputs(output); + std::string output = alib::StringDataFactory::toString(string); CPPUNIT_ASSERT( input == output ); - string::StringFromStringParser parser2(outputs); - string::String string2 = parser2.parseValue(); + string::String string2 = alib::StringDataFactory::fromString<string::String>(output); CPPUNIT_ASSERT( string == string2 ); } { std::string input = "#E"; - std::stringstream inputs(input); - - string::StringFromStringParser parser(inputs); - string::String string = parser.parseValue(); + string::String string = alib::StringDataFactory::fromString<string::String>(input); - string::StringToStringComposer composer; - std::string output = composer.compose(string); - std::stringstream outputs(output); + std::string output = alib::StringDataFactory::toString(string); CPPUNIT_ASSERT( input == output ); - string::StringFromStringParser parser2(outputs); - string::String string2 = parser2.parseValue(); + string::String string2 = alib::StringDataFactory::fromString<string::String>(output); CPPUNIT_ASSERT( string == string2 ); } -- GitLab