X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FParse.ih;h=5129197d9b824b1fae0dfb58bfefaf7805868e89;hb=456ee576285b76aa46240f8001f426757810dcc1;hp=02930e6e4fc132c5d93b8f367aedd0c4e98e9f51;hpb=9c0078ac0054789badff2a987364ed0448b080ef;p=senf.git diff --git a/Console/Parse.ih b/Console/Parse.ih index 02930e6..5129197 100644 --- a/Console/Parse.ih +++ b/Console/Parse.ih @@ -42,6 +42,11 @@ namespace senf { namespace console { namespace detail { +#ifndef DOXYGEN + + /////////////////////////////////////////////////////////////////////////// + // append_a + struct append_action { template @@ -56,16 +61,15 @@ namespace detail { template inline boost::spirit::ref_value_actor append_a(T & ref) - { - return boost::spirit::ref_value_actor(ref); - } + { return boost::spirit::ref_value_actor(ref); } template inline boost::spirit::ref_const_ref_actor append_a(T & ref, Value const & value) - { - return boost::spirit::ref_const_ref_actor(ref, value); - } + { return boost::spirit::ref_const_ref_actor(ref, value); } + + /////////////////////////////////////////////////////////////////////////// + // Grammar template struct CommandGrammar : boost::spirit::grammar > @@ -78,10 +82,21 @@ namespace detail { /////////////////////////////////////////////////////////////////////////// // The parse context (variables needed while parsing) + typedef ArgumentToken::TokenType TokenType; + struct Context { std::string str; std::vector path; char ch; + TokenType type; + + // OUCH ... This is sooooo stupid .. push_back_a and assign_a take their + // arguments by const-reference and STORE the REFERENCE ... they do NOT accept + // literal values !!!!!! + static const TokenType BasicString; + static const TokenType HexString; + static const TokenType Word; + static const std::string EmptyString; }; Context & context; @@ -114,6 +129,10 @@ namespace detail { Dispatch_actor dispatch(Callback cb, Arg const & arg) const { return Dispatch_actor(boost::bind(cb, boost::ref(dispatcher), arg)); } + template + Dispatch_actor dispatch(Callback cb, Arg1 const & arg1, Arg2 const & arg2) const + { return Dispatch_actor(boost::bind(cb, boost::ref(dispatcher), arg1, arg2)); } + /////////////////////////////////////////////////////////////////////////// CommandGrammar(ParseDispatcher & d, Context & c) @@ -136,7 +155,8 @@ namespace detail { special_p ("/(){};"), // Characters which are returned as punctuation tokens - punctuation_p (",="), + // (only allowed within '()') + punctuation_p (",=/{};"), // Whitespace characters space_p (" \t\n\r"), @@ -163,7 +183,7 @@ namespace detail { // Syntax summary: // This is EBNF with some minor tweaks to accommodate C++ syntax // - // * and + precede their argument + // * and + like EBNF but they precede their argument // >> is followed by // ! optional // a % b match any number of a's separated by b @@ -188,7 +208,7 @@ namespace detail { // // Aligned to the right at column 50 are semantic actions. // - // For clarity, I have used 'ch_p' explicitly throughout even though it is auxiliary + // For clarity, I have used 'ch_p' explicitly throughout even though it is optional // in most cases. // // More info is in the Boost.Spirit documentation @@ -237,6 +257,7 @@ namespace detail { argument = simple_argument [ self.dispatch(&PD::pushArgument, + boost::ref(self.context.type), boost::ref(self.context.str)) ] | complex_argument ; @@ -255,6 +276,8 @@ namespace detail { string // Returns value in context.str = eps_p [ clear_a(self.context.str) ] + >> eps_p [ assign_a(self.context.type, + self.context.BasicString) ] >> lexeme_d [ ch_p('"') @@ -269,6 +292,8 @@ namespace detail { hexstring // Returns value in context.str = eps_p [ clear_a(self.context.str) ] + >> eps_p [ assign_a(self.context.type, + self.context.HexString) ] >> confix_p( "x\"", * hexbyte, '"' ) ; @@ -278,13 +303,15 @@ namespace detail { ; relpath - = ( word [ push_back_a(self.context.path) ] + = ( word [ push_back_a(self.context.path) ] % ch_p('/') ) - >> ( ! ch_p('/') [ push_back_a(self.context.path,"") ] ) + >> ( ! ch_p('/') [ push_back_a(self.context.path, + self.context.EmptyString) ] ) ; abspath - = ch_p('/') [ push_back_a(self.context.path, "") ] + = ch_p('/') [ push_back_a(self.context.path, + self.context.EmptyString) ] >> ( relpath | eps_p [ push_back_a(self.context.path, "") ] ) ; @@ -296,7 +323,8 @@ namespace detail { ; token - = simple_argument [ self.dispatch(&PD::pushWord, + = simple_argument [ self.dispatch(&PD::pushWord, + boost::ref(self.context.type), boost::ref(self.context.str)) ] | punctuation [ self.dispatch(&PD::pushPunctuation, boost::ref(self.context.str)) ] @@ -308,7 +336,12 @@ namespace detail { ; word // Returns value in context.str - = lexeme_d[ + word_p ] [ assign_a(self.context.str) ] + = lexeme_d + [ + eps_p [ assign_a(self.context.type, + self.context.Word) ] + >> (+ word_p) [ assign_a(self.context.str) ] + ] ; hexbyte @@ -349,6 +382,23 @@ namespace detail { }; }; + template + ArgumentToken::TokenType const CommandGrammar::Context::BasicString ( + ArgumentToken::BasicString); + + template + ArgumentToken::TokenType const CommandGrammar::Context::HexString( + ArgumentToken::HexString); + + template + ArgumentToken::TokenType const CommandGrammar::Context::Word( + ArgumentToken::Word); + + template + std::string const CommandGrammar::Context::EmptyString; + +#endif + }}} ///////////////////////////////ih.e////////////////////////////////////////