test spirit parser moved from classic to X3.
This commit is contained in:
306
src/tests/spirit/PFunctionAst.h
Normal file
306
src/tests/spirit/PFunctionAst.h
Normal file
@@ -0,0 +1,306 @@
|
||||
/***************************************************************************
|
||||
|
||||
PFunctionAst.hpp
|
||||
|
||||
Author: Andreas Suter
|
||||
e-mail: andreas.suter@psi.ch
|
||||
|
||||
Abstract Syntax Tree (AST) definitions for Spirit X3 parser.
|
||||
Migrated from Qi to X3 for improved compile times and cleaner syntax.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2007-2025 by Andreas Suter *
|
||||
* andreas.suter@psi.ch *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _PFUNCTIONAST_HPP_
|
||||
#define _PFUNCTIONAST_HPP_
|
||||
|
||||
#include <boost/config/warning_disable.hpp>
|
||||
#include <boost/variant/recursive_variant.hpp>
|
||||
#include <boost/fusion/include/adapt_struct.hpp>
|
||||
#include <boost/fusion/include/io.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <list>
|
||||
|
||||
namespace musrfit { namespace ast
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* @brief Abstract Syntax Tree (AST) definitions for the function parser.
|
||||
*
|
||||
* This namespace defines the complete AST structure used to represent
|
||||
* parsed function expressions. The AST is built using Boost.Variant for
|
||||
* type-safe unions and Boost.Spirit X3's automatic AST generation from
|
||||
* grammar rules.
|
||||
*
|
||||
* The AST supports:
|
||||
* - Arithmetic operations: +, -, *, /
|
||||
* - Mathematical functions: cos, sin, tan, exp, log, sqrt, pow, etc.
|
||||
* - Constants: PI, GAMMA_MU, field (B), energy (EN), temperature (T#)
|
||||
* - Parameter references: PAR#, -PAR#
|
||||
* - Map references: MAP#
|
||||
* - Function labels: FUN#
|
||||
* - Expression evaluation with proper precedence
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Enumeration of arithmetic operators.
|
||||
*
|
||||
* These tokens represent the fundamental arithmetic operations supported
|
||||
* by the expression evaluator.
|
||||
*/
|
||||
enum optoken
|
||||
{
|
||||
op_plus, ///< Addition operator (+)
|
||||
op_minus, ///< Subtraction operator (-)
|
||||
op_times, ///< Multiplication operator (*)
|
||||
op_divide, ///< Division operator (/)
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enumeration of supported mathematical functions.
|
||||
*
|
||||
* These function identifiers map to standard mathematical operations
|
||||
* evaluated during the semantic analysis phase.
|
||||
*/
|
||||
enum funid
|
||||
{
|
||||
fun_cos, ///< Cosine function
|
||||
fun_sin, ///< Sine function
|
||||
fun_tan, ///< Tangent function
|
||||
fun_cosh, ///< Hyperbolic cosine function
|
||||
fun_sinh, ///< Hyperbolic sine function
|
||||
fun_tanh, ///< Hyperbolic tangent function
|
||||
fun_acos, ///< Arccosine function
|
||||
fun_asin, ///< Arcsine function
|
||||
fun_atan, ///< Arctangent function
|
||||
fun_acosh, ///< Inverse hyperbolic cosine function
|
||||
fun_asinh, ///< Inverse hyperbolic sine function
|
||||
fun_atanh, ///< Inverse hyperbolic tangent function
|
||||
fun_log, ///< Base-10 logarithm function
|
||||
fun_ln, ///< Natural logarithm function
|
||||
fun_exp, ///< Exponential function
|
||||
fun_sqrt ///< Square root function
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents an empty/null AST node.
|
||||
*
|
||||
* Used as a placeholder in variant types where no value is present.
|
||||
*/
|
||||
struct nil {};
|
||||
|
||||
// Forward declarations for recursive AST structures
|
||||
struct expression;
|
||||
struct function_call;
|
||||
struct power_call;
|
||||
|
||||
/**
|
||||
* @brief Represents a constant value in an expression.
|
||||
*
|
||||
* Constants can be:
|
||||
* - Mathematical constants: PI, GAMMA_MU
|
||||
* - Metadata values: B (field), EN (energy), T# (temperature)
|
||||
*/
|
||||
struct constant
|
||||
{
|
||||
/**
|
||||
* @brief Enumeration of constant types.
|
||||
*/
|
||||
enum type {
|
||||
pi, ///< Mathematical constant π (3.14159...)
|
||||
gamma_mu, ///< Muon gyromagnetic ratio constant
|
||||
field, ///< Magnetic field from experimental data (B or -B)
|
||||
energy, ///< Energy from experimental data (EN or -EN)
|
||||
temp ///< Temperature from experimental data (T# or -T#)
|
||||
};
|
||||
|
||||
type const_type; ///< The type of constant
|
||||
bool sign; ///< Sign flag: false for positive, true for negative
|
||||
int index; ///< Index for temperature (T0, T1, T2, ...)
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents a parameter reference in an expression.
|
||||
*
|
||||
* Parameters are fit parameters referenced as PAR# or -PAR#,
|
||||
* where # is the parameter number (1-based).
|
||||
*/
|
||||
struct parameter
|
||||
{
|
||||
int number; ///< Parameter number (extracted from PAR#)
|
||||
bool sign; ///< Sign flag: false for PAR#, true for -PAR#
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents a map reference in an expression.
|
||||
*
|
||||
* Maps provide indirect parameter references: MAP# or -MAP#
|
||||
* references the map vector at index #-1, which then indexes
|
||||
* into the parameter vector.
|
||||
*/
|
||||
struct map_ref
|
||||
{
|
||||
int number; ///< Map number (extracted from MAP#)
|
||||
bool sign; ///< Sign flag: false for MAP#, true for -MAP#
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Variant type representing any operand in an expression.
|
||||
*
|
||||
* An operand can be a literal number, constant, parameter, map reference,
|
||||
* function call, power operation, or parenthesized expression. The variant
|
||||
* uses recursive_wrapper for types that contain expressions to handle
|
||||
* recursive grammar structures.
|
||||
*/
|
||||
typedef boost::variant<
|
||||
nil ///< Empty placeholder
|
||||
, double ///< Numeric literal
|
||||
, constant ///< Constant value
|
||||
, parameter ///< Parameter reference
|
||||
, map_ref ///< Map reference
|
||||
, boost::recursive_wrapper<function_call> ///< Function call (recursive)
|
||||
, boost::recursive_wrapper<power_call> ///< Power operation (recursive)
|
||||
, boost::recursive_wrapper<expression> ///< Parenthesized expression (recursive)
|
||||
>
|
||||
operand;
|
||||
|
||||
/**
|
||||
* @brief Represents a binary operation with an operator and right operand.
|
||||
*
|
||||
* Used in expression chains where the left operand is the accumulated
|
||||
* result from previous operations.
|
||||
*/
|
||||
struct operation
|
||||
{
|
||||
optoken operator_; ///< The binary operator (+, -, *, /)
|
||||
operand operand_; ///< The right-hand operand
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents a complete expression with operator precedence.
|
||||
*
|
||||
* Expressions are built as a first operand followed by a sequence of
|
||||
* operations. This structure naturally encodes operator precedence as
|
||||
* determined by the grammar rules.
|
||||
*/
|
||||
struct expression
|
||||
{
|
||||
operand first; ///< The first operand in the expression
|
||||
std::list<operation> rest; ///< Sequence of operations applied left-to-right
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents a function call with a single argument.
|
||||
*
|
||||
* Examples: COS(PAR1), SQRT(B), EXP(-PAR2 * T0)
|
||||
*/
|
||||
struct function_call
|
||||
{
|
||||
funid func_id; ///< The function identifier
|
||||
expression arg; ///< The argument expression
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents a power operation.
|
||||
*
|
||||
* Syntax: POW(base, exponent)
|
||||
* Both base and exponent are full expressions.
|
||||
*/
|
||||
struct power_call
|
||||
{
|
||||
expression base; ///< The base expression
|
||||
expression pow; ///< The exponent expression
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents an assignment statement.
|
||||
*
|
||||
* Syntax: FUN# = expression
|
||||
* Assigns the result of evaluating the right-hand expression to a
|
||||
* function label.
|
||||
*/
|
||||
struct assignment
|
||||
{
|
||||
int func_number; ///< Function number (extracted from FUN#)
|
||||
expression rhs; ///< The right-hand side expression to evaluate
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Stream output operator for nil nodes (debugging support).
|
||||
* @param out the output stream
|
||||
* @return the output stream for chaining
|
||||
*/
|
||||
inline std::ostream& operator<<(std::ostream& out, nil) { out << std::string("nil"); return out; }
|
||||
}}
|
||||
|
||||
// Boost.Fusion adaptations to make structures compatible with X3 attribute propagation
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
musrfit::ast::constant,
|
||||
(musrfit::ast::constant::type, const_type)
|
||||
(bool, sign)
|
||||
(int, index)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
musrfit::ast::parameter,
|
||||
(int, number)
|
||||
(bool, sign)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
musrfit::ast::map_ref,
|
||||
(int, number)
|
||||
(bool, sign)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
musrfit::ast::operation,
|
||||
(musrfit::ast::optoken, operator_)
|
||||
(musrfit::ast::operand, operand_)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
musrfit::ast::expression,
|
||||
(musrfit::ast::operand, first)
|
||||
(std::list<musrfit::ast::operation>, rest)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
musrfit::ast::function_call,
|
||||
(musrfit::ast::funid, func_id)
|
||||
(musrfit::ast::expression, arg)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
musrfit::ast::power_call,
|
||||
(musrfit::ast::expression, base)
|
||||
(musrfit::ast::expression, pow)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
musrfit::ast::assignment,
|
||||
(int, func_number)
|
||||
(musrfit::ast::expression, rhs)
|
||||
)
|
||||
|
||||
#endif // _PFUNCTIONAST_HPP_
|
||||
Reference in New Issue
Block a user