#ifndef _CLI_PARSER_H_ #define _CLI_PARSER_H_ #include <ast/Param.h> #include <ast/Statement.h> #include <ast/Option.h> #include <ast/Arg.h> #include <ast/options/TypeOption.h> #include <ast/options/CategoryOption.h> #include <command/Command.h> #include <ast/statements/StatementList.h> #include <lexer/Lexer.h> #include <exception/CommonException.h> #include <alib/algorithm> namespace cli { class Parser { cli::Lexer m_lexer; cli::Lexer::Token m_current; public: Parser ( cli::Lexer lexer ) : m_lexer ( std::move ( lexer ) ), m_current ( m_lexer.nextToken ( ) ) { } template < class ... Tokens > bool check ( Tokens ... tokens ) const { // TODO repace in c++17 with fold expressions return ext::orAll ( m_current.m_type == tokens ... ); } template < class ... NonreservedTokens > bool check_nonreserved_kw ( const NonreservedTokens & ... kw ) const { return m_current.m_type == Lexer::TokenType::IDENTIFIER && ext::orAll ( m_current.m_value == kw ... ); } template < class ... Tokens > bool match ( Tokens ... tokens ) { if ( ! check ( tokens ... ) ) throw exception::CommonException ( "Mismatched token while matching a token." ); m_current = m_lexer.nextToken ( ); return true; } bool match_nonreserved_kw ( const std::string & kw ) { if ( ! check_nonreserved_kw ( kw ) ) throw exception::CommonException ( "Mismatched token while matching a token." ); m_current = m_lexer.nextToken ( ); return true; } std::string matchIdentifier ( ) { if ( ! check ( Lexer::TokenType::IDENTIFIER ) ) throw exception::CommonException ( "Mismatched token while matching a token." ); std::string res = m_current.m_value; m_current = m_lexer.nextToken ( ); return res; } std::string matchString ( ) { if ( ! check ( Lexer::TokenType::STRING ) ) throw exception::CommonException ( "Mismatched token while matching a token." ); std::string res = m_current.m_value; m_current = m_lexer.nextToken ( ); return res; } int matchInteger ( ) { if ( ! check ( Lexer::TokenType::INTEGER ) ) throw exception::CommonException ( "Mismatched token while matching a token." ); int res = ext::from_string < int > ( m_current.m_value ); m_current = m_lexer.nextToken ( ); return res; } std::string getTokenValue ( ) { return m_current.m_value; } std::unique_ptr < CategoryOption > category_option ( ); std::unique_ptr < TypeOption > type_option ( ); std::unique_ptr < Arg > arg ( ); std::unique_ptr < Arg > optional_arg ( ); bool move_arg ( ); std::unique_ptr < Param > in_redirect_param ( ); std::unique_ptr < Param > param ( ); std::unique_ptr < Arg > template_param ( ); std::unique_ptr < Param > move_param ( ); std::unique_ptr < Param > value_param ( ); std::shared_ptr < Statement > in_redirect_statement ( ); std::shared_ptr < Statement > single_statement ( ); std::shared_ptr < StatementList > statement_list ( ); std::shared_ptr < StatementList > statement_list_cont ( ); void out_redirect ( std::shared_ptr < StatementList > & list ); void result ( std::shared_ptr < StatementList > & list ); std::pair < bool, bool > introspect_cast_from_to ( ); std::unique_ptr < Command > introspect_command ( ); std::unique_ptr < Command > parse ( ); }; } /* namespace cli */ #endif /* _CLI_PARSER_H_ */