When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are $$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$

Gaudi Parser migration guideline

We are currently migrating from Boost Spirit v1.x (Classic) to Spirit v2.x. The new Spirit version is not back compatible with old one and all user's grammars should be rewritten. The purpose of this guide is to help you with migration.

Original grammar

// ============================================================================
// GaudiKernel
// ============================================================================
#include "GaudiKernel/Parsers.h"
#include "GaudiKernel/Grammars.h"
#include "GaudiKernel/Parsers.icpp"
// ============================================================================
namespace Gaudi
{
  // ==========================================================================
  namespace Parsers 
  {
    // ========================================================================
    /** @class ValueWithErrorGrammar  
     *
     *  The valid represenation of value with error are:
     *     "( 34 +- 10 )" , "( 34 , 10 )" , "34"  
     *
     *  @author Vanya BELYAEV  Ivan.Belyaev@nikhef.nl
     *  @date 2009-09-13
     */
    class ValueWithErrorGrammar 
      : public grammar
    <
      ValueWithErrorGrammar,
      ClosureGrammar<Gaudi::Math::ValueWithError>::context_t
    >
    {
    public:
      // ======================================================================
      typedef RealGrammar<double>                               ValueGrammarT ;
      typedef Gaudi::Math::ValueWithError                             ResultT ;
      // ======================================================================
    public:
      // ======================================================================
      /// callback. Action when we match first value
      void matchValue  ( const ValueGrammarT::ResultT v ) const
      { this->val().setValue ( v ) ; }
      /// callback. Action when we match second value
      void matchError  ( const ValueGrammarT::ResultT e ) const 
      { this->val().setError ( e ) ; }
      // ======================================================================
    public:
      // ============================================================
      template <typename ScannerT>
      struct definition
      {
        //
        definition ( ValueWithErrorGrammar const &self)
        {
          vale = 
            ( 
             str_p("(") 
             >> grvalue [boost::bind(&ValueWithErrorGrammar::matchValue,&self,_1)]
             >> !( ( str_p( "+-" ) | ',' | ';' ) 
                   >> grvalue [boost::bind(&ValueWithErrorGrammar::matchError,&self,_1)]) 
             >> ')' 
             ) | grvalue [boost::bind(&ValueWithErrorGrammar::matchValue,&self,_1)] ;
        }
        // 
        rule<ScannerT> const& start() const { return vale; }
        rule<ScannerT> vale;
        ValueGrammarT  grvalue ;
      } ;
      // ======================================================================
    } ;
    // ========================================================================
  } //                                          end of namespace Gaudi::Parsers 
  // ==========================================================================
} //                                                     end of namespace Gaudi
// ============================================================================
// =============================================================================
/*  parse the input string into the result 
 *  @param result (output) the result 
 *  @param input  (input) input string
 *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
 *  @date 2009-09-13
 */     
// =============================================================================
StatusCode Gaudi::Parsers::parse 
( Gaudi::Math::ValueWithError& result , 
  const std::string&           input  ) 
{
  ValueWithErrorGrammar gr ;
  //
  return parse
    ( createIterator ( input ) , 
      IteratorT ()             ,
      gr[var(result)=arg1]     , 
      SkipperGrammar()         ).full ;
}
// =============================================================================
/* parse the input string into the result 
 *  @param result (output) the result 
 *  @param input  (input) input string
 *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
 *  @date 2009-09-13
 */     
// =============================================================================
StatusCode Gaudi::Parsers::parse 
( std::vector<Gaudi::Math::ValueWithError>& result , 
  const std::string&                        input  ) 
{
  VectorGrammar<ValueWithErrorGrammar> gr ;
  // 
  return parse 
    ( createIterator ( input ) , 
      IteratorT ()             ,
      gr[var(result)=arg1]     ,
      SkipperGrammar()         ) . full ;
}
// =============================================================================

New grammar

