#include <parser/Parser.h> #include <ast/statements/CastStatement.h> #include <ast/statements/SingleStatement.h> #include <ast/statements/ResultImmediateFileStatement.h> #include <ast/statements/ResultBindedFileStatement.h> #include <ast/statements/ResultVariableStatement.h> #include <ast/statements/ResultPrintStatement.h> #include <ast/statements/VariableValueStatement.h> #include <ast/statements/BindedValueStatement.h> #include <ast/statements/BindedFileStatement.h> #include <ast/statements/ImmediateFileStatement.h> #include <ast/params/StatementParam.h> #include <ast/params/ImmediateFileParam.h> #include <ast/params/BindedFileParam.h> #include <ast/params/PreviousResultParam.h> #include <ast/params/ImmediateValueParam.h> #include <ast/params/BindedValueParam.h> #include <ast/params/VariableValueParam.h> #include <ast/params/CastParam.h> #include <command/ExecuteCommand.h> #include <command/QuitCommand.h> #include <command/HelpCommand.h> #include <command/IntrospectionCommand.h> #include <command/SetCommand.h> #include <primitive/Integer.h> #include <primitive/String.h> namespace cli { std::unique_ptr < Param > Parser::in_redirect_param ( ) { if ( check ( cli::Lexer::TokenType::LEFT_PAREN ) ) { match ( cli::Lexer::TokenType::LEFT_PAREN ); auto sub_statement = std::make_unique < StatementParam > ( statement_list ( ) ); match ( cli::Lexer::TokenType::RIGHT_PAREN ); return sub_statement; } else if ( check ( cli::Lexer::TokenType::COLON_SIGN ) ) { match ( cli::Lexer::TokenType::COLON_SIGN ); std::string name = getTokenValue ( ); match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER ); return std::make_unique < BindedFileParam > ( std::move ( name ) ); } else { std::string filename = matchIdentifier ( ); return std::make_unique < ImmediateFileParam > ( filename ); } } std::unique_ptr < Param > Parser::param ( ) { if ( check ( cli::Lexer::TokenType::DASH_SIGN ) ) { match ( cli::Lexer::TokenType::DASH_SIGN ); return std::make_unique < PreviousResultParam > ( ); } else if ( check ( cli::Lexer::TokenType::IN_REDIRECT ) ) { match ( cli::Lexer::TokenType::IN_REDIRECT ); return in_redirect_param ( ); } else if ( check ( cli::Lexer::TokenType::IDENTIFIER ) ) { std::string value = matchIdentifier ( ); return std::make_unique < ImmediateValueParam < std::string > > ( value ); } else if ( check ( cli::Lexer::TokenType::INTEGER ) ) { int value = matchInteger ( ); return std::make_unique < ImmediateValueParam < int > > ( value ); } else if ( check ( cli::Lexer::TokenType::LEFT_PAREN ) ) { match ( cli::Lexer::TokenType::LEFT_PAREN ); std::string type = matchIdentifier ( ); match ( cli::Lexer::TokenType::RIGHT_PAREN ); std::unique_ptr < Param > castedParam = param ( ); return std::make_unique < CastParam > ( std::move ( type ), std::move ( castedParam ) ); } else if ( check ( cli::Lexer::TokenType::COLON_SIGN ) ) { match ( cli::Lexer::TokenType::COLON_SIGN ); std::string name = getTokenValue ( ); match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER ); return std::make_unique < BindedValueParam > ( std::move ( name ) ); } else if ( check ( cli::Lexer::TokenType::DOLAR_SIGN ) ) { match ( cli::Lexer::TokenType::DOLAR_SIGN ); std::string name = getTokenValue ( ); match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER ); return std::make_unique < VariableValueParam > ( std::move ( name ) ); } else { throw exception::CommonException ( "Mismatched set while expanding param rule." ); } } std::shared_ptr < Statement > Parser::in_redirect_statement ( ) { if ( check ( cli::Lexer::TokenType::COLON_SIGN ) ) { match ( cli::Lexer::TokenType::COLON_SIGN ); std::string name = getTokenValue ( ); match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER ); return std::make_unique < BindedFileStatement > ( std::move ( name ) ); } else { std::string filename = matchIdentifier ( ); return std::make_unique < ImmediateFileStatement > ( filename ); } } std::shared_ptr < Statement > Parser::single_statement ( ) { if ( check ( cli::Lexer::TokenType::DOLAR_SIGN ) ) { match ( cli::Lexer::TokenType::DOLAR_SIGN ); std::string name = matchIdentifier ( ); return std::make_shared < VariableValueStatement > ( std::move ( name ) ); } else if ( check ( cli::Lexer::TokenType::COLON_SIGN ) ) { match ( cli::Lexer::TokenType::COLON_SIGN ); std::string name = matchIdentifier ( ); return std::make_shared < BindedValueStatement > ( std::move ( name ) ); } else if ( check ( cli::Lexer::TokenType::IN_REDIRECT ) ) { match ( cli::Lexer::TokenType::IN_REDIRECT ); return in_redirect_statement ( ); } else if ( check ( cli::Lexer::TokenType::LEFT_PAREN ) ) { match ( cli::Lexer::TokenType::LEFT_PAREN ); std::string type = matchIdentifier ( ); match ( cli::Lexer::TokenType::RIGHT_PAREN ); std::shared_ptr < Statement > casted_statement = single_statement ( ); return std::make_shared < CastStatement > ( std::move ( type ), casted_statement ); } else if ( check ( cli::Lexer::TokenType::IDENTIFIER ) ) { std::string name = matchIdentifier ( ); std::vector < std::unique_ptr < Param > > params; while ( ! check ( cli::Lexer::TokenType::OUT_REDIRECT ) && ! check ( cli::Lexer::TokenType::COLON_SIGN ) && ! check ( cli::Lexer::TokenType::PIPE_SIGN ) && ! check ( cli::Lexer::TokenType::END ) && ! check ( cli::Lexer::TokenType::RIGHT_PAREN ) ) { params.emplace_back ( param ( ) ); } return std::make_shared < SingleStatement > ( name, std::move ( params ) ); } else { throw exception::CommonException ( "Mismatched set while expanding param rule." ); } } std::shared_ptr < StatementList > Parser::statement_list ( ) { std::shared_ptr < Statement > statement = single_statement ( ); return std::make_shared < StatementList > ( statement, statement_list_cont ( ) ); } std::shared_ptr < StatementList > Parser::statement_list_cont ( ) { if ( check ( cli::Lexer::TokenType::PIPE_SIGN ) ) { match ( cli::Lexer::TokenType::PIPE_SIGN ); std::shared_ptr < Statement > statement = single_statement ( ); return std::make_shared < StatementList > ( statement, statement_list_cont ( ) ); } else { return nullptr; } } void Parser::out_redirect ( std::shared_ptr < StatementList > & list ) { if ( check ( cli::Lexer::TokenType::COLON_SIGN ) ) { match ( cli::Lexer::TokenType::COLON_SIGN ); std::string name = getTokenValue ( ); match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER ); list->append ( std::make_unique < ResultBindedFileStatement > ( std::move ( name ) ) ); } else if ( check ( cli::Lexer::TokenType::DOLAR_SIGN ) ) { match ( cli::Lexer::TokenType::DOLAR_SIGN ); std::string name = getTokenValue ( ); match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER ); list->append ( std::make_unique < ResultVariableStatement > ( std::move ( name ) ) ); } else if ( check ( cli::Lexer::TokenType::IDENTIFIER ) ) { std::string filename = matchIdentifier ( ); list->append ( std::make_unique < ResultImmediateFileStatement > ( std::move ( filename ) ) ); } else { return; } } void Parser::result ( std::shared_ptr < StatementList > & list ) { if ( check ( cli::Lexer::TokenType::OUT_REDIRECT ) ) { match ( cli::Lexer::TokenType::OUT_REDIRECT ); out_redirect ( list ); } else if ( check ( cli::Lexer::TokenType::END ) ) { list->append ( std::make_unique < ResultPrintStatement > ( ) ); } else { return; } } std::string Parser::optional_identifier ( ) { if ( check ( cli::Lexer::TokenType::IDENTIFIER ) ) { return matchIdentifier ( ); } else { return ""; } } std::unique_ptr < Command > Parser::parse ( ) { if ( check_nonreserved_kw ( "execute" ) ) { match_nonreserved_kw ( "execute" ); std::shared_ptr < StatementList > res = statement_list ( ); result ( res ); match ( cli::Lexer::TokenType::END ); return std::make_unique < ExecuteCommand > ( res ); } else if ( check_nonreserved_kw ( "quit" ) ) { match_nonreserved_kw ( "quit" ); match ( cli::Lexer::TokenType::END ); return std::make_unique < QuitCommand > ( ); } else if ( check_nonreserved_kw ( "help" ) ) { match_nonreserved_kw ( "help" ); std::string command = optional_identifier ( ); match ( cli::Lexer::TokenType::END ); return std::make_unique < HelpCommand > ( std::move ( command ) ); } else if ( check_nonreserved_kw ( "introspect" ) ) { match_nonreserved_kw ( "introspect" ); std::string command = optional_identifier ( ); match ( cli::Lexer::TokenType::END ); return std::make_unique < IntrospectionCommand > ( std::move ( command ) ); } else if ( check_nonreserved_kw ( "set" ) ) { match_nonreserved_kw ( "set" ); std::string param = matchIdentifier ( ); std::string value = getTokenValue ( ); match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER ); match ( cli::Lexer::TokenType::END ); return std::make_unique < SetCommand > ( std::move ( param ), std::move ( value ) ); } else { throw exception::CommonException ( "Mismatched set while expanding param rule." ); } } } /* namespace cli */