LifeV
ParserSpiritGrammar.hpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  * @file
29  * @brief File containing the Boost Spirit parser grammar
30  *
31  * @date 05-02-2010
32  * @author Cristiano Malossi <cristiano.malossi@epfl.ch>
33  *
34  * @maintainer Cristiano Malossi <cristiano.malossi@epfl.ch>
35  */
36 
37 #ifndef Parser_SpiritGrammar_H
38 #define Parser_SpiritGrammar_H 1
39 
40 #include <lifev/core/util/ParserDefinitions.hpp>
41 
42 namespace LifeV
43 {
44 
45 #if ( !defined(HAVE_BOOST_SPIRIT_QI) || !defined(ENABLE_SPIRIT_PARSER) )
46 
47 /// @cond
48 //! ParserSpiritGrammar - An empty implementation for boost version < 1.41
49 template < typename IteratorType = std::string::const_iterator, typename ResultsType = std::vector < Real > >
50 class ParserSpiritGrammar
51 {
52 public:
53 
54  typedef IteratorType iterator_Type;
55  typedef boost::iterator_range< iterator_Type > iteratorRange_Type;
56  typedef ResultsType results_Type;
57 
58  ParserSpiritGrammar() : M_real (0.) {}
59  ParserSpiritGrammar ( const ParserSpiritGrammar& ) : M_real (0.) {}
60  ~ParserSpiritGrammar() {}
61 
62  ParserSpiritGrammar& operator= ( const ParserSpiritGrammar& )
63  {
64  return *this;
65  }
66 
67  void clearVariables() {}
68 
69  void setDefaultVariables() {}
70  void setVariable ( const std::string&, const Real& ) {}
71 
72  Real& variable ( const std::string& )
73  {
74  return M_real;
75  }
76 
77 private:
78 
79  Real M_real;
80 };
81 /// @endcond
82 
83 #else
84 
85 //! ParserSpiritGrammar - A string parser grammar based on \c boost::spirit::qi
86 /*!
87  * @author(s) Cristiano Malossi
88  *
89  * \c ParserSpiritGrammar is a \c boost::spirit::qi based class to perform
90  * evaluation of \c std::string expressions.
91  *
92  * <b>EXAMPLE - HOW TO USE</b>
93  * Let's consider the following example: suppose that we have this function:
94  *
95  * [u,v,w] = f(x,y,z,t)
96  *
97  * where
98  *
99  * u(x) = a*b*x
100  * v(x,y) = a/b*sqrt(x^2 + y^2)
101  * w(t) = b*t;
102  *
103  * with "a" and "b" constants such that a=5.12345, b=9.999999.
104  *
105  * To evaluate function f(x,y,z,t), we use this syntax:
106  *
107  * <CODE>
108  * string = "a=5.12345 ; b=9.999999 ; (a*b*x, a/b*sqrt(x^2 + y^2), b*t)"
109  * </CODE>
110  *
111  * where semicolons (";") separate constants and commas (",") separate output functions.
112  *
113  * NOTE:
114  * Currently ParserSpiritGrammar works with the following operators:
115  * \verbatim
116  * +, -, *, /, ^, sqrt(), sin(), cos(), tan(), exp(), log(), log10(), >, <.
117  * \endverbatim
118  *
119  */
120 template < typename IteratorType = std::string::const_iterator, typename ResultsType = std::vector < Real > >
122 {
123 public:
124 
125  //! @name Public Types
126  //@{
127 
128  /*! @typedef iterator_Type */
129  //! Type definition for the iterator
130  typedef IteratorType iterator_Type;
131 
132  /*! @typedef iteratorRange_Type */
133  //!Type definition for the iterator range
135 
136  /*! @typedef results_Type */
137  //! Type definition for the results
138  typedef ResultsType results_Type;
139 
140  /*! @typedef qiRuleVoid_Type */
141  //! Type definition for the void rule of the parser
142  typedef qi::rule< iterator_Type, void(), ascii::space_type > qiRuleVoid_Type;
143 
144  /*! @typedef qiRuleReal_Type */
145  //! Type definition for the Real rule of the parser
147 
148  /*! @typedef qiRuleResults_Type */
149  //! Type definition for the result rule of the parser
151 
152  /*! @typedef qiSymbolReal_Type */
153  //! Type definition for the Real symbol of the parser
154  typedef qi::symbols<char, Real > qiSymbolReal_Type;
155 
156  //@}
157 
158 
159  //! @name Constructors & Destructor
160  //@{
161 
162  //! Constructor
163  explicit ParserSpiritGrammar();
164 
165  //! Copy constructor
166  /*!
167  * @param ParserSpiritGrammar ParserSpiritGrammar
168  */
170 
171  //! Destructor
172  virtual ~ParserSpiritGrammar() {}
173 
174  //@}
175 
176 
177  //! @name Operators
178  //@{
179 
180  //! Operator =
181  /*!
182  * @param SpiritGrammar ParserSpiritGrammar
183  * @return reference to a copy of the class
184  */
186 
187  //@}
188 
189 
190  //! @name Methods
191  //@{
192 
193  //! Assign a variable using a \c boost::iterator_range
194  /*!
195  * @param stringIteratorRange name of the parameter
196  * @param value value of the parameter
197  */
199  {
201  }
202 
203  //! Clear all the variables.
204  void clearVariables()
205  {
206  M_variable.clear();
207  }
208 
209  /* TODO Implement the showMe and use the M_command to enable it.
210  * Note that the M_command is a rule to execute commands given in the strings, e.g.:
211  * string = "a=1; b=2; showMe; a*t+b" means that first we set the variables "a" and "b",
212  * then we call the command showMe (to display the variables) and finally we evaluate
213  * the function, i.e., "f=a*t+b", where t is the time.
214  */
215  // //! Show all the variables
216  // void ShowMe() { std::cout << "To be implemented" << std::endl; }
217 
218  //@}
219 
220 
221  //! @name Set Methods
222  //@{
223 
224  //! Set default variables
225  void setDefaultVariables();
226 
227  //! Set/replace a variable
228  /*!
229  * @param name name of the parameter
230  * @param value value of the parameter
231  */
232  void setVariable ( const std::string& name, const Real& value );
233 
234  //@}
235 
236  //! @name Get Methods
237  //@{
238 
239  //! Get variable
240  /*!
241  * @param name name of the parameter
242  * @return value of the variable
243  */
244  Real& variable ( const std::string& name )
245  {
246  return M_variable.at ( name );
247  }
248 
249  //@}
250 
251 private:
252 
253  //! @name Private Methods
254  //@
255 
256  //! Phoenix wrapper for \c std::sin
257  /*!
258  * @param value input value
259  * @return sin( value )
260  */
261  Real sin ( const Real& value ) const
262  {
263  return std::sin ( value );
264  }
265 
266  //! Phoenix wrapper for \c std::cos
267  /*!
268  * @param value input value
269  * @return cos( value )
270  */
271  Real cos ( const Real& value ) const
272  {
273  return std::cos ( value );
274  }
275 
276  //! Phoenix wrapper for \c std::tan
277  /*!
278  * @param value input value
279  * @return tan( value )
280  */
281  Real tan ( const Real& value ) const
282  {
283  return std::tan ( value );
284  }
285 
286  //! Phoenix wrapper for \c std::pow
287  /*!
288  * @param base input base
289  * @param exponent input exponent
290  * @return pow( base, exponent )
291  */
292  Real pow ( const Real& Base, const Real& Exponent ) const
293  {
294  return std::pow ( Base, Exponent );
295  }
296 
297  //! Phoenix wrapper for \c std::sqrt
298  /*!
299  * @param value input value
300  * @return sqrt( value )
301  */
302  Real sqrt ( const Real& value ) const
303  {
304  return std::sqrt ( value );
305  }
306 
307  //! Phoenix wrapper for \c std::exp
308  /*!
309  * @param value input value
310  * @return exp( value )
311  */
312  Real exp ( const Real& value ) const
313  {
314  return std::exp ( value );
315  }
316 
317  //! Phoenix wrapper for \c std::log
318  /*!
319  * @param value input value
320  * @return log( value )
321  */
322  Real log ( const Real& value ) const
323  {
324  return std::log ( value );
325  }
326 
327  //! Phoenix wrapper for \c std::log10
328  /*!
329  * @param value input value
330  * @return log10( value )
331  */
332  Real log10 ( const Real& value ) const
333  {
334  return std::log10 ( value );
335  }
336 
337  //@}
338 
340 
342  // qiRuleVoid_Type M_command;
343 
353 
355 };
356 
357 
358 
359 // ===================================================
360 // Constructors & Destructor
361 // ===================================================
362 template < typename IteratorType, typename ResultsType >
365  M_start (),
366  M_assignment (),
367  // M_command (),
368  M_expression (),
369  M_compare (),
370  M_plusMinus (),
371  M_multiplyDivide (),
372  M_elevate (),
373  M_element (),
374  M_number (),
375  M_function (),
376  M_group (),
377  M_variable ()
378 {
379  M_start =
380  (
382  // | M_command
383  | ( -qi::lit ('[') >> M_expression % ',' >> -qi::lit (']') )
384  )
385  ;
386 
387  M_assignment =
388  (
389  qi::raw[qi::lexeme[ (qi::alpha | '_') >> * (qi::alnum | '_')]]
390  >> qi::lit ('=')
391  >> M_expression
393  ;
394  /*
395  M_command =
396  qi::lit("ShowMe")[phoenix::bind(&ParserSpiritGrammar::ShowMe, this)]
397  ;
398  */
399 
400  M_expression =
401  *M_compare [qi::_val = qi::_1]
402  ;
403 
404  M_compare =
405  M_plusMinus [qi::_val = qi::_1]
406  >> * (
407  qi::lit (">=") >> M_plusMinus [qi::_val = qi::_val >= qi::_1]
408  | qi::lit ("<=") >> M_plusMinus [qi::_val = qi::_val <= qi::_1]
409  | qi::lit (">") >> M_plusMinus [qi::_val = qi::_val > qi::_1]
410  | qi::lit ("<") >> M_plusMinus [qi::_val = qi::_val < qi::_1]
411  )
412  ;
413 
414  M_plusMinus =
416  >> * (
417  qi::lit ('+') >> M_multiplyDivide [qi::_val += qi::_1]
418  | qi::lit ('-') >> M_multiplyDivide [qi::_val -= qi::_1]
419  )
420  ;
421 
423  M_elevate [qi::_val = qi::_1]
424  >> * (
425  qi::lit ('*') >> M_elevate [qi::_val *= qi::_1]
426  | qi::lit ('/') >> M_elevate [qi::_val /= qi::_1]
427  )
428  ;
429 
430  M_elevate =
431  (
432  qi::lit ('-') >> M_element [qi::_val = qi::_1]
433  >> (
435  this, qi::_val, qi::_1)]
436  )
437  >> * (
439  this, qi::_val, qi::_1)]
440  )
441  )
442  |
443  (
444  M_element [qi::_val = qi::_1]
445  >> * (
447  this, qi::_val, qi::_1)]
448  )
449  )
450  ;
451 
452  M_element =
453  (
454  qi::lit ('-') >> M_element [qi::_val = -qi::_1]
455  )
456  |
457  (
458  M_number [qi::_val = qi::_1]
459  | M_function [qi::_val = qi::_1]
460  | M_variable [qi::_val = qi::_1]
461  | M_group [qi::_val = qi::_1]
462  )
463  ;
464 
465  M_number =
466  (
467  qi::double_
468  // || ('.' >> qi::double_)
469  // >> -('.' >> qi::double_) | ('.' >> qi::double_)
470  )
471  ;
472 
473  M_function =
474  (
475  qi::lit ("sin") >> M_group [qi::_val = phoenix::bind (&ParserSpiritGrammar::sin, this, qi::_1)]
476  | qi::lit ("cos") >> M_group [qi::_val = phoenix::bind (&ParserSpiritGrammar::cos, this, qi::_1)]
477  | qi::lit ("tan") >> M_group [qi::_val = phoenix::bind (&ParserSpiritGrammar::tan, this, qi::_1)]
478  | qi::lit ("sqrt") >> M_group [qi::_val = phoenix::bind (&ParserSpiritGrammar::sqrt, this, qi::_1)]
479  | qi::lit ("exp") >> M_group [qi::_val = phoenix::bind (&ParserSpiritGrammar::exp, this, qi::_1)]
480  | qi::lit ("log") >> M_group [qi::_val = phoenix::bind (&ParserSpiritGrammar::log, this, qi::_1)]
481  | qi::lit ("log10") >> M_group [qi::_val = phoenix::bind (&ParserSpiritGrammar::log10, this, qi::_1)]
482  )
483  ;
484 
485  M_group =
486  (
487  '('
488  >> M_expression [qi::_val = qi::_1]
489  >> ')'
490  )
491  ;
492 }
493 
494 template < typename IteratorType, typename ResultsType >
499  // M_command ( spiritGrammar.M_command ),
510 {
511 }
512 
513 // ===================================================
514 // Operators
515 // ===================================================
516 template < typename IteratorType, typename ResultsType >
519 {
520  if ( this != &spiritGrammar )
521  {
525  // M_command = spiritGrammar.M_command;
536  }
537 
538  return *this;
539 }
540 
541 // ===================================================
542 // Set Methods
543 // ===================================================
544 template < typename IteratorType, typename ResultsType >
545 inline void
547 {
548  M_variable.add ( "pi" , M_PI );
549  M_variable.add ( "e", M_E );
550 }
551 
552 template < typename IteratorType, typename ResultsType >
553 inline void
555 {
556  Real* p = M_variable.find ( name );
557  if ( p != 0 )
558  {
559  *p = value;
560  }
561  else
562  {
563  M_variable.add ( name, value );
564  }
565 }
566 
567 #endif /* HAVE_BOOST_SPIRIT_QI || !ENABLE_SPIRIT_PARSER */
568 
569 } // Namespace LifeV
570 
571 #endif /* Parser_SpiritGrammar_H */
void updateInverseJacobian(const UInt &iQuadPt)
double Real
Generic real data.
Definition: LifeV.hpp:175