// ============================================================================
// GaudiKernel
// ============================================================================
#include "GaudiKernel/ParsersFactory.h"
// ============================================================================
namespace Gaudi
{
  // ==========================================================================
  namespace Parsers
  {
    // ========================================================================
    /** @class ValueWithErrorGrammar
     *
     *  The valid represenation of value with error are:
     *     "( 34 +- 10 )" , "( 34 , 10 )" , "34"
     *
     *  @author Vanya BELYAEV  Ivan.Belyaev@nikhef.nl
     *  @author Alexander Mazurov  alexander.mazurov@gmail.com
     *  @date 2011-07-27
     */
    template< typename Iterator, typename Skipper>
    class ValueWithErrorGrammar:
       public qi::grammar<Iterator,Gaudi::Math::ValueWithError(), Skipper> {
     // =======================================================================
     public: // Result type
       typedef Gaudi::Math::ValueWithError ResultT ;
     // =======================================================================
     public: // Grammar is defined at the constructor:
      ValueWithErrorGrammar() :ValueWithErrorGrammar::base_type(value) {
          value = ( qi::lit("(") >> grvalue[op(qi::_val,qi::_1)]
             >> -((qi::lit("+-") | qi::lit(',') | qi::lit(';'))
                   >> grvalue[op(qi::_val,qi::_1, tag_error())])
             >> ')'
             ) | grvalue[op(qi::_val,qi::_1)] ;
        }
     // =======================================================================
     private:  // Rules and grammars:
      // Start rule should have the same template parameters as
      // qi::grammar at the class declaration:
      qi::rule<Iterator, Gaudi::Math::ValueWithError(), Skipper> value;
      RealGrammar<Iterator, double, Skipper> grvalue;
     // =======================================================================
     private: // Semantic actions:
      struct tag_error{};
      struct Operations {
        // Some magic:
        template <typename A, typename B = boost::fusion::unused_type,
            typename C = boost::fusion::unused_type,
            typename D = boost::fusion::unused_type>
        struct result { typedef void type; };
        // Actions:
        // --------------------------------------------------------------------
        void operator()(Gaudi::Math::ValueWithError& val, double v) const {
          val.setValue(v);
        }
        void operator()(Gaudi::Math::ValueWithError& val, double err,
            tag_error) const {
          val.setError(err);
        }
        // --------------------------------------------------------------------
      };  // End of Operations
      // ----------------------------------------------------------------------
      ph::function<Operations> op;
    };
    // ========================================================================
    REGISTER_GRAMMAR(Gaudi::Math::ValueWithError, ValueWithErrorGrammar);
    // ========================================================================
  } //                                          end of namespace Gaudi::Parsers
  // ==========================================================================
} //                                                     end of namespace Gaudi
// ============================================================================


// =============================================================================
/*  parse the input string into the result
 *  @param result (output) the result
 *  @param input  (input) input string
 *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
 *  @date 2009-09-13
 */
// =============================================================================
StatusCode Gaudi::Parsers::parse(Gaudi::Math::ValueWithError& result,
    const std::string& input) {
  return parse_(result, input);
}
// =============================================================================
/* parse the input string into the result
 *  @param result (output) the result
 *  @param input  (input) input string
 *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
 *  @date 2009-09-13
 */
// =============================================================================
StatusCode Gaudi::Parsers::parse(
    std::vector<Gaudi::Math::ValueWithError>& result,
    const std::string& input) {
  return parse_(result, input);
}

Include files

Original

#include "GaudiKernel/Parsers.h"
#include "GaudiKernel/Grammars.h"
#include "GaudiKernel/Parsers.icpp"

New

#include "GaudiKernel/ParsersFactory.h"

Grammar class declaration

class ValueWithErrorGrammar: 
  public grammar<ValueWithErrorGrammar, ClosureGrammar<Gaudi::Math::ValueWithError>::context_t>
template< typename Iterator, typename Skipper> 
  class ValueWithErrorGrammar:  
     public qi::grammar<Iterator,Gaudi::Math::ValueWithError(), Skipper>
  • Gaudi::Math::ValueWithError — is the grammar result type

Grammar definition

template <typename ScannerT>
      struct definition
      {
        //
        definition ( ValueWithErrorGrammar const &self)
        {
          vale = 
            ( 
             str_p("(") 
             >> grvalue [boost::bind(&ValueWithErrorGrammar::matchValue,&self,_1)]
             >> !( ( str_p( "+-" ) | ',' | ';' ) 
                   >> grvalue [boost::bind(&ValueWithErrorGrammar::matchError,&self,_1)]) 
             >> ')' 
             ) | grvalue [boost::bind(&ValueWithErrorGrammar::matchValue,&self,_1)] ;
        }
        // 
        rule<ScannerT> const& start() const { return vale; }
        rule<ScannerT> vale;
        ValueGrammarT  grvalue ;
      } ;
ValueWithErrorGrammar() :ValueWithErrorGrammar::base_type(value) {
          value = ( qi::lit("(") >> grvalue[op(qi::_val,qi::_1)]
             >> -((qi::lit("+-") | qi::lit(',') | qi::lit(';'))
                   >> grvalue[op(qi::_val,qi::_1, tag_error())])
             >> ')'
             ) | grvalue[op(qi::_val,qi::_1)] ;
        }
  • The grammar is now defined at the grammar's class constructor and not at a separate structure (struct definition).
  • ValueWithErrorGrammar::base_type(value) — defines a grammar's start rule.

Grammar's inner rules and grammars declaration

rule<ScannerT> const& start() const { return vale; }
rule<ScannerT> vale;
ValueGrammarT  grvalue ;
// Start rule should have the same template parameters as
// qi::grammar at the class declaration:
qi::rule<Iterator, Gaudi::Math::ValueWithError(), Skipper> value;
RealGrammar<Iterator, double, Skipper> grvalue;
  • Start rule should have the same template parameters as qi::grammar at the class declaration

Semantic actions

* bind functions
vale = 
            ( 
             str_p("(") 
             >> grvalue [boost::bind(&ValueWithErrorGrammar::matchValue,&self,_1)]
             >> !( ( str_p( "+-" ) | ',' | ';' ) 
                   >> grvalue [boost::bind(&ValueWithErrorGrammar::matchError,&self,_1)]) 
             >> ')' 
             ) | grvalue [boost::bind(&ValueWithErrorGrammar::matchValue,&self,_1)] ;
* call op functor (declataion is shown at the next section)
value = ( qi::lit("(") >> grvalue[op(qi::_val,qi::_1)]
             >> -((qi::lit("+-") | qi::lit(',') | qi::lit(';'))
                   >> grvalue[op(qi::_val,qi::_1, tag_error())])
             >> ')'
             ) | grvalue[op(qi::_val,qi::_1)] ;
  • qi::_val — is assign's left side rule's attribute: qi::rule<Iterator, *Gaudi::Math::ValueWithError*(), Skipper> value;
  • qi::_1 — is a attribute of rule which stands on left from semantic action: RealGrammar<Iterator, double, Skipper> grvalue
  • tag_error — is a user defined empty struct which is used only for choosing right type of operation (see the next section).

Semantic action's declaration

/// callback. Action when we match first value
void matchValue  ( const ValueGrammarT::ResultT v ) const
{ this->val().setValue ( v ) ; }
/// callback. Action when we match second value
void matchError  ( const ValueGrammarT::ResultT e ) const 
{ this->val().setError ( e ) ; }
* this->val() — is a grammar's result type.
struct tag_error{};
 struct Operations {
        // Some magic:
        template <typename A, typename B = boost::fusion::unused_type,
            typename C = boost::fusion::unused_type,
            typename D = boost::fusion::unused_type>
        struct result { typedef void type; };
        // Actions:
        // --------------------------------------------------------------------
        void operator()(Gaudi::Math::ValueWithError& val, double v) const {
          val.setValue(v);
        }
        void operator()(Gaudi::Math::ValueWithError& val, double err,
            tag_error) const {
          val.setError(err);
        }
        // --------------------------------------------------------------------
 };  // End of Operations
// ----------------------------------------------------------------------
ph::function<Operations> op;
  • Operation's class declaration contains some magic in header :/
  • Operation's class is a functor where each operator () is a some semantic action.
  • At operations we have access only to input parameters. We can't access grammar's result type directly.
  • rule_left = rule_right; — In this case attribute of rule_right will be implicitly copied to rule_left's attribute
  • rule_left = rule_right[op(qi::_val, qi::_1)] — if at the right site we explicitly use semantic actions (in [...]) then attribute from right side will not be copied implicitly.

Create parser functions

First you need to to execute macro REGISTER_GRAMMAR
REGISTER_GRAMMAR(Gaudi::Math::ValueWithError, ValueWithErrorGrammar);

After this step you automatically will get a parser for Gaudi::Math::ValueWithError together with a set of containter parsers based on your type (vectors of ValueWithError, vector of vectors of ValueWithError, maps with different types for which grammars already exists). The parser function is now StatusCode Gaudi::Parsers::parse_(YourType& output, const std::string& input);

To use your parser in Gaudi properties we need to create the corresponding parse function. For example:

// =============================================================================
/*  parse the input string into the result
 *  @param result (output) the result
 *  @param input  (input) input string
 *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
 *  @date 2009-09-13
 */
// =============================================================================
StatusCode Gaudi::Parsers::parse(Gaudi::Math::ValueWithError& result,
    const std::string& input) {
  return parse_(result, input);
}
// =============================================================================
/* parse the input string into the result
 *  @param result (output) the result
 *  @param input  (input) input string
 *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
 *  @date 2009-09-13
 */
// =============================================================================
StatusCode Gaudi::Parsers::parse(
    std::vector<Gaudi::Math::ValueWithError>& result,
    const std::string& input) {
  return parse_(result, input);
}
-- SashaMazurov - 18 Jun 2007
Edit | Attach | Watch | Print version | History: r7 < r6 < r5 < r4 < r3 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r7 - 2011-10-24 - SashaMazurov
 
    • Cern Search Icon Cern Search
    • TWiki Search Icon TWiki Search
    • Google Search Icon Google Search

    Sandbox All webs login

This site is powered by the TWiki collaboration platform Powered by PerlCopyright & 2008-2020 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
or Ideas, requests, problems regarding TWiki? use Discourse or Send feedback