diff --git a/alib2cli/src/lexer/Lexer.h b/alib2cli/src/lexer/Lexer.h index 0c669cc1268d6f1e27ecd66927e58ba2fee1568a..9fad02d97fbce27964bfc8c6f90833ce3c09c24a 100644 --- a/alib2cli/src/lexer/Lexer.h +++ b/alib2cli/src/lexer/Lexer.h @@ -4,6 +4,8 @@ #include <alib/string> #include <alib/iostream> +#include <exception/CommonException.h> + namespace cli { class Lexer { @@ -36,6 +38,57 @@ public: END }; + static std::string tokenTypeToString ( TokenType type ) { + switch ( type ) { + case TokenType::IDENTIFIER : + return "identifier"; + case TokenType::INTEGER : + return "number"; + case TokenType::STRING : + return "string"; + case TokenType::IN_REDIRECT : + return "in_redirect"; + case TokenType::OUT_REDIRECT : + return "out_redirect"; + case TokenType::LEFT_PAREN : + return "left_paren"; + case TokenType::RIGHT_PAREN : + return "right_paren"; + case TokenType::LEFT_BRACE : + return "left_brace"; + case TokenType::RIGHT_BRACE : + return "right_brace"; + case TokenType::LEFT_BRACKET : + return "left_bracket"; + case TokenType::RIGHT_BRACKET : + return "right_bracket"; + case TokenType::AT_SIGN : + return "at_sign"; + case TokenType::DOLAR_SIGN : + return "dolar_sign"; + case TokenType::AMPERSAND_SIGN : + return "ampersand_sign"; + case TokenType::PIPE_SIGN : + return "pipe_sign"; + case TokenType::CARET_SIGN : + return "caret_sign"; + case TokenType::COLON_SIGN : + return "colon_sign"; + case TokenType::DASH_SIGN : + return "dash_sign"; + case TokenType::EQUAL_SIGN : + return "equal_sign"; + case TokenType::HASH_SIGN : + return "hash_sign"; + case TokenType::ERROR : + return "error"; + case TokenType::END : + return "end"; + default: + throw exception::CommonException ( "Unhandler case in Lexer::tokenTypeToString" ); + } + } + static TokenType is_kw ( const std::string & /* identifier */ ) { return TokenType::IDENTIFIER; } @@ -44,54 +97,24 @@ public: std::string m_value; TokenType m_type; - friend std::ostream & operator << ( std::ostream & out, const Token & token ) { - switch ( token.m_type ) { + operator std::string ( ) const { + std::string res = Lexer::tokenTypeToString ( m_type ); + switch ( m_type ) { case TokenType::IDENTIFIER : - return out << "identifier: " << token.m_value; + return res + ": " + m_value; case TokenType::INTEGER : - return out << "number: " << token.m_value; + return res + ": " + ext::to_string ( m_value ); case TokenType::STRING : - return out << "string: \"" << token.m_value << "\""; - case TokenType::IN_REDIRECT : - return out << "in_redirect"; - case TokenType::OUT_REDIRECT : - return out << "out_redirect"; - case TokenType::LEFT_PAREN : - return out << "left_paren"; - case TokenType::RIGHT_PAREN : - return out << "right_paren"; - case TokenType::LEFT_BRACE : - return out << "left_brace"; - case TokenType::RIGHT_BRACE : - return out << "right_brace"; - case TokenType::LEFT_BRACKET : - return out << "left_bracket"; - case TokenType::RIGHT_BRACKET : - return out << "right_bracket"; - case TokenType::AT_SIGN : - return out << "at_sign"; - case TokenType::DOLAR_SIGN : - return out << "dolar_sign"; - case TokenType::AMPERSAND_SIGN : - return out << "ampersand_sign"; - case TokenType::PIPE_SIGN : - return out << "pipe_sign"; - case TokenType::CARET_SIGN : - return out << "caret_sign"; - case TokenType::COLON_SIGN : - return out << "colon_sign"; - case TokenType::DASH_SIGN : - return out << "dash_sign"; - case TokenType::EQUAL_SIGN : - return out << "equal_sign"; - case TokenType::HASH_SIGN : - return out << "hash_sign"; - case TokenType::ERROR : - return out << "error"; - case TokenType::END : - return out << "end"; + return res + ": \"" + ext::to_string ( m_value ) + "\""; + default: + return res; } } + + friend std::ostream & operator << ( std::ostream & out, const Token & token ) { + return out << ( std::string ) token; + } + }; Lexer ( std::string line ) : m_index ( 0 ), m_line ( std::move ( line ) ) { diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp index 73ff80b51bb2f973332d2264f71e7be45ca8d744..c0b408992a8988ee07441cb27503cedfd506176b 100644 --- a/alib2cli/src/parser/Parser.cpp +++ b/alib2cli/src/parser/Parser.cpp @@ -113,59 +113,54 @@ std::shared_ptr < Statement > Parser::in_redirect ( ) { } } -std::shared_ptr < Statement > Parser::param ( ) { - if ( check ( cli::Lexer::TokenType::DASH_SIGN ) ) { - match ( cli::Lexer::TokenType::DASH_SIGN ); - return std::make_shared < PreviousResultStatement > ( ); +std::shared_ptr < Statement > Parser::common ( ) { + if ( check ( cli::Lexer::TokenType::DOLAR_SIGN ) ) { + match ( cli::Lexer::TokenType::DOLAR_SIGN ); + std::unique_ptr < Arg > name = arg ( ); + return std::make_shared < VariableStatement > ( std::move ( name ) ); } else if ( check ( cli::Lexer::TokenType::IN_REDIRECT ) ) { match ( cli::Lexer::TokenType::IN_REDIRECT ); return in_redirect ( ); - } else if ( check ( cli::Lexer::TokenType::IDENTIFIER ) ) { - std::string value = matchIdentifier ( ); - return std::make_shared < ImmediateStatement < std::string > > ( value ); } else if ( check ( cli::Lexer::TokenType::STRING ) ) { std::string value = matchString ( ); return std::make_shared < ImmediateStatement < std::string > > ( value ); } else if ( check ( cli::Lexer::TokenType::INTEGER ) ) { int value = matchInteger ( ); return std::make_shared < ImmediateStatement < int > > ( value ); - } else if ( check ( cli::Lexer::TokenType::LEFT_PAREN ) ) { - match ( cli::Lexer::TokenType::LEFT_PAREN ); - std::unique_ptr < Arg > type = arg ( ); - match ( cli::Lexer::TokenType::RIGHT_PAREN ); - bool move = move_arg ( ); - std::shared_ptr < Statement > castedParam = param ( ); - return std::make_shared < CastStatement > ( std::move ( type ), castedParam, move ); - } else if ( check ( cli::Lexer::TokenType::DOLAR_SIGN ) ) { - match ( cli::Lexer::TokenType::DOLAR_SIGN ); - std::unique_ptr < Arg > name = arg ( ); - return std::make_shared < VariableStatement > ( std::move ( name ) ); } else if ( check ( cli::Lexer::TokenType::HASH_SIGN ) ) { match ( cli::Lexer::TokenType::HASH_SIGN ); std::string value = getTokenValue ( ); match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER ); return std::make_shared < ValueStatement > ( std::make_unique < BindedArg > ( std::move ( value ) ) ); } else { - throw exception::CommonException ( "Mismatched set while expanding param rule." ); + throw exception::CommonException ( "Mismatched set while expanding common rule." ); } } -std::shared_ptr < Statement > Parser::single_statement ( ) { - if ( check ( cli::Lexer::TokenType::DOLAR_SIGN ) ) { - match ( cli::Lexer::TokenType::DOLAR_SIGN ); - std::unique_ptr < Arg > name = arg ( ); - return std::make_shared < VariableStatement > ( std::move ( name ) ); - } else if ( check ( cli::Lexer::TokenType::IN_REDIRECT ) ) { - match ( cli::Lexer::TokenType::IN_REDIRECT ); - return in_redirect ( ); +std::shared_ptr < Statement > Parser::param ( ) { + if ( check ( cli::Lexer::TokenType::DOLAR_SIGN, cli::Lexer::TokenType::IN_REDIRECT, cli::Lexer::TokenType::STRING, cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::HASH_SIGN ) ) { + return common ( ); + } else if ( check ( cli::Lexer::TokenType::DASH_SIGN ) ) { + match ( cli::Lexer::TokenType::DASH_SIGN ); + return std::make_shared < PreviousResultStatement > ( ); + } else if ( check ( cli::Lexer::TokenType::IDENTIFIER ) ) { + std::string value = matchIdentifier ( ); + return std::make_shared < ImmediateStatement < std::string > > ( value ); } else if ( check ( cli::Lexer::TokenType::LEFT_PAREN ) ) { match ( cli::Lexer::TokenType::LEFT_PAREN ); std::unique_ptr < Arg > type = arg ( ); match ( cli::Lexer::TokenType::RIGHT_PAREN ); bool move = move_arg ( ); - std::shared_ptr < Statement > casted_statement = single_statement ( ); - return std::make_shared < CastStatement > ( std::move ( type ), casted_statement, move ); - // TODO builtin statement type to get string type + std::shared_ptr < Statement > castedParam = param ( ); + return std::make_shared < CastStatement > ( std::move ( type ), castedParam, move ); + } else { + throw exception::CommonException ( "Mismatched set while expanding param rule." ); + } +} + +std::shared_ptr < Statement > Parser::statement ( ) { + if ( check ( cli::Lexer::TokenType::DOLAR_SIGN, cli::Lexer::TokenType::IN_REDIRECT, cli::Lexer::TokenType::STRING, cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::HASH_SIGN ) ) { + return common ( ); } else if ( check ( cli::Lexer::TokenType::IDENTIFIER ) ) { std::unique_ptr < Arg > name = std::make_unique < ImmediateArg > ( matchIdentifier ( ) ); ext::vector < std::unique_ptr < cli::Arg > > templateArgs; @@ -182,12 +177,13 @@ std::shared_ptr < Statement > Parser::single_statement ( ) { } return std::make_shared < SingleStatement > ( std::move ( name ), std::move ( templateArgs ), std::move ( params ), std::move ( category ), std::move ( moves ) ); - } else if ( check ( cli::Lexer::TokenType::STRING ) ) { - std::string value = matchString ( ); - return std::make_unique < ImmediateStatement < std::string > > ( value ); - } else if ( check ( cli::Lexer::TokenType::INTEGER ) ) { - int value = matchInteger ( ); - return std::make_unique < ImmediateStatement < int > > ( value ); + } else if ( check ( cli::Lexer::TokenType::LEFT_PAREN ) ) { + match ( cli::Lexer::TokenType::LEFT_PAREN ); + std::unique_ptr < Arg > type = arg ( ); + match ( cli::Lexer::TokenType::RIGHT_PAREN ); + bool move = move_arg ( ); + std::shared_ptr < Statement > castedStatement = statement ( ); + return std::make_shared < CastStatement > ( std::move ( type ), castedStatement, move ); } else if ( check ( cli::Lexer::TokenType::LEFT_BRACE ) ) { match ( cli::Lexer::TokenType::LEFT_BRACE ); std::unique_ptr < TypeOption > type = type_option ( ); @@ -202,22 +198,18 @@ std::shared_ptr < Statement > Parser::single_statement ( ) { std::shared_ptr < Statement > res = std::make_shared < ContainerStatement > ( "Set", std::move ( params ), std::move ( type ), std::move ( moves ) ); match ( cli::Lexer::TokenType::RIGHT_BRACE ); return res; - } else if ( check ( cli::Lexer::TokenType::HASH_SIGN ) ) { - match ( cli::Lexer::TokenType::HASH_SIGN ); - std::string value = getTokenValue ( ); - match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER ); - return std::make_shared < ValueStatement > ( std::make_unique < BindedArg > ( std::move ( value ) ) ); } else { - throw exception::CommonException ( "Mismatched set while expanding param single_statement." ); + // TODO builtin statement type to get string type + throw exception::CommonException ( "Mismatched set while expanding param statement." ); } } std::shared_ptr < StatementList > Parser::statement_list ( ) { ext::vector < std::shared_ptr < Statement > > list; - list.emplace_back ( single_statement ( ) ); + list.emplace_back ( statement ( ) ); while ( check ( cli::Lexer::TokenType::PIPE_SIGN ) ) { match ( cli::Lexer::TokenType::PIPE_SIGN ); - list.emplace_back ( single_statement ( ) ); + list.emplace_back ( statement ( ) ); } return std::make_shared < StatementList > ( list ); } diff --git a/alib2cli/src/parser/Parser.h b/alib2cli/src/parser/Parser.h index 9f7054ee19b445d3658f51dfc907d84e36e56eb5..b7279465942140f705f243cd88e15901cca7962f 100644 --- a/alib2cli/src/parser/Parser.h +++ b/alib2cli/src/parser/Parser.h @@ -39,10 +39,10 @@ public: 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." ); + template < class Token, class ... Tokens > + bool match ( Token token, Tokens ... tokens ) { + if ( ! check ( token, tokens ... ) ) + throw exception::CommonException ( std::string ( "Mismatched token while matching a token " ) + Lexer::tokenTypeToString ( token ) + "." ); m_current = m_lexer.nextToken ( ); return true; } @@ -93,11 +93,13 @@ public: bool move_arg ( ); - std::shared_ptr < Statement > param ( ); - std::shared_ptr < Statement > in_redirect ( ); - std::shared_ptr < Statement > single_statement ( ); + std::shared_ptr < Statement > common ( ); + + std::shared_ptr < Statement > param ( ); + + std::shared_ptr < Statement > statement ( ); std::shared_ptr < StatementList > statement_list ( );