// Custom includes
#include <vector>
+#include "../../config.hh"
#include <boost/spirit.hpp>
#include <boost/spirit/utility/grammar_def.hpp>
#include <boost/spirit/dynamic.hpp>
///////////////////////////////////////////////////////////////////////////
// Start rules
- enum { CommandParser, SkipParser, ArgumentsParser };
+ enum { CommandParser, SkipParser, ArgumentsParser, PathParser };
///////////////////////////////////////////////////////////////////////////
// The parse context (variables needed while parsing)
ParseDispatcher & dispatcher;
+ //////////////////////////////////////////////////////////////////////////
+ // charachter sets
+
+ static boost::spirit::chset<> special_p;
+ static boost::spirit::chset<> punctuation_p;
+ static boost::spirit::chset<> space_p;
+ static boost::spirit::chset<> invalid_p;
+ static boost::spirit::chset<> word_p;
+ static boost::spirit::distinct_parser<> keyword_p;
+
///////////////////////////////////////////////////////////////////////////
// Errors
enum Errors {
EndOfStatementExpected,
- GroupOrArgumentsExpected,
PathExpected,
ClosingParenExpected,
QuoteExpected
struct definition
: public boost::spirit::grammar_def< boost::spirit::rule<Scanner>,
boost::spirit::rule<Scanner>,
+ boost::spirit::rule<Scanner>,
boost::spirit::rule<Scanner> >
{
boost::spirit::rule<Scanner> command, path, argument, word, string, hexstring, token,
punctuation, hexbyte, balanced_tokens, simple_argument, complex_argument, builtin,
skip, statement, relpath, abspath, arguments, group_start, group_close,
- statement_end;
- boost::spirit::chset<> special_p, punctuation_p, space_p, invalid_p, word_p;
- boost::spirit::distinct_parser<> keyword_p;
-
- definition(CommandGrammar const & self) :
-
- // Characters with a special meaning within the parser
- special_p ("/(){};\""),
-
- // Additional characters which are returned as punctuation tokens
- // (only allowed within '()').
- punctuation_p (",="),
-
- // Whitespace characters
- space_p (" \t\n\r"),
-
- // Invalid characters: All chars below \x20 (space) which are not space_p
- // (don't put a \0 in the chset<> argument *string* ...)
- invalid_p ( (boost::spirit::chset<>('\0')
- | boost::spirit::chset<>("\x01-\x20")) - space_p ),
-
- // Valid word characters
- word_p (
- boost::spirit::anychar_p - special_p - punctuation_p - space_p - invalid_p),
-
- // Keywords must not be followed by a word char or '/'
- keyword_p ( word_p | boost::spirit::ch_p('/') )
+ statement_end, opt_path;
+ definition(CommandGrammar const & self)
{
using namespace boost::spirit;
using namespace ::phoenix;
actor< variable< ParseDispatcher > > d_ (self.dispatcher);
assertion<Errors> end_of_statement_expected (EndOfStatementExpected);
- assertion<Errors> group_or_arguments_expected (GroupOrArgumentsExpected);
assertion<Errors> path_expected (PathExpected);
assertion<Errors> closing_paren_expected (ClosingParenExpected);
assertion<Errors> quote_expected (QuoteExpected);
= builtin >> end_of_statement_expected(statement_end)
| group_close
| ch_p(';') // Ignore empty commands
- | path_expected(path)
- >> group_or_arguments_expected( group_start | statement )
+ | statement
+ ;
+
+ statement
+ = path_expected(path) [ bind(&PD::beginCommand)(d_, path_) ]
+ >> arguments
+ >> end_of_statement_expected(
+ ( group_start | statement_end )
+ [ bind(&PD::endCommand)(d_) ]
+ )
;
builtin
- = keyword_p("cd")
+ = self.keyword_p("cd")
>> path_expected(path)
>> eps_p [ bind(&PD::builtin_cd)(d_, path_) ]
- | keyword_p("ls")
+ | self.keyword_p("ls")
>> ! path
>> eps_p [ bind(&PD::builtin_ls)(d_, path_) ]
- | keyword_p("exit") [ bind(&PD::builtin_exit)(d_) ]
- | keyword_p("help")
+ | self.keyword_p("exit") [ bind(&PD::builtin_exit)(d_) ]
+ | self.keyword_p("help")
>> ! path
>> eps_p [ bind(&PD::builtin_help)(d_, path_) ]
;
group_start
- = ch_p('{') [ bind(&PD::pushDirectory)(d_, path_) ]
+ = ch_p('{') [ bind(&PD::pushDirectory)(d_) ]
;
group_close
= ch_p('}') [ bind(&PD::popDirectory)(d_) ]
;
- statement
- = eps_p [ bind(&PD::beginCommand)(d_, path_) ]
- >> arguments
- >> end_of_statement_expected(statement_end)
- [ bind(&PD::endCommand)(d_) ]
- ;
-
arguments
= * argument
;
[ token_ = construct_<Token>(Token::HexString,
str_) ]
;
+
+ opt_path
+ = ! path [ bind(&PD::beginCommand)(d_, path_) ]
+ [ bind(&PD::endCommand)(d_) ]
+ ;
path // Returns value in context.path
= eps_p [ clear(path_) ]
| ch_p(';') [ token_ = construct_<Token>(
Token::CommandTerminator,
";") ]
- | punctuation_p [ token_ = construct_<Token>(
+ | self.punctuation_p [ token_ = construct_<Token>(
Token::OtherPunctuation,
construct_<std::string>(1u, arg1)) ]
;
word // Returns value in context.token
= lexeme_d
[
- (+ word_p) [ str_ = construct_<std::string>(arg1, arg2) ]
+ (+ self.word_p) [ str_ = construct_<std::string>(arg1, arg2) ]
]
>> eps_p [ token_ = construct_<Token>(
Token::Word,
;
skip
- = space_p | comment_p('#')
+ = self.space_p | comment_p('#')
;
///////////////////////////////////////////////////////////////////
start_parsers(
command, // CommandParser
skip, // SkipParser
- arguments // ArgumentsParser
+ arguments, // ArgumentsParser
+ opt_path // PathParser
);
BOOST_SPIRIT_DEBUG_TRACE_RULE(command,1);
};
};
+ template <class PD> boost::spirit::chset<> CommandGrammar<PD>::special_p (
+ "/(){};\"");
+ template <class PD> boost::spirit::chset<> CommandGrammar<PD>::punctuation_p (
+ ",=");
+ template <class PD> boost::spirit::chset<> CommandGrammar<PD>::space_p (
+ " \t\n\r");
+ template <class PD> boost::spirit::chset<> CommandGrammar<PD>::invalid_p (
+ (boost::spirit::chset<>('\0') | boost::spirit::chset<>("\x01-\x20")) - space_p );
+ template <class PD> boost::spirit::chset<> CommandGrammar<PD>::word_p (
+ boost::spirit::anychar_p - special_p - punctuation_p - space_p - invalid_p);
+ template <class PD> boost::spirit::distinct_parser<> CommandGrammar<PD>::keyword_p (
+ word_p | boost::spirit::ch_p('/'));
+
#endif
}}}