From 40ad032e8cd6d13ed27853d1660c1091a65d4472 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Sun, 20 Sep 2015 21:28:21 +0200 Subject: [PATCH] parse trees from string representation --- aconvert2/src/aconvert.cpp | 274 +++++++++++---------- alib2str/src/StringApi.cpp | 73 +++--- alib2str/src/StringApi.hpp | 79 +++--- alib2str/src/tree/TreeFromStringLexer.cpp | 90 +++++++ alib2str/src/tree/TreeFromStringLexer.h | 34 +++ alib2str/src/tree/TreeFromStringParser.cpp | 103 ++++++++ alib2str/src/tree/TreeFromStringParser.h | 44 ++++ alib2str/src/tree/TreeToStringComposer.cpp | 18 ++ alib2str/src/tree/TreeToStringComposer.h | 40 +++ 9 files changed, 562 insertions(+), 193 deletions(-) create mode 100644 alib2str/src/tree/TreeFromStringLexer.cpp create mode 100644 alib2str/src/tree/TreeFromStringLexer.h create mode 100644 alib2str/src/tree/TreeFromStringParser.cpp create mode 100644 alib2str/src/tree/TreeFromStringParser.h create mode 100644 alib2str/src/tree/TreeToStringComposer.cpp create mode 100644 alib2str/src/tree/TreeToStringComposer.h diff --git a/aconvert2/src/aconvert.cpp b/aconvert2/src/aconvert.cpp index f1369ee304..1989751617 100644 --- a/aconvert2/src/aconvert.cpp +++ b/aconvert2/src/aconvert.cpp @@ -8,7 +8,6 @@ #include <tclap/CmdLine.h> #include <fstream> -#include "automaton/Automaton.h" #include "factory/XmlDataFactory.hpp" #include "factory/StringDataFactory.hpp" #include "exception/AlibException.h" @@ -16,199 +15,224 @@ #include "DotConverter.h" #include "GasTexConverter.h" -void automatonFromString(std::istream& in, std::ostream& out) { - automaton::Automaton automaton = alib::StringDataFactory::fromStream<automaton::Automaton>(in); +void automatonFromString ( std::istream & in, std::ostream & out ) { + automaton::Automaton automaton = alib::StringDataFactory::fromStream < automaton::Automaton > ( in ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::XmlDataFactory::toStream( automaton, out); + alib::XmlDataFactory::toStream ( automaton, out ); } -void grammarFromString(std::istream& in, std::ostream& out) { - grammar::Grammar grammar = alib::StringDataFactory::fromStream<grammar::Grammar>(in); +void grammarFromString ( std::istream & in, std::ostream & out ) { + grammar::Grammar grammar = alib::StringDataFactory::fromStream < grammar::Grammar > ( in ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::XmlDataFactory::toStream( grammar, out); + alib::XmlDataFactory::toStream ( grammar, out ); } -void regexpFromString(std::istream& in, std::ostream& out) { - regexp::RegExp regexp = alib::StringDataFactory::fromStream<regexp::RegExp>(in); +void regexpFromString ( std::istream & in, std::ostream & out ) { + regexp::RegExp regexp = alib::StringDataFactory::fromStream < regexp::RegExp > ( in ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::XmlDataFactory::toStream( regexp, out ); + alib::XmlDataFactory::toStream ( regexp, out ); } -void stringFromString(std::istream& in, std::ostream& out) { - string::String string = alib::StringDataFactory::fromStream<string::String>(in); +void stringFromString ( std::istream & in, std::ostream & out ) { + string::String string = alib::StringDataFactory::fromStream < string::String > ( in ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::XmlDataFactory::toStream(string, out); + alib::XmlDataFactory::toStream ( string, out ); } -void automatonToString(std::istream& in, std::ostream& out) { - automaton::Automaton automaton = alib::XmlDataFactory::fromStream<automaton::Automaton>(in); +void treeFromString ( std::istream & in, std::ostream & out ) { + tree::Tree tree = alib::StringDataFactory::fromStream < tree::Tree > ( in ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::StringDataFactory::toStream( automaton, out); + alib::XmlDataFactory::toStream ( tree, out ); } -void grammarToString(std::istream& in, std::ostream& out) { - grammar::Grammar grammar = alib::XmlDataFactory::fromStream<grammar::Grammar>(in); +void automatonToString ( std::istream & in, std::ostream & out ) { + automaton::Automaton automaton = alib::XmlDataFactory::fromStream < automaton::Automaton > ( in ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::StringDataFactory::toStream( grammar, out); + alib::StringDataFactory::toStream ( automaton, out ); } -void regexpToString(std::istream& in, std::ostream& out) { - regexp::RegExp regexp = alib::XmlDataFactory::fromStream<regexp::RegExp>(in); +void grammarToString ( std::istream & in, std::ostream & out ) { + grammar::Grammar grammar = alib::XmlDataFactory::fromStream < grammar::Grammar > ( in ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::StringDataFactory::toStream( regexp, out); + alib::StringDataFactory::toStream ( grammar, out ); } -void stringToString(std::istream& in, std::ostream& out) { - string::String string = alib::XmlDataFactory::fromStream<string::String>(in); +void regexpToString ( std::istream & in, std::ostream & out ) { + regexp::RegExp regexp = alib::XmlDataFactory::fromStream < regexp::RegExp > ( in ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::StringDataFactory::toStream( string, out); + alib::StringDataFactory::toStream ( regexp, out ); } -void automatonToDot(std::istream& in, std::ostream& out) { - automaton::Automaton automaton = alib::XmlDataFactory::fromStream<automaton::Automaton>(in); +void stringToString ( std::istream & in, std::ostream & out ) { + string::String string = alib::XmlDataFactory::fromStream < string::String > ( in ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - DotConverter::convert(out, automaton); + alib::StringDataFactory::toStream ( string, out ); } -void automatonToGasTex(std::istream& in, std::ostream& out) { - automaton::Automaton automaton = alib::XmlDataFactory::fromStream<automaton::Automaton>(in); +void treeToString ( std::istream & in, std::ostream & out ) { + tree::Tree tree = alib::XmlDataFactory::fromStream < tree::Tree > ( in ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - GasTexConverter::convert(out, automaton); + alib::StringDataFactory::toStream ( tree, out ); } -int main(int argc, char* argv[]) { +void automatonToDot ( std::istream & in, std::ostream & out ) { + automaton::Automaton automaton = alib::XmlDataFactory::fromStream < automaton::Automaton > ( in ); + + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); + + DotConverter::convert ( out, automaton ); +} + +void automatonToGasTex ( std::istream & in, std::ostream & out ) { + automaton::Automaton automaton = alib::XmlDataFactory::fromStream < automaton::Automaton > ( in ); + + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); + + GasTexConverter::convert ( out, automaton ); +} + +int main ( int argc, char * argv[] ) { try { - TCLAP::CmdLine cmd("Convert binary", ' ', "0.01"); + TCLAP::CmdLine cmd ( "Convert binary", ' ', "0.01" ); - TCLAP::SwitchArg automaton_from_string( "", "automaton_from_string", "Convert automaton from string representation"); - cmd.add( automaton_from_string ); + TCLAP::SwitchArg automaton_from_string ( "", "automaton_from_string", "Convert automaton from string representation" ); + cmd.add ( automaton_from_string ); - TCLAP::SwitchArg automaton_to_string( "", "automaton_to_string", "Convert automaton to string representation"); - cmd.add( automaton_to_string ); + TCLAP::SwitchArg automaton_to_string ( "", "automaton_to_string", "Convert automaton to string representation" ); + cmd.add ( automaton_to_string ); - TCLAP::SwitchArg automaton_to_dot( "", "automaton_to_dot", "Convert automaton to dot representation"); - cmd.add( automaton_to_dot ); + TCLAP::SwitchArg automaton_to_dot ( "", "automaton_to_dot", "Convert automaton to dot representation" ); + cmd.add ( automaton_to_dot ); - TCLAP::SwitchArg automaton_to_gastex( "", "automaton_to_gastex", "Convert automaton to gastex representation"); - cmd.add( automaton_to_gastex ); + TCLAP::SwitchArg automaton_to_gastex ( "", "automaton_to_gastex", "Convert automaton to gastex representation" ); + cmd.add ( automaton_to_gastex ); - TCLAP::SwitchArg grammar_from_string( "", "grammar_from_string", "Convert grammar from string representation"); - cmd.add( grammar_from_string ); + TCLAP::SwitchArg grammar_from_string ( "", "grammar_from_string", "Convert grammar from string representation" ); + cmd.add ( grammar_from_string ); - TCLAP::SwitchArg grammar_to_string( "", "grammar_to_string", "Convert grammar to string representation"); - cmd.add( grammar_to_string ); + TCLAP::SwitchArg grammar_to_string ( "", "grammar_to_string", "Convert grammar to string representation" ); + cmd.add ( grammar_to_string ); - TCLAP::SwitchArg regexp_from_string( "", "regexp_from_string", "Convert regexp from string representation"); - cmd.add( regexp_from_string ); + TCLAP::SwitchArg regexp_from_string ( "", "regexp_from_string", "Convert regexp from string representation" ); + cmd.add ( regexp_from_string ); - TCLAP::SwitchArg regexp_to_string( "", "regexp_to_string", "Convert regexp to string representation"); - cmd.add( regexp_to_string ); + TCLAP::SwitchArg regexp_to_string ( "", "regexp_to_string", "Convert regexp to string representation" ); + cmd.add ( regexp_to_string ); - TCLAP::SwitchArg string_from_string( "", "string_from_string", "Convert string from string representation"); - cmd.add( string_from_string ); + TCLAP::SwitchArg string_from_string ( "", "string_from_string", "Convert string from string representation" ); + cmd.add ( string_from_string ); - TCLAP::SwitchArg string_to_string( "","string_to_string", "Convert string to string representation"); - cmd.add( string_to_string ); + TCLAP::SwitchArg string_to_string ( "", "string_to_string", "Convert string to string representation" ); + cmd.add ( string_to_string ); - TCLAP::ValueArg<std::string> input( "i", "input", "Input file", false, "-", "file"); - cmd.add( input ); + TCLAP::SwitchArg tree_from_string ( "", "tree_from_string", "Convert tree from string representation" ); + cmd.add ( tree_from_string ); - TCLAP::SwitchArg measure( "m", "measure", "Measure times", false); - cmd.add( measure ); + TCLAP::SwitchArg tree_to_string ( "", "tree_to_string", "Convert tree to string representation" ); + cmd.add ( tree_to_string ); - TCLAP::SwitchArg verbose( "v", "verbose", "Be verbose", false); - cmd.add( verbose ); + TCLAP::ValueArg < std::string > input ( "i", "input", "Input file", false, "-", "file" ); + cmd.add ( input ); - cmd.parse(argc, argv); + TCLAP::SwitchArg measure ( "m", "measure", "Measure times", false ); + cmd.add ( measure ); - std::chrono::measurements::start("Overal", std::chrono::measurements::Type::OVERALL); - std::chrono::measurements::start("Input read", std::chrono::measurements::Type::AUXILARY); + TCLAP::SwitchArg verbose ( "v", "verbose", "Be verbose", false ); + cmd.add ( verbose ); - std::istream* in = NULL; - if(input.isSet()) { - if(input.getValue() == "-") { - in = &std::cin; - } else { - in = new std::ifstream(input.getValue()); - } - } else { - in = &std::cin; - } + cmd.parse ( argc, argv ); + + std::chrono::measurements::start ( "Overal", std::chrono::measurements::Type::OVERALL ); + std::chrono::measurements::start ( "Input read", std::chrono::measurements::Type::AUXILARY ); + + std::istream * in = NULL; - if(automaton_from_string.getValue()) { - automatonFromString(*in, std::cout); - } else if(automaton_to_string.getValue()) { - automatonToString(*in, std::cout); - } else if(automaton_to_dot.getValue()) { - automatonToDot(*in, std::cout); - } else if(automaton_to_gastex.getValue()) { - automatonToGasTex(*in, std::cout); - } else if(grammar_from_string.getValue()) { - grammarFromString(*in, std::cout); - } else if(grammar_to_string.getValue()) { - grammarToString(*in, std::cout); - } else if(regexp_from_string.getValue()) { - regexpFromString(*in, std::cout); - } else if(regexp_to_string.getValue()) { - regexpToString(*in, std::cout); - } else if(string_from_string.getValue()) { - stringFromString(*in, std::cout); - } else if(string_to_string.getValue()) { - stringToString(*in, std::cout); + if ( input.isSet ( ) ) { + if ( input.getValue ( ) == "-" ) + in = & std::cin; + else + in = new std::ifstream ( input.getValue ( ) ); + } else { + in = & std::cin; } - if(input.isSet() && input.getValue() != "-") { + if ( automaton_from_string.getValue ( ) ) + automatonFromString ( * in, std::cout ); + else if ( automaton_to_string.getValue ( ) ) + automatonToString ( * in, std::cout ); + else if ( automaton_to_dot.getValue ( ) ) + automatonToDot ( * in, std::cout ); + else if ( automaton_to_gastex.getValue ( ) ) + automatonToGasTex ( * in, std::cout ); + else if ( grammar_from_string.getValue ( ) ) + grammarFromString ( * in, std::cout ); + else if ( grammar_to_string.getValue ( ) ) + grammarToString ( * in, std::cout ); + else if ( regexp_from_string.getValue ( ) ) + regexpFromString ( * in, std::cout ); + else if ( regexp_to_string.getValue ( ) ) + regexpToString ( * in, std::cout ); + else if ( string_from_string.getValue ( ) ) + stringFromString ( * in, std::cout ); + else if ( string_to_string.getValue ( ) ) + stringToString ( * in, std::cout ); + else if ( tree_from_string.getValue ( ) ) + treeFromString ( * in, std::cout ); + else if ( tree_to_string.getValue ( ) ) + treeToString ( * in, std::cout ); + + if ( input.isSet ( ) && ( input.getValue ( ) != "-" ) ) delete in; - } - std::chrono::measurements::end(); - std::chrono::measurements::end(); + std::chrono::measurements::end ( ); + std::chrono::measurements::end ( ); - if(measure.getValue()) std::clog << std::chrono::measurements::results() << std::endl; + if ( measure.getValue ( ) ) std::clog << std::chrono::measurements::results ( ) << std::endl; return 0; - } catch (const exception::AlibException& exception) { - alib::XmlDataFactory::toStdout(exception); + } catch ( const exception::AlibException & exception ) { + alib::XmlDataFactory::toStdout ( exception ); return 1; - } catch(const TCLAP::ArgException& exception) { - std::cerr << exception.error() << std::endl; + } catch ( const TCLAP::ArgException & exception ) { + std::cerr << exception.error ( ) << std::endl; return 2; - } catch (const std::exception& exception) { - std::cerr << "Exception caught: " << exception.what() << std::endl; + } catch ( const std::exception & exception ) { + std::cerr << "Exception caught: " << exception.what ( ) << std::endl; return 3; - } catch(...) { + } catch ( ... ) { std::cerr << "Unknown exception caught." << std::endl; return 127; } } - diff --git a/alib2str/src/StringApi.cpp b/alib2str/src/StringApi.cpp index 19b1af90c4..a3c97bbb23 100644 --- a/alib2str/src/StringApi.cpp +++ b/alib2str/src/StringApi.cpp @@ -19,69 +19,78 @@ const automaton::AutomatonFromStringParser FromStringParsers::automatonParser; const grammar::GrammarFromStringParser FromStringParsers::grammarParser; const graph::GraphFromStringParser FromStringParsers::graphParser; const primitive::PrimitiveFromStringParser FromStringParsers::primitiveParser; +const tree::TreeFromStringParser FromStringParsers::treeParser; -alphabet::Symbol stringApi<alphabet::Symbol>::parse(std::istream& input) { - return FromStringParsers::symbolParser.parseSymbol(input); +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 alphabet::SymbolToStringComposer::compose(output, data); +void stringApi < alphabet::Symbol >::compose ( std::ostream & output, const alphabet::Symbol & data ) { + return alphabet::SymbolToStringComposer::compose ( output, data ); } -automaton::Automaton stringApi<automaton::Automaton>::parse(std::istream& input) { - return FromStringParsers::automatonParser.parseAutomaton(input); +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 automaton::AutomatonToStringComposer::compose(output, data); +void stringApi < automaton::Automaton >::compose ( std::ostream & output, const automaton::Automaton & data ) { + return automaton::AutomatonToStringComposer::compose ( output, data ); } -grammar::Grammar stringApi<grammar::Grammar>::parse(std::istream& input) { - return FromStringParsers::grammarParser.parseGrammar(input); +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 grammar::GrammarToStringComposer::compose(output, data); +void stringApi < grammar::Grammar >::compose ( std::ostream & output, const grammar::Grammar & data ) { + return grammar::GrammarToStringComposer::compose ( output, data ); } -graph::Graph stringApi<graph::Graph>::parse(std::istream& input) { - return FromStringParsers::graphParser.parseGraph(input); +graph::Graph stringApi < graph::Graph >::parse ( std::istream & input ) { + return FromStringParsers::graphParser.parseGraph ( input ); } -void stringApi<graph::Graph>::compose(std::ostream& output, const graph::Graph& data) { - return graph::GraphToStringComposer::compose(output, data); +void stringApi < graph::Graph >::compose ( std::ostream & output, const graph::Graph & data ) { + return graph::GraphToStringComposer::compose ( output, data ); } -label::Label stringApi<label::Label>::parse(std::istream& input) { - return FromStringParsers::labelParser.parseLabel(input); +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 label::LabelToStringComposer::compose(output, data); +void stringApi < label::Label >::compose ( std::ostream & output, const label::Label & data ) { + return label::LabelToStringComposer::compose ( output, data ); } -regexp::RegExp stringApi<regexp::RegExp>::parse(std::istream& input) { - return FromStringParsers::regexpParser.parseRegExp(input); +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 regexp::RegExpToStringComposer::compose(output, data); +void stringApi < regexp::RegExp >::compose ( std::ostream & output, const regexp::RegExp & data ) { + return regexp::RegExpToStringComposer::compose ( output, data ); } -string::String stringApi<string::String>::parse(std::istream& input) { - return FromStringParsers::stringParser.parseString(input); +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 string::StringToStringComposer::compose(output, data); +void stringApi < string::String >::compose ( std::ostream & output, const string::String & data ) { + return string::StringToStringComposer::compose ( output, data ); } -primitive::Primitive stringApi<primitive::Primitive>::parse(std::istream& input) { - return FromStringParsers::primitiveParser.parsePrimitive(input); +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 primitive::PrimitiveToStringComposer::compose(output, data); +void stringApi < primitive::Primitive >::compose ( std::ostream & output, const primitive::Primitive & data ) { + return primitive::PrimitiveToStringComposer::compose ( output, data ); +} + +tree::Tree stringApi < tree::Tree >::parse ( std::istream & input ) { + return FromStringParsers::treeParser.parseTree ( input ); +} + +void stringApi < tree::Tree >::compose ( std::ostream & output, const tree::Tree & data ) { + return tree::TreeToStringComposer::compose ( output, data ); } } /* namespace alib */ diff --git a/alib2str/src/StringApi.hpp b/alib2str/src/StringApi.hpp index 6420ad1b8c..bd6042c24b 100644 --- a/alib2str/src/StringApi.hpp +++ b/alib2str/src/StringApi.hpp @@ -16,6 +16,7 @@ #include "grammar/GrammarFromStringParser.h" #include "graph/GraphFromStringParser.h" #include "primitive/PrimitiveFromStringParser.h" +#include "tree/TreeFromStringParser.h" #include "label/LabelToStringComposer.h" #include "alphabet/SymbolToStringComposer.h" @@ -25,64 +26,70 @@ #include "grammar/GrammarToStringComposer.h" #include "graph/GraphToStringComposer.h" #include "primitive/PrimitiveToStringComposer.h" +#include "tree/TreeToStringComposer.h" #include "object/ObjectBase.h" namespace alib { -template<typename T> +template < typename T > struct stringApi { - static T parse(std::istream& input); - static void compose(std::ostream& output, const T& data); + 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 < 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<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<grammar::Grammar> { - static grammar::Grammar parse(std::istream& input); - static void compose(std::ostream& output, const grammar::Grammar& data); +template < > +struct stringApi < graph::Graph > { + static graph::Graph parse ( std::istream & input ); + static void compose ( std::ostream & output, const graph::Graph & data ); }; -template<> -struct stringApi<graph::Graph> { - static graph::Graph parse(std::istream& input); - static void compose(std::ostream& output, const graph::Graph& 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<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<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<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 ); }; -template<> -struct stringApi<primitive::Primitive> { - static primitive::Primitive parse(std::istream& input); - static void compose(std::ostream& output, const primitive::Primitive& data); +template < > +struct stringApi < tree::Tree > { + static tree::Tree parse ( std::istream & input ); + static void compose ( std::ostream & output, const tree::Tree & data ); }; class FromStringParsers { @@ -95,7 +102,7 @@ public: static const grammar::GrammarFromStringParser grammarParser; static const graph::GraphFromStringParser graphParser; static const primitive::PrimitiveFromStringParser primitiveParser; - + static const tree::TreeFromStringParser treeParser; }; } /* namespace alib */ diff --git a/alib2str/src/tree/TreeFromStringLexer.cpp b/alib2str/src/tree/TreeFromStringLexer.cpp new file mode 100644 index 0000000000..8a4fab3c1f --- /dev/null +++ b/alib2str/src/tree/TreeFromStringLexer.cpp @@ -0,0 +1,90 @@ +/* + * TreeFromStringLexer.cpp + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#include "TreeFromStringLexer.h" + +namespace tree { + +TreeFromStringLexer::Token TreeFromStringLexer::next ( std::istream & in ) const { + TreeFromStringLexer::Token token; + + token.type = TokenType::ERROR; + token.value = ""; + token.raw = ""; + char character; + +L0: 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.value += character; + token.raw += character; + goto L1; + } else if ( character == '|' ) { + token.type = TokenType::BAR; + token.value += character; + token.raw += character; + return token; + } else if ( ( character >= '0' ) && ( character <= '9' ) ) { + token.type = TokenType::RANK; + token.value += character; + token.raw += character; + goto L2; + } else { + in.putback ( character ); + putback ( in, std::move ( token ) ); + in.clear ( ); + token.type = TokenType::ERROR; + return token; + } + +L1: character = in.get ( ); + + if ( in.eof ( ) ) { + token.type = TokenType::TEOF; + return token; + } else if ( character == 'S' ) { + token.type = TokenType::SUBTREE_WILDCARD; + token.value += character; + token.raw += character; + return token; + } else { + in.putback ( character ); + putback ( in, std::move ( token ) ); + token.type = TokenType::ERROR; + return token; + } + +L2: character = in.get ( ); + + if ( in.eof ( ) ) { + return token; + } else if ( ( character >= '0' ) && ( character <= '9' ) ) { + token.value += character; + token.raw += character; + goto L1; + } else { + in.unget ( ); + return token; + } +} + +void TreeFromStringLexer::putback ( std::istream & in, TreeFromStringLexer::Token token ) const { + while ( !token.raw.empty ( ) ) { + in.putback ( token.raw.back ( ) ); + token.raw.pop_back ( ); + } + + in.clear ( ); +} + +} /* namespace tree */ diff --git a/alib2str/src/tree/TreeFromStringLexer.h b/alib2str/src/tree/TreeFromStringLexer.h new file mode 100644 index 0000000000..59990027fa --- /dev/null +++ b/alib2str/src/tree/TreeFromStringLexer.h @@ -0,0 +1,34 @@ +/* + * TreeFromStringLexer.h + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#ifndef TREE_FROM_STRING_LEXER_H_ +#define TREE_FROM_STRING_LEXER_H_ + +#include <string> +#include <istream> + +namespace tree { + +class TreeFromStringLexer { +public: + enum class TokenType { + BAR, RANK, SUBTREE_WILDCARD, TEOF, ERROR + }; + + struct Token { + TokenType type; + std::string value; + std::string raw; + }; + + Token next ( std::istream & input ) const; + void putback ( std::istream &, Token token ) const; +}; + +} /* namespace tree */ + +#endif /* TREE_FROM_STRING_LEXER_H_ */ diff --git a/alib2str/src/tree/TreeFromStringParser.cpp b/alib2str/src/tree/TreeFromStringParser.cpp new file mode 100644 index 0000000000..8b09091ac9 --- /dev/null +++ b/alib2str/src/tree/TreeFromStringParser.cpp @@ -0,0 +1,103 @@ +/* + * TreeFromStringParser.cpp + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#include "TreeFromStringParser.h" +#include "exception/AlibException.h" +#include "tree/TreeClasses.h" + +#include "../StringApi.hpp" + +namespace tree { + +Tree TreeFromStringParser::parseTree ( std::istream & input ) const { + return parseTree ( input, std::set < FEATURES > ( { FEATURES::RANKED_TREE, FEATURES::UNRANKED_TREE } ) ); +} + +Tree TreeFromStringParser::parseTree ( std::istream & input, const std::set < FEATURES > & features ) const { + alphabet::Symbol symbol = alib::stringApi < alphabet::Symbol >::parse ( input ); + + unsigned rank = 0; + + TreeFromStringLexer::Token token = m_TreeLexer.next ( input ); + + if ( token.type == TreeFromStringLexer::TokenType::RANK ) { + rank = std::stou ( token.value ); + + std::vector < tree::RankedNode * > childs; + + for ( unsigned i = 0; i < rank; i++ ) + childs.push_back ( parseRankedContent ( input ) ); + + RankedTree tree ( RankedNode ( alphabet::RankedSymbol ( symbol, rank ), std::move ( childs ) ) ); + + if ( features.count ( FEATURES::RANKED_TREE ) ) return Tree { + tree + }; + } else { + std::vector < tree::UnrankedNode * > childs; + + while ( token.type != TreeFromStringLexer::TokenType::BAR ) { + m_TreeLexer.putback ( input, token ); + childs.push_back ( parseUnrankedContent ( input ) ); + rank++; + token = m_TreeLexer.next ( input ); + } + + if ( token.type != TreeFromStringLexer::TokenType::BAR ) + throw exception::AlibException ( "Missing bar" ); + + UnrankedTree tree ( UnrankedNode ( symbol, childs ) ); + + if ( features.count ( FEATURES::UNRANKED_TREE ) ) return Tree { + tree + }; + } + + throw exception::AlibException ( "Invalid input" ); +} + +tree::RankedNode * TreeFromStringParser::parseRankedContent ( std::istream & input ) const { + alphabet::Symbol symbol = alib::stringApi < alphabet::Symbol >::parse ( input ); + + unsigned rank = 0; + std::vector < tree::RankedNode * > childs; + + TreeFromStringLexer::Token token = m_TreeLexer.next ( input ); + + if ( token.type == TreeFromStringLexer::TokenType::RANK ) + rank = std::stou ( token.value ); + else + throw exception::AlibException ( "Missing rank" ); + + for ( unsigned i = 0; i < rank; i++ ) + childs.push_back ( parseRankedContent ( input ) ); + + return new RankedNode ( alphabet::RankedSymbol ( std::move ( symbol ), rank ), std::move ( childs ) ); +} + +tree::UnrankedNode * TreeFromStringParser::parseUnrankedContent ( std::istream & input ) const { + alphabet::Symbol symbol = alib::stringApi < alphabet::Symbol >::parse ( input ); + + unsigned rank = 0; + std::vector < tree::UnrankedNode * > childs; + + TreeFromStringLexer::Token token = m_TreeLexer.next ( input ); + + while ( token.type != TreeFromStringLexer::TokenType::BAR ) { + m_TreeLexer.putback ( input, token ); + childs.push_back ( parseUnrankedContent ( input ) ); + rank++; + token = m_TreeLexer.next ( input ); + } + + if ( token.type != TreeFromStringLexer::TokenType::BAR ) + throw exception::AlibException ( "Missing bar" ); + + return new UnrankedNode ( std::move ( symbol ), std::move ( childs ) ); +} + +} /* namespace tree */ diff --git a/alib2str/src/tree/TreeFromStringParser.h b/alib2str/src/tree/TreeFromStringParser.h new file mode 100644 index 0000000000..27c986a392 --- /dev/null +++ b/alib2str/src/tree/TreeFromStringParser.h @@ -0,0 +1,44 @@ +/* + * TreeFromStringParser.h + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#ifndef TREE_FROM_STRING_PARSER_H_ +#define TREE_FROM_STRING_PARSER_H_ + +#include "tree/TreeFeatures.h" +#include "TreeFromStringLexer.h" + +#include <set> + +namespace alib { + +template < typename T > +struct stringApi; + +} /* namespace alib */ + +namespace tree { + +class TreeFromStringParser { +public: + TreeFromStringParser ( ) { } + +private: + tree::RankedNode * parseRankedContent ( std::istream & ) const; + tree::UnrankedNode * parseUnrankedContent ( std::istream & ) const; + + TreeFromStringLexer m_TreeLexer; + + tree::Tree parseTree ( std::istream & ) const; + tree::Tree parseTree ( std::istream &, const std::set < FEATURES > & features ) const; + + template < typename T > + friend struct alib::stringApi; +}; + +} /* namespace tree */ + +#endif /* TREE_FROM_STRING_PARSER_H_ */ diff --git a/alib2str/src/tree/TreeToStringComposer.cpp b/alib2str/src/tree/TreeToStringComposer.cpp new file mode 100644 index 0000000000..f2ee31a8b4 --- /dev/null +++ b/alib2str/src/tree/TreeToStringComposer.cpp @@ -0,0 +1,18 @@ +/* + * TreeToStringComposer.cpp + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#include "TreeToStringComposer.h" + +#include "../StringApi.hpp" + +namespace tree { + +void TreeToStringComposer::compose ( std::ostream & out, const Tree & tree ) { + getInstance ( ).dispatch ( out, tree.getData ( ) ); +} + +} /* namespace tree */ diff --git a/alib2str/src/tree/TreeToStringComposer.h b/alib2str/src/tree/TreeToStringComposer.h new file mode 100644 index 0000000000..5afbc0f055 --- /dev/null +++ b/alib2str/src/tree/TreeToStringComposer.h @@ -0,0 +1,40 @@ +/* + * TreeToStringComposer.h + * + * Created on: Nov 23, 2013 + * Author: Jan Travnciek + */ + +#ifndef TREE_TO_STRING_COMPOSER_H_ +#define TREE_TO_STRING_COMPOSER_H_ + +#include <ostream> +#include <common/multipleDispatch.hpp> +#include "tree/Tree.h" +#include "tree/TreeFeatures.h" + +namespace tree { + +/** + * This class contains methods to print XML representation of tree to the output stream. + */ +class TreeToStringComposer : public std::SingleDispatchFirstStaticParam < void, std::ostream &, TreeBase > { +public: + /** + * Prints XML representation of String to the output stream. + * @param tree String to print + * @param out output stream to which print the String + */ + static void compose ( std::ostream & output, const Tree & tree ); + + static TreeToStringComposer & getInstance ( ) { + static TreeToStringComposer res; + + return res; + } + +}; + +} /* namespace tree */ + +#endif /* TREE_TO_STRING_COMPOSER_H_ */ -- GitLab