diff --git a/alib2cli/src/ast/Option.h b/alib2cli/src/ast/Option.h index 8e3febebbf573eb9b0ea8120badbcc0e7a532bd8..32b991662016b4c2984e71d6d09e52132a8d5327 100644 --- a/alib2cli/src/ast/Option.h +++ b/alib2cli/src/ast/Option.h @@ -5,6 +5,7 @@ #include <ast/statements/SingleStatement.h> #include <ast/statements/ContainerStatement.h> #include <ast/statements/ContainerFileStatement.h> +#include <ast/statements/FileStatement.h> namespace cli { @@ -16,6 +17,7 @@ public: virtual void eval ( SingleStatement & statement ) const = 0; virtual void eval ( ContainerStatement & statement ) const = 0; virtual void eval ( ContainerFileStatement & statement ) const = 0; + virtual void eval ( FileStatement & statement ) const = 0; }; } /* namespace cli */ diff --git a/alib2cli/src/ast/options/CategoryOption.h b/alib2cli/src/ast/options/CategoryOption.h index defe21f6581cdc27941d6cbc80dfc5775ed847df..85d8bf3dbe2ffc8232048b1f0868213ed40f4b11 100644 --- a/alib2cli/src/ast/options/CategoryOption.h +++ b/alib2cli/src/ast/options/CategoryOption.h @@ -25,6 +25,10 @@ public: virtual void eval ( ContainerFileStatement & ) const override { throw exception::CommonException ( "ContainerFileStatement cannot be categorized." ); } + + virtual void eval ( FileStatement & ) const override { + throw exception::CommonException ( "FileStatement cannot be categorized." ); + } }; } /* namespace cli */ diff --git a/alib2cli/src/ast/options/HL3Option.h b/alib2cli/src/ast/options/HL3Option.h index 405e63ba48ce86fb0a1e70d1f20e6aecc07980c2..6dba5a8131e4175b7babd4f3ee68f8a2047cab74 100644 --- a/alib2cli/src/ast/options/HL3Option.h +++ b/alib2cli/src/ast/options/HL3Option.h @@ -18,6 +18,10 @@ public: virtual void eval ( ContainerFileStatement & ) const override { std::cout << "The cake is a lie, as well as the release date of HL3. GLaDOS told me." << std::endl; } + + virtual void eval ( FileStatement & ) const override { + std::cout << "The cake is a lie, as well as the release date of HL3. GLaDOS told me." << std::endl; + } }; } /* namespace cli */ diff --git a/alib2cli/src/ast/options/TypeOption.h b/alib2cli/src/ast/options/TypeOption.h index f9f06d8cb9acc0520eefc04da41c160610af5508..f70d3095002a8f98b0e502d63377bd34fce339b2 100644 --- a/alib2cli/src/ast/options/TypeOption.h +++ b/alib2cli/src/ast/options/TypeOption.h @@ -24,6 +24,10 @@ public: virtual void eval ( ContainerFileStatement & statement ) const override { statement.setType ( m_type ); } + + virtual void eval ( FileStatement & statement ) const override { + statement.setType ( m_type ); + } }; } /* namespace cli */ diff --git a/alib2cli/src/ast/statements/ContainerFileStatement.h b/alib2cli/src/ast/statements/ContainerFileStatement.h index 962eec43b7e00bff96097e2809a8dc05f89a04bb..e2e2d88c31ad2b79c581676b7a11a45bf3483d3f 100644 --- a/alib2cli/src/ast/statements/ContainerFileStatement.h +++ b/alib2cli/src/ast/statements/ContainerFileStatement.h @@ -2,7 +2,6 @@ #define _CLI_CONTAINER_FILE_STATEMENT_H_ #include <ast/Statement.h> -#include <abstraction/Registry.h> namespace cli { diff --git a/alib2cli/src/ast/statements/ContainerStatement.cpp b/alib2cli/src/ast/statements/ContainerStatement.cpp index 4b14caf0d0be12dde9e7e50c3f4de10824ef0066..9751550f2afe283cc0d186f9daf9d404a13ec7cd 100644 --- a/alib2cli/src/ast/statements/ContainerStatement.cpp +++ b/alib2cli/src/ast/statements/ContainerStatement.cpp @@ -3,6 +3,8 @@ #include <ast/Param.h> #include <ast/Arg.h> #include <abstraction/common/CastHelper.h> +#include <exception/CommonException.h> +#include <iostream> namespace cli { diff --git a/alib2cli/src/ast/statements/ContainerStatement.h b/alib2cli/src/ast/statements/ContainerStatement.h index 83930e6affe9d2f7d846d563f284778a85de4646..35b97849d36173a4456d16d65440ec323258b344 100644 --- a/alib2cli/src/ast/statements/ContainerStatement.h +++ b/alib2cli/src/ast/statements/ContainerStatement.h @@ -2,9 +2,6 @@ #define _CLI_CONTAINER_STATEMENT_H_ #include <ast/Statement.h> -#include <abstraction/Registry.h> -#include <exception/CommonException.h> -#include <iostream> namespace cli { diff --git a/alib2cli/src/ast/statements/FileStatement.cpp b/alib2cli/src/ast/statements/FileStatement.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9b8768ab8d0ae4c015159ca5b3b4336d8f8a4e11 --- /dev/null +++ b/alib2cli/src/ast/statements/FileStatement.cpp @@ -0,0 +1,29 @@ +#include <ast/statements/FileStatement.h> +#include <ast/Statement.h> +#include <ast/Option.h> +#include <ast/Arg.h> +#include <abstraction/Registry.h> + +namespace cli { + +FileStatement::FileStatement ( ext::vector < std::unique_ptr < Option > > options, std::unique_ptr < Arg > file ) : m_file ( std::move ( file ) ), m_options ( std::move ( options ) ) { + for ( const std::unique_ptr < Option > & option : m_options ) { + option->eval ( * this ); + } +} + +std::shared_ptr < abstraction::OperationAbstraction > FileStatement::translateAndEval ( const std::shared_ptr < abstraction::OperationAbstraction > &, Environment & environment ) const { + ext::deque < sax::Token > tokens = sax::FromXMLParserHelper::parseInput ( m_file->eval ( environment ) ); + + std::string type = m_type; + if ( type == "" ) + type = tokens [ 0 ].getData ( ); + + return abstraction::Registry::getXmlParserAbstraction ( type, tokens ); +} + +void FileStatement::setType ( std::string type ) { + m_type = std::move ( type ); +} + +} /* namespace cli */ diff --git a/alib2cli/src/ast/statements/FileStatement.h b/alib2cli/src/ast/statements/FileStatement.h index a43017588741abcb4278b2398003f3bf6743e42f..cc3828577edd7c6c3623e69cafd125b786ebc7b1 100644 --- a/alib2cli/src/ast/statements/FileStatement.h +++ b/alib2cli/src/ast/statements/FileStatement.h @@ -2,22 +2,21 @@ #define _CLI_FILE_STATEMENT_H_ #include <ast/Statement.h> -#include <abstraction/Registry.h> namespace cli { class FileStatement final : public Statement { std::unique_ptr < cli::Arg > m_file; + ext::vector < std::unique_ptr < Option > > m_options; + + std::string m_type; public: - FileStatement ( std::unique_ptr < Arg > file ) : m_file ( std::move ( file ) ) { - } - - virtual std::shared_ptr < abstraction::OperationAbstraction > translateAndEval ( const std::shared_ptr < abstraction::OperationAbstraction > &, Environment & environment ) const override { - ext::deque < sax::Token > tokens = sax::FromXMLParserHelper::parseInput ( m_file->eval ( environment ) ); - std::string type = tokens [ 0 ].getData ( ); - return abstraction::Registry::getXmlParserAbstraction ( type, tokens ); - } + FileStatement ( ext::vector < std::unique_ptr < Option > > options, std::unique_ptr < Arg > file ); + + virtual std::shared_ptr < abstraction::OperationAbstraction > translateAndEval ( const std::shared_ptr < abstraction::OperationAbstraction > &, Environment & environment ) const override; + + void setType ( std::string type ); }; } /* namespace cli */ diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp index 69e808981c4729316ee76f39135a5551e343d851..b153b061ca57e32a20426650de21568e77f02269 100644 --- a/alib2cli/src/parser/Parser.cpp +++ b/alib2cli/src/parser/Parser.cpp @@ -200,8 +200,19 @@ std::shared_ptr < Statement > Parser::in_redirect_statement ( ) { std::unique_ptr < Arg > file = arg ( ); return std::make_shared < ContainerFileStatement > ( "Set", std::move ( options ), std::move ( file ) ); } else { + ext::vector < std::unique_ptr < Option > > options; + while ( check ( cli::Lexer::TokenType::COLON_SIGN ) ) { + match ( cli::Lexer::TokenType::COLON_SIGN ); + std::unique_ptr < Option > res = type_option ( ); + if ( ! res ) + res = option ( ); + if ( ! res ) + throw exception::CommonException ( "Option not recognised" ); + options.emplace_back ( std::move ( res ) ); + } + std::unique_ptr < Arg > file = arg ( ); - return std::make_shared < FileStatement > ( std::move ( file ) ); + return std::make_shared < FileStatement > ( std::move ( options ), std::move ( file ) ); } } diff --git a/alib2cli/test-src/cli/CliTest.cpp b/alib2cli/test-src/cli/CliTest.cpp index c7e34789d3f9e375511ab9374c6d1b3a86a19add..7aac73590953182538740527cceee1595a283656 100644 --- a/alib2cli/test-src/cli/CliTest.cpp +++ b/alib2cli/test-src/cli/CliTest.cpp @@ -96,6 +96,9 @@ void CliTest::testCreateUnique ( ) { parser = cli::Parser ( cli::Lexer ( "execute One | Add <( Add (int) <#2 <(One) ) - | Neg (double) - | Divide (double) - <(One | (double) Add <(One) - )" ) ); parser.parse ( )->run ( environment ); + parser = cli::Parser ( cli::Lexer ( "execute <:type int #2" ) ); + parser.parse ( )->run ( environment ); + parser = cli::Parser ( cli::Lexer ( "execute One > $res" ) ); parser.parse ( )->run ( environment ); diff --git a/alib2common/src/abstraction/PrimitiveRegistrator.cpp b/alib2common/src/abstraction/PrimitiveRegistrator.cpp index c02d2f8471d9bc168ed8cbbc2aaa6115f9f5aa63..7752bd316698f3cff8b75270403a86820b4403a2 100644 --- a/alib2common/src/abstraction/PrimitiveRegistrator.cpp +++ b/alib2common/src/abstraction/PrimitiveRegistrator.cpp @@ -7,6 +7,7 @@ #include <abstraction/CastRegistry.hpp> #include <abstraction/XmlFileWriterRegistry.hpp> +#include <abstraction/XmlParserRegistry.hpp> #include <abstraction/NormalizeRegistry.hpp> #include <abstraction/ValuePrinterRegistry.hpp> #include <abstraction/ImmediateRegistry.hpp> @@ -44,6 +45,8 @@ public: abstraction::ContainerRegistry::registerSet < int > ( ); + abstraction::XmlParserRegistry::registerXmlParser < int > ( "int" ); + abstraction::XmlFileWriterRegistry::registerXmlFileWriter < int > ( ); abstraction::XmlFileWriterRegistry::registerXmlFileWriter < double > ( ); abstraction::XmlFileWriterRegistry::registerXmlFileWriter < std::string > ( ); diff --git a/alib2common/src/abstraction/XmlParserRegistry.hpp b/alib2common/src/abstraction/XmlParserRegistry.hpp index 7adf27a9d021819a11d75360360aee63c5a64d62..eef86abb62647fd8f3e7775df2feb8f24d815745 100644 --- a/alib2common/src/abstraction/XmlParserRegistry.hpp +++ b/alib2common/src/abstraction/XmlParserRegistry.hpp @@ -38,11 +38,15 @@ class XmlParserRegistry { } public: + template < class ReturnType > + static void registerXmlParser ( std::string result ) { + getEntries ( ).insert ( std::make_pair ( result, std::unique_ptr < Entry > ( new EntryImpl < ReturnType > ( ) ) ) ); + } + template < class ReturnType > static void registerXmlParser ( ) { std::string ret = alib::xmlApi < ReturnType >::xmlTagName ( ); - - getEntries ( ).insert ( std::make_pair ( ret, std::unique_ptr < Entry > ( new EntryImpl < ReturnType > ( ) ) ) ); + registerXmlParser < ReturnType > ( ret ); } static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & typeName, ext::deque < sax::Token > tokens );