musrfit 1.10.0
PFunctionGrammar.h
Go to the documentation of this file.
1/***************************************************************************
2
3 PFunctionGrammar.h
4
5 Author: Andreas Suter
6 e-mail: andreas.suter@psi.ch
7
8 Header-only grammar for parsing function entries in msr-file FUNCTION blocks.
9 This version uses Boost.Spirit X3 in header-only mode for maximum compatibility.
10
11***************************************************************************/
12
13/***************************************************************************
14 * Copyright (C) 2007-2026 by Andreas Suter *
15 * andreas.suter@psi.ch *
16 * *
17 * This program is free software; you can redistribute it and/or modify *
18 * it under the terms of the GNU General Public License as published by *
19 * the Free Software Foundation; either version 2 of the License, or *
20 * (at your option) any later version. *
21 * *
22 * This program is distributed in the hope that it will be useful, *
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
25 * GNU General Public License for more details. *
26 * *
27 * You should have received a copy of the GNU General Public License *
28 * along with this program; if not, write to the *
29 * Free Software Foundation, Inc., *
30 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
31 ***************************************************************************/
32
33#ifndef _PFUNCTIONGRAMMAR_H_
34#define _PFUNCTIONGRAMMAR_H_
35
36// Check Boost version - require 1.61+ for Spirit X3
37#include <boost/version.hpp>
38#if BOOST_VERSION < 106100
39# error "Boost version 1.61.0 or higher is required for Spirit X3. Please upgrade Boost."
40#endif
41
42#include "PFunctionAst.h"
43#include <boost/spirit/home/x3.hpp>
44
45namespace x3 = boost::spirit::x3;
46
58namespace musrfit { namespace grammar
59{
60 using x3::int_;
61 using x3::double_;
62 using x3::lit;
63 using x3::lexeme;
64 using x3::attr;
65
67 // Symbol tables - using inline to avoid multiple definition errors
69
76 struct additive_op_ : x3::symbols<ast::optoken>
77 {
79 {
80 add("+", ast::op_plus)("-", ast::op_minus);
81 }
82 };
83
85
92 struct multiplicative_op_ : x3::symbols<ast::optoken>
93 {
95 {
96 add("*", ast::op_times)("/", ast::op_divide);
97 }
98 };
99
101
109 struct fun_tok_ : x3::symbols<ast::funid>
110 {
112 {
113 add
114 ("COS", ast::fun_cos)
115 ("SIN", ast::fun_sin)
116 ("TAN", ast::fun_tan)
117 ("COSH", ast::fun_cosh)
118 ("SINH", ast::fun_sinh)
119 ("TANH", ast::fun_tanh)
120 ("ACOS", ast::fun_acos)
121 ("ASIN", ast::fun_asin)
122 ("ATAN", ast::fun_atan)
123 ("ACOSH", ast::fun_acosh)
124 ("ASINH", ast::fun_asinh)
125 ("ATANH", ast::fun_atanh)
126 ("LOG", ast::fun_log)
127 ("LN", ast::fun_ln)
128 ("EXP", ast::fun_exp)
129 ("SQRT", ast::fun_sqrt);
130 }
131 };
132
134
141 struct const_tok_ : x3::symbols<ast::constant::type>
142 {
144 {
145 add("PI", ast::constant::pi)("GAMMA_MU", ast::constant::gamma_mu);
146 }
147 };
148
150
152 // Grammar Rules - Forward Declarations
154
156 x3::rule<class assignment, ast::assignment> const assignment = "assignment";
157
159 x3::rule<class expression, ast::expression> const expression = "expression";
160
162 x3::rule<class term, ast::expression> const term = "term";
163
165 x3::rule<class factor, ast::operand> const factor = "factor";
166
168 x3::rule<class constant, ast::constant> const constant = "constant";
169
171 x3::rule<class parameter, ast::parameter> const parameter = "parameter";
172
174 x3::rule<class map_ref, ast::map_ref> const map = "map";
175
177 x3::rule<class function_call, ast::function_call> const function = "function";
178
180 x3::rule<class power_call, ast::power_call> const power = "power";
181
183 // Grammar Rule Definitions
185
192 auto const assignment_def =
193 lit("FUN") >> int_ >> '=' >> expression;
194
201 auto const expression_def =
202 term >> *(additive_op >> term);
203
210 auto const term_def =
212
220 auto const factor_def =
221 double_
222 | constant
223 | parameter
224 | map
225 | function
226 | power
227 | ('(' >> expression >> ')');
228
235 auto const constant_def =
236 (const_tok >> attr(false) >> attr(0))
237 | (lit("B") >> attr(ast::constant::field) >> attr(false) >> attr(0))
238 | (lit("-B") >> attr(ast::constant::field) >> attr(true) >> attr(0))
239 | (lit("EN") >> attr(ast::constant::energy) >> attr(false) >> attr(0))
240 | (lit("-EN") >> attr(ast::constant::energy) >> attr(true) >> attr(0))
241 | (lit('T') >> attr(ast::constant::temp) >> attr(false) >> int_)
242 | (lit("-T") >> attr(ast::constant::temp) >> attr(true) >> int_);
243
251 auto const parameter_def =
252 (lexeme[lit("-PAR") >> int_] >> attr(true))
253 | (lit("PAR") >> int_ >> attr(false));
254
261 auto const map_def =
262 (lexeme[lit("-MAP") >> int_] >> attr(true))
263 | (lit("MAP") >> int_ >> attr(false));
264
271 auto const function_def =
272 fun_tok >> '(' >> expression >> ')';
273
280 auto const power_def =
281 lit("POW") >> '(' >> expression >> ',' >> expression >> ')';
282
289 BOOST_SPIRIT_DEFINE(
292 term,
293 factor,
294 constant,
295 parameter,
296 map,
297 function,
298 power
299 )
300
301}}
302
307namespace musrfit {
322 inline auto const& function_grammar()
323 {
324 return grammar::assignment;
325 }
326}
327
328#endif // _PFUNCTIONGRAMMAR_H_
Boost.Spirit X3 grammar definitions for parsing function expressions.
auto const assignment_def
Assignment rule: FUN# = expression.
fun_tok_ fun_tok
Global instance of function name symbol table.
multiplicative_op_ multiplicative_op
Global instance of multiplicative operator symbol table.
auto const expression_def
Expression rule: term ((+|-) term)*.
x3::rule< class parameter, ast::parameter > const parameter
Parameter reference: PAR# or -PAR#.
x3::rule< class term, ast::expression > const term
Term with multiplication/division (higher precedence)
x3::rule< class function_call, ast::function_call > const function
Function call: FUNC(expression)
auto const function_def
Function rule: FUNC(expression)
auto const factor_def
Factor rule: the atomic elements of expressions.
auto const constant_def
Constant rule: PI | GAMMA_MU | B | -B | EN | -EN | T# | -T#.
additive_op_ additive_op
Global instance of additive operator symbol table.
x3::rule< class map_ref, ast::map_ref > const map
Map reference: MAP# or -MAP#.
x3::rule< class assignment, ast::assignment > const assignment
Top-level rule: FUN# = expression.
auto const term_def
Term rule: factor ((*|/) factor)*.
auto const parameter_def
Parameter rule: PAR# | -PAR#.
auto const map_def
Map rule: MAP# | -MAP#.
x3::rule< class factor, ast::operand > const factor
Factor: literal, constant, parameter, function, or parenthesized expression (highest precedence)
x3::rule< class constant, ast::constant > const constant
Constant: PI, GAMMA_MU, B, EN, or T#.
auto const power_def
Power rule: POW(base, exponent)
x3::rule< class expression, ast::expression > const expression
Expression with addition/subtraction (lowest precedence)
const_tok_ const_tok
Global instance of constant name symbol table.
x3::rule< class power_call, ast::power_call > const power
Power operation: POW(base, exponent)
Top-level namespace for musrfit components.
auto const & function_grammar()
Provides access to the top-level grammar rule.
Symbol table for additive operators (+ and -).
Symbol table for named constants.
Symbol table for mathematical function names.
Symbol table for multiplicative operators (* and /).