From 184d1e6e66002cdda52419d95f882ffaa9842364 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Tue, 3 Oct 2017 16:39:18 +0200 Subject: [PATCH] improve automata string parsers --- .../automaton/AutomatonFromStringLexer.cpp | 41 ++++++++++++++++--- .../src/automaton/AutomatonFromStringLexer.h | 10 ++++- alib2str/src/automaton/string/FSM/DFA.h | 5 +-- .../src/automaton/string/FSM/EpsilonNFA.h | 5 +-- .../string/FSM/MultiInitialStateNFA.h | 5 +-- alib2str/src/automaton/string/FSM/NFA.h | 5 +-- 6 files changed, 47 insertions(+), 24 deletions(-) diff --git a/alib2str/src/automaton/AutomatonFromStringLexer.cpp b/alib2str/src/automaton/AutomatonFromStringLexer.cpp index 839fe6ec8f..8e1401147e 100644 --- a/alib2str/src/automaton/AutomatonFromStringLexer.cpp +++ b/alib2str/src/automaton/AutomatonFromStringLexer.cpp @@ -6,6 +6,8 @@ */ #include "AutomatonFromStringLexer.h" +#include <exception/CommonException.h> +#include <iterator> namespace automaton { @@ -75,7 +77,7 @@ L0: return token; } else { in.clear(); - putback(in, std::move(token)); + putback(in, token); token.type = TokenType::ERROR; return token; } @@ -92,19 +94,46 @@ L1: } else { in.clear ( ); in.unget ( ); - putback(in, std::move(token)); + putback(in, token); token.type = TokenType::ERROR; return token; } } -void AutomatonFromStringLexer::putback(std::istream& in, AutomatonFromStringLexer::Token token) { +AutomatonFromStringLexer::Token AutomatonFromStringLexer::peek ( std::istream & in ) { + Token token = next ( in ); + putback ( in, token ); + return token; +} + +void AutomatonFromStringLexer::putback ( std::istream& in, const std::string & data ) { in.clear(); - while(!token.raw.empty()) { - in.putback(token.raw.back()); - token.raw.pop_back(); + for ( char character : ext::make_reverse ( data ) ) + in.putback ( character ); +} + +void AutomatonFromStringLexer::putback ( std::istream& in, const Token & token ) { + putback ( in, token.raw ); +} + +bool AutomatonFromStringLexer::test ( std::istream & in, const std::string & value ) { + if ( testAndConsume ( in, value ) ) { + in.clear ( ); + putback ( in, value ); + return true; + } else { + return false; } } +bool AutomatonFromStringLexer::testAndConsume ( std::istream & in, const std::string & value ) { + return ( bool ) ( in >> ext::string ( value ) ); +} + +void AutomatonFromStringLexer::consume ( std::istream & in, const std::string & value ) { + if ( ! testAndConsume ( in, value ) ) + throw exception::CommonException ( "Can't consume " + value + " from input stream." ); +} + } /* namespace automaton */ diff --git a/alib2str/src/automaton/AutomatonFromStringLexer.h b/alib2str/src/automaton/AutomatonFromStringLexer.h index cca67001b4..077480a67a 100644 --- a/alib2str/src/automaton/AutomatonFromStringLexer.h +++ b/alib2str/src/automaton/AutomatonFromStringLexer.h @@ -36,8 +36,14 @@ public: std::string raw; }; - static Token next(std::istream& input); - static void putback(std::istream&, Token token); + static Token next(std::istream & input); + static Token peek(std::istream & input); + static void putback ( std::istream&, const std::string & token); + static void putback ( std::istream&, const Token & token); + + static bool test ( std::istream & input, const std::string & value ); + static void consume ( std::istream & input, const std::string & value ); + static bool testAndConsume ( std::istream & input, const std::string & value ); }; } /* namepsace automaton */ diff --git a/alib2str/src/automaton/string/FSM/DFA.h b/alib2str/src/automaton/string/FSM/DFA.h index 145846aa13..3bfae51c1d 100644 --- a/alib2str/src/automaton/string/FSM/DFA.h +++ b/alib2str/src/automaton/string/FSM/DFA.h @@ -123,10 +123,7 @@ void stringApi < automaton::DFA < SymbolType, StateType > >::parseTransition(std template<class SymbolType, class StateType > bool stringApi < automaton::DFA < SymbolType, StateType > >::first ( std::istream & input ) { - automaton::AutomatonFromStringLexer::Token token = automaton::AutomatonFromStringLexer::next ( input ); - bool res = token.type == automaton::AutomatonFromStringLexer::TokenType::DFA; - automaton::AutomatonFromStringLexer::putback ( input, token ); - return res; + return automaton::AutomatonFromStringLexer::peek ( input ).type == automaton::AutomatonFromStringLexer::TokenType::DFA; } template<class SymbolType, class StateType > diff --git a/alib2str/src/automaton/string/FSM/EpsilonNFA.h b/alib2str/src/automaton/string/FSM/EpsilonNFA.h index 71e93d520a..ae651b0625 100644 --- a/alib2str/src/automaton/string/FSM/EpsilonNFA.h +++ b/alib2str/src/automaton/string/FSM/EpsilonNFA.h @@ -132,10 +132,7 @@ void stringApi < automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > >: template<class SymbolType, class EpsilonType, class StateType > bool stringApi < automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > >::first ( std::istream & input ) { - automaton::AutomatonFromStringLexer::Token token = automaton::AutomatonFromStringLexer::next ( input ); - bool res = token.type == automaton::AutomatonFromStringLexer::TokenType::EPSILON_NFA; - automaton::AutomatonFromStringLexer::putback ( input, token ); - return res; + return automaton::AutomatonFromStringLexer::peek ( input ).type == automaton::AutomatonFromStringLexer::TokenType::EPSILON_NFA; } template<class SymbolType, class EpsilonType, class StateType > diff --git a/alib2str/src/automaton/string/FSM/MultiInitialStateNFA.h b/alib2str/src/automaton/string/FSM/MultiInitialStateNFA.h index f1e6c1d895..d680cbf1f2 100644 --- a/alib2str/src/automaton/string/FSM/MultiInitialStateNFA.h +++ b/alib2str/src/automaton/string/FSM/MultiInitialStateNFA.h @@ -104,10 +104,7 @@ void stringApi < automaton::MultiInitialStateNFA < SymbolType, StateType > >::pa template<class SymbolType, class StateType > bool stringApi < automaton::MultiInitialStateNFA < SymbolType, StateType > >::first ( std::istream & input ) { - automaton::AutomatonFromStringLexer::Token token = automaton::AutomatonFromStringLexer::next ( input ); - bool res = token.type == automaton::AutomatonFromStringLexer::TokenType::MULTI_INITIAL_STATE_NFA; - automaton::AutomatonFromStringLexer::putback ( input, token ); - return res; + return automaton::AutomatonFromStringLexer::peek ( input ).type == automaton::AutomatonFromStringLexer::TokenType::MULTI_INITIAL_STATE_NFA; } template<class SymbolType, class StateType > diff --git a/alib2str/src/automaton/string/FSM/NFA.h b/alib2str/src/automaton/string/FSM/NFA.h index f490f74fb0..1934aae330 100644 --- a/alib2str/src/automaton/string/FSM/NFA.h +++ b/alib2str/src/automaton/string/FSM/NFA.h @@ -124,10 +124,7 @@ void stringApi < automaton::NFA < SymbolType, StateType > >::parseTransition(std template<class SymbolType, class StateType > bool stringApi < automaton::NFA < SymbolType, StateType > >::first ( std::istream & input ) { - automaton::AutomatonFromStringLexer::Token token = automaton::AutomatonFromStringLexer::next ( input ); - bool res = token.type == automaton::AutomatonFromStringLexer::TokenType::NFA; - automaton::AutomatonFromStringLexer::putback ( input, token ); - return res; + return automaton::AutomatonFromStringLexer::peek ( input ).type == automaton::AutomatonFromStringLexer::TokenType::NFA; } template<class SymbolType, class StateType > -- GitLab