Skip to content
Snippets Groups Projects
Parser.cpp 8.95 KiB
Newer Older
  • Learn to ignore specific revisions
  • #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>
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    #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 ( );
    
    		ext::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." );
    	}
    }
    
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    std::shared_ptr < StatementList > Parser::statement_list ( ) {
    
    	std::shared_ptr < Statement > statement = single_statement ( );
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    	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 ) ) );
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    void Parser::result ( std::shared_ptr < StatementList > & list ) {
    
    	if ( check ( cli::Lexer::TokenType::OUT_REDIRECT ) ) {
    
    		match ( cli::Lexer::TokenType::OUT_REDIRECT );
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    		out_redirect ( list );
    
    	} else if ( check ( cli::Lexer::TokenType::END ) ) {
    
    		list->append ( std::make_unique < ResultPrintStatement > ( ) );
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    		return;
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    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" );
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    		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" );
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    		std::string command = optional_identifier ( );
    
    		match ( cli::Lexer::TokenType::END );
    		return std::make_unique < HelpCommand > ( std::move ( command ) );
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    	} 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." );
    	}