Skip to content
Snippets Groups Projects
Commit fa19781a authored by Jan Trávníček's avatar Jan Trávníček
Browse files

housekeeping of parser

parent e8a1ab49
No related branches found
No related tags found
No related merge requests found
......@@ -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 ) ) {
......
......@@ -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 );
}
......
......@@ -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 ( );
 
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment