test spirit parser moved from classic to X3.
This commit is contained in:
73
src/tests/spirit/CMakeLists.txt
Normal file
73
src/tests/spirit/CMakeLists.txt
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
# - spirit_fcn_test
|
||||||
|
cmake_minimum_required(VERSION 3.17)
|
||||||
|
|
||||||
|
project(spirit_fcn_test VERSION 0.1 LANGUAGES CXX)
|
||||||
|
|
||||||
|
#--- set a default build type if none was specified ---------------------------
|
||||||
|
set(default_build_type "Debug")
|
||||||
|
|
||||||
|
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
|
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
|
||||||
|
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
|
||||||
|
STRING "Choose the type of build." FORCE)
|
||||||
|
# Set the possible values of build type for cmake-gui
|
||||||
|
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
||||||
|
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
#--- check for pkg-config -----------------------------------------------------
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
|
||||||
|
#--- check for ROOT -----------------------------------------------------------
|
||||||
|
find_package(ROOT 6.18 REQUIRED COMPONENTS Gui MathMore Minuit2 XMLParser)
|
||||||
|
if (ROOT_mathmore_FOUND)
|
||||||
|
execute_process(COMMAND root-config --bindir OUTPUT_VARIABLE ROOT_BINDIR)
|
||||||
|
string(STRIP ${ROOT_BINDIR} ROOT_BINDIR)
|
||||||
|
execute_process(COMMAND root-config --version OUTPUT_VARIABLE ROOT_VERSION)
|
||||||
|
string(STRIP ${ROOT_VERSION} ROOT_VERSION)
|
||||||
|
message("-- Found ROOT: ${ROOT_BINDIR} (found version: ${ROOT_VERSION})")
|
||||||
|
#---Define useful ROOT functions and macros (e.g. ROOT_GENERATE_DICTIONARY)
|
||||||
|
include(${ROOT_USE_FILE})
|
||||||
|
endif (ROOT_mathmore_FOUND)
|
||||||
|
|
||||||
|
#--- check for boost ----------------------------------------------------------
|
||||||
|
find_package(Boost QUIET)
|
||||||
|
if (Boost_VERSION VERSION_GREATER_EQUAL "1.89")
|
||||||
|
find_package(Boost REQUIRED
|
||||||
|
COMPONENTS
|
||||||
|
filesystem
|
||||||
|
)
|
||||||
|
else (Boost_VERSION VERSION_GREATER_EQUAL "1.89")
|
||||||
|
find_package(Boost REQUIRED
|
||||||
|
COMPONENTS
|
||||||
|
system
|
||||||
|
filesystem
|
||||||
|
)
|
||||||
|
endif (Boost_VERSION VERSION_GREATER_EQUAL "1.89")
|
||||||
|
|
||||||
|
#--- create executable --------------------------------------------------------
|
||||||
|
add_executable(spirit_fcn_test
|
||||||
|
spirit_fcn_test.cpp
|
||||||
|
PFunction.cpp
|
||||||
|
PFunctionHandler.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
#--- add include directories --------------------------------------------------
|
||||||
|
target_include_directories(spirit_fcn_test
|
||||||
|
BEFORE PRIVATE
|
||||||
|
${Boost_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
#--- link libraries -----------------------------------------------------------
|
||||||
|
target_link_libraries(spirit_fcn_test
|
||||||
|
${ROOT_LIBRARIES}
|
||||||
|
${Boost_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
#--- installation info --------------------------------------------------------
|
||||||
|
install(
|
||||||
|
TARGETS
|
||||||
|
spirit_fcn_test
|
||||||
|
RUNTIME DESTINATION
|
||||||
|
bin
|
||||||
|
)
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,17 +1,17 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
|
||||||
PFunction.h
|
PFunction.h - Test version (simplified, no PMetaData)
|
||||||
|
|
||||||
Author: Andreas Suter
|
Author: Andreas Suter
|
||||||
e-mail: andreas.suter@psi.ch
|
e-mail: andreas.suter@psi.ch
|
||||||
|
|
||||||
$Id$
|
Modernized test version using Boost.Spirit X3 and visitor pattern.
|
||||||
|
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2007 by Andreas Suter *
|
* Copyright (C) 2007-2026 by Andreas Suter *
|
||||||
* andreas.suter@psi.c *
|
* andreas.suter@psi.ch *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
@@ -35,91 +35,54 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <boost/version.hpp>
|
#include <boost/variant.hpp>
|
||||||
|
|
||||||
#if BOOST_VERSION >= 103800
|
#include "PFunctionAst.h"
|
||||||
# include <boost/spirit/include/classic_ast.hpp>
|
|
||||||
using namespace BOOST_SPIRIT_CLASSIC_NS;
|
|
||||||
#else
|
|
||||||
# include <boost/spirit/tree/ast.hpp>
|
|
||||||
using namespace boost::spirit;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "PFunctionGrammar.h"
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
#define OP_ADD 0
|
|
||||||
#define OP_SUB 1
|
|
||||||
#define OP_MUL 2
|
|
||||||
#define OP_DIV 3
|
|
||||||
|
|
||||||
#define FUN_COS 0
|
|
||||||
#define FUN_SIN 1
|
|
||||||
#define FUN_TAN 2
|
|
||||||
#define FUN_COSH 3
|
|
||||||
#define FUN_SINH 4
|
|
||||||
#define FUN_TANH 5
|
|
||||||
#define FUN_ACOS 6
|
|
||||||
#define FUN_ASIN 7
|
|
||||||
#define FUN_ATAN 8
|
|
||||||
#define FUN_ACOSH 9
|
|
||||||
#define FUN_ASINH 10
|
|
||||||
#define FUN_ATANH 11
|
|
||||||
#define FUN_LOG 12
|
|
||||||
#define FUN_LN 13
|
|
||||||
#define FUN_EXP 14
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
typedef struct func_tree_node {
|
|
||||||
int fID; ///< tag showing what tree element this is
|
|
||||||
int fOperatorTag; ///< tag for '+', '-', '*', '/'
|
|
||||||
int fFunctionTag; ///< tag got "cos", "sin", ...
|
|
||||||
int fIvalue; ///< for parameter numbers and maps
|
|
||||||
bool fSign; ///< for sign. true = '-', false = '+'
|
|
||||||
double fDvalue; ///< for numbers
|
|
||||||
vector<func_tree_node> children; ///< holding sub-tree
|
|
||||||
} PFuncTreeNode;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* \brief Test version of PFunction class - simplified without PMetaData.
|
||||||
|
*
|
||||||
|
* This test version uses the same X3 grammar and AST but with a simpler
|
||||||
|
* interface for testing purposes. It does not support metadata (field,
|
||||||
|
* energy, temperature).
|
||||||
|
*/
|
||||||
class PFunction {
|
class PFunction {
|
||||||
public:
|
public:
|
||||||
PFunction(tree_parse_info<> info, vector<double> param, vector<int> map, bool debug);
|
PFunction(const std::string& input, std::vector<double> param, std::vector<int> map, bool debug = false);
|
||||||
virtual ~PFunction();
|
virtual ~PFunction();
|
||||||
|
|
||||||
virtual bool IsValid() { return fValid; }
|
virtual bool IsValid() { return fValid; }
|
||||||
virtual int GetFuncNo() { return fFuncNo; }
|
virtual int GetFuncNo() { return fFuncNo; }
|
||||||
virtual double Eval();
|
virtual double Eval();
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
virtual void InitNode(PFuncTreeNode &node);
|
musrfit::ast::expression fAst;
|
||||||
|
std::vector<double> fParam;
|
||||||
|
std::vector<int> fMap;
|
||||||
|
bool fValid;
|
||||||
|
int fFuncNo;
|
||||||
|
bool fDebug;
|
||||||
|
|
||||||
virtual bool CheckParameterAndMapRange();
|
// Simplified evaluation visitor (no metadata support)
|
||||||
virtual bool CheckParameterAndMapInTree(iter_t const& i);
|
class EvalVisitor : public boost::static_visitor<double> {
|
||||||
virtual bool SetFuncNo(iter_t const& i);
|
public:
|
||||||
|
EvalVisitor(const std::vector<int>& map, const std::vector<double>& param)
|
||||||
|
: fMap(map), fParam(param) {}
|
||||||
|
|
||||||
virtual bool GenerateFuncEvalTree();
|
double operator()(const musrfit::ast::nil&) const;
|
||||||
virtual void FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node);
|
double operator()(double val) const;
|
||||||
virtual double EvalNode(PFuncTreeNode &node);
|
double operator()(const musrfit::ast::constant& c) const;
|
||||||
virtual void CleanupFuncEvalTree();
|
double operator()(const musrfit::ast::parameter& p) const;
|
||||||
virtual void CleanupNode(PFuncTreeNode &node);
|
double operator()(const musrfit::ast::map_ref& m) const;
|
||||||
|
double operator()(const musrfit::ast::function_call& f) const;
|
||||||
virtual long EvaluateTree(tree_parse_info<> info);
|
double operator()(const musrfit::ast::power_call& p) const;
|
||||||
virtual long EvalTreeExpression(iter_t const& i);
|
double operator()(const musrfit::ast::expression& e) const;
|
||||||
|
|
||||||
virtual long PrintTree(tree_parse_info<> info);
|
|
||||||
virtual long PrintTreeExpression(iter_t const& i);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
tree_parse_info<> fInfo;
|
const std::vector<int>& fMap;
|
||||||
vector<double> fParam;
|
const std::vector<double>& fParam;
|
||||||
vector<int> fMap;
|
};
|
||||||
PFuncTreeNode fFunc;
|
|
||||||
|
|
||||||
bool fDebug;
|
|
||||||
bool fValid; ///< flag showing if the function is valid
|
|
||||||
int fFuncNo; ///< function number, i.e. FUNx with x the function number
|
|
||||||
|
|
||||||
string fFuncString;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _PFUNCTION_H_
|
#endif // _PFUNCTION_H_
|
||||||
|
|||||||
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_
|
||||||
@@ -1,17 +1,18 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
|
||||||
PFunctionGrammer.h
|
PFunctionGrammar.h
|
||||||
|
|
||||||
Author: Andreas Suter
|
Author: Andreas Suter
|
||||||
e-mail: andreas.suter@psi.ch
|
e-mail: andreas.suter@psi.ch
|
||||||
|
|
||||||
$Id$
|
Header-only grammar for parsing function entries in msr-file FUNCTION blocks.
|
||||||
|
This version uses Boost.Spirit X3 in header-only mode for maximum compatibility.
|
||||||
|
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2007 by Andreas Suter *
|
* Copyright (C) 2007-2025 by Andreas Suter *
|
||||||
* andreas.suter@psi.c *
|
* andreas.suter@psi.ch *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
@@ -32,133 +33,164 @@
|
|||||||
#ifndef _PFUNCTIONGRAMMAR_H_
|
#ifndef _PFUNCTIONGRAMMAR_H_
|
||||||
#define _PFUNCTIONGRAMMAR_H_
|
#define _PFUNCTIONGRAMMAR_H_
|
||||||
|
|
||||||
#include <iostream>
|
// Check Boost version - require 1.61+ for Spirit X3
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
//#define BOOST_SPIRIT_DEBUG
|
|
||||||
|
|
||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
#include <boost/spirit/version.hpp>
|
#if BOOST_VERSION < 106100
|
||||||
|
# error "Boost version 1.61.0 or higher is required for Spirit X3. Please upgrade Boost."
|
||||||
#if BOOST_VERSION >= 103800
|
|
||||||
# include <boost/spirit/include/classic_core.hpp>
|
|
||||||
# include <boost/spirit/include/classic_ast.hpp>
|
|
||||||
using namespace BOOST_SPIRIT_CLASSIC_NS;
|
|
||||||
#else
|
|
||||||
# include <boost/spirit/core.hpp>
|
|
||||||
# include <boost/spirit/tree/ast.hpp>
|
|
||||||
using namespace boost::spirit;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef char const* iterator_t;
|
#include "PFunctionAst.h"
|
||||||
typedef tree_match<iterator_t> parse_tree_match_t;
|
#include <boost/spirit/home/x3.hpp>
|
||||||
typedef parse_tree_match_t::tree_iterator iter_t;
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
namespace x3 = boost::spirit::x3;
|
||||||
/**
|
|
||||||
*
|
namespace musrfit { namespace grammar
|
||||||
*/
|
|
||||||
struct PFunctionGrammar : public grammar<PFunctionGrammar>
|
|
||||||
{
|
{
|
||||||
static const int realID = 1;
|
using x3::int_;
|
||||||
static const int constPiID = 2;
|
using x3::double_;
|
||||||
static const int constGammaMuID = 3;
|
using x3::lit;
|
||||||
static const int funLabelID = 4;
|
using x3::lexeme;
|
||||||
static const int parameterID = 5;
|
using x3::attr;
|
||||||
static const int mapID = 6;
|
|
||||||
static const int functionID = 7;
|
|
||||||
static const int factorID = 8;
|
|
||||||
static const int termID = 9;
|
|
||||||
static const int expressionID = 10;
|
|
||||||
static const int assignmentID = 11;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
///////////////////////////////////////////////////////////////////////////
|
||||||
struct definition
|
// Symbol tables - using inline to avoid multiple definition errors
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct additive_op_ : x3::symbols<ast::optoken>
|
||||||
{
|
{
|
||||||
definition(PFunctionGrammar const& /*self*/)
|
additive_op_()
|
||||||
{
|
{
|
||||||
// Start grammar definition
|
add("+", ast::op_plus)("-", ast::op_minus);
|
||||||
real = leaf_node_d[ real_p ];
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const_pi = leaf_node_d[ str_p("PI") ];
|
inline additive_op_ additive_op;
|
||||||
|
|
||||||
const_gamma_mu = leaf_node_d[ str_p("GAMMA_MU") ];
|
struct multiplicative_op_ : x3::symbols<ast::optoken>
|
||||||
|
{
|
||||||
|
multiplicative_op_()
|
||||||
|
{
|
||||||
|
add("*", ast::op_times)("/", ast::op_divide);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
fun_label = leaf_node_d[ ( lexeme_d[ "FUN" >> +digit_p ] ) ];
|
inline multiplicative_op_ multiplicative_op;
|
||||||
|
|
||||||
parameter = leaf_node_d[ ( lexeme_d[ "PAR" >> +digit_p ] ) |
|
struct fun_tok_ : x3::symbols<ast::funid>
|
||||||
( lexeme_d[ "-PAR" >> +digit_p ] ) ];
|
{
|
||||||
|
fun_tok_()
|
||||||
|
{
|
||||||
|
add
|
||||||
|
("COS", ast::fun_cos)
|
||||||
|
("SIN", ast::fun_sin)
|
||||||
|
("TAN", ast::fun_tan)
|
||||||
|
("COSH", ast::fun_cosh)
|
||||||
|
("SINH", ast::fun_sinh)
|
||||||
|
("TANH", ast::fun_tanh)
|
||||||
|
("ACOS", ast::fun_acos)
|
||||||
|
("ASIN", ast::fun_asin)
|
||||||
|
("ATAN", ast::fun_atan)
|
||||||
|
("ACOSH", ast::fun_acosh)
|
||||||
|
("ASINH", ast::fun_asinh)
|
||||||
|
("ATANH", ast::fun_atanh)
|
||||||
|
("LOG", ast::fun_log)
|
||||||
|
("LN", ast::fun_ln)
|
||||||
|
("EXP", ast::fun_exp)
|
||||||
|
("SQRT", ast::fun_sqrt);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
map = leaf_node_d[ ( lexeme_d[ "MAP" >> +digit_p ] ) ];
|
inline fun_tok_ fun_tok;
|
||||||
|
|
||||||
function = lexeme_d[ root_node_d[ str_p("COS") ] >> ch_p('(') ] >> expression >> ch_p(')')
|
struct const_tok_ : x3::symbols<ast::constant::type>
|
||||||
| lexeme_d[ root_node_d[ str_p("SIN") ] >> ch_p('(') ] >> expression >> ch_p(')')
|
{
|
||||||
| lexeme_d[ root_node_d[ str_p("TAN") ] >> ch_p('(') ] >> expression >> ch_p(')')
|
const_tok_()
|
||||||
| lexeme_d[ root_node_d[ str_p("COSH") ] >> ch_p('(') ] >> expression >> ch_p(')')
|
{
|
||||||
| lexeme_d[ root_node_d[ str_p("SINH") ] >> ch_p('(') ] >> expression >> ch_p(')')
|
add("PI", ast::constant::pi)("GAMMA_MU", ast::constant::gamma_mu);
|
||||||
| lexeme_d[ root_node_d[ str_p("TANH") ] >> ch_p('(') ] >> expression >> ch_p(')')
|
}
|
||||||
| lexeme_d[ root_node_d[ str_p("ACOS") ] >> ch_p('(') ] >> expression >> ch_p(')')
|
};
|
||||||
| lexeme_d[ root_node_d[ str_p("ASIN") ] >> ch_p('(') ] >> expression >> ch_p(')')
|
|
||||||
| lexeme_d[ root_node_d[ str_p("ATAN") ] >> ch_p('(') ] >> expression >> ch_p(')')
|
|
||||||
| lexeme_d[ root_node_d[ str_p("ACOSH") ] >> ch_p('(') ] >> expression >> ch_p(')')
|
|
||||||
| lexeme_d[ root_node_d[ str_p("ASINH") ] >> ch_p('(') ] >> expression >> ch_p(')')
|
|
||||||
| lexeme_d[ root_node_d[ str_p("ATANH") ] >> ch_p('(') ] >> expression >> ch_p(')')
|
|
||||||
| lexeme_d[ root_node_d[ str_p("LOG") ] >> ch_p('(') ] >> expression >> ch_p(')')
|
|
||||||
| lexeme_d[ root_node_d[ str_p("LN") ] >> ch_p('(') ] >> expression >> ch_p(')')
|
|
||||||
| lexeme_d[ root_node_d[ str_p("EXP") ] >> ch_p('(') ] >> expression >> ch_p(')')
|
|
||||||
;
|
|
||||||
|
|
||||||
factor = real
|
inline const_tok_ const_tok;
|
||||||
| const_pi
|
|
||||||
| const_gamma_mu
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Rules
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
x3::rule<class assignment, ast::assignment> const assignment = "assignment";
|
||||||
|
x3::rule<class expression, ast::expression> const expression = "expression";
|
||||||
|
x3::rule<class term, ast::expression> const term = "term";
|
||||||
|
x3::rule<class factor, ast::operand> const factor = "factor";
|
||||||
|
x3::rule<class constant, ast::constant> const constant = "constant";
|
||||||
|
x3::rule<class parameter, ast::parameter> const parameter = "parameter";
|
||||||
|
x3::rule<class map_ref, ast::map_ref> const map = "map";
|
||||||
|
x3::rule<class function_call, ast::function_call> const function = "function";
|
||||||
|
x3::rule<class power_call, ast::power_call> const power = "power";
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Rule definitions
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
auto const assignment_def =
|
||||||
|
lit("FUN") >> int_ >> '=' >> expression;
|
||||||
|
|
||||||
|
auto const expression_def =
|
||||||
|
term >> *(additive_op >> term);
|
||||||
|
|
||||||
|
auto const term_def =
|
||||||
|
factor >> *(multiplicative_op >> factor);
|
||||||
|
|
||||||
|
auto const factor_def =
|
||||||
|
double_
|
||||||
|
| constant
|
||||||
| parameter
|
| parameter
|
||||||
| map
|
| map
|
||||||
| function
|
| function
|
||||||
| inner_node_d[ch_p('(') >> expression >> ch_p(')')]
|
| power
|
||||||
;
|
| ('(' >> expression >> ')');
|
||||||
|
|
||||||
term = factor >>
|
auto const constant_def =
|
||||||
*( (root_node_d[ch_p('*')] >> factor)
|
(const_tok >> attr(false) >> attr(0))
|
||||||
| (root_node_d[ch_p('/')] >> factor)
|
| (lit("B") >> attr(ast::constant::field) >> attr(false) >> attr(0))
|
||||||
);
|
| (lit("-B") >> attr(ast::constant::field) >> attr(true) >> attr(0))
|
||||||
|
| (lit("EN") >> attr(ast::constant::energy) >> attr(false) >> attr(0))
|
||||||
|
| (lit("-EN") >> attr(ast::constant::energy) >> attr(true) >> attr(0))
|
||||||
|
| (lit('T') >> attr(ast::constant::temp) >> attr(false) >> int_)
|
||||||
|
| (lit("-T") >> attr(ast::constant::temp) >> attr(true) >> int_);
|
||||||
|
|
||||||
expression = term >>
|
auto const parameter_def =
|
||||||
*( (root_node_d[ch_p('+')] >> term)
|
(lexeme[lit("-PAR") >> int_] >> attr(true))
|
||||||
| (root_node_d[ch_p('-')] >> term)
|
| (lit("PAR") >> int_ >> attr(false));
|
||||||
);
|
|
||||||
|
|
||||||
assignment = (fun_label >> ch_p('=') >> expression);
|
auto const map_def =
|
||||||
// End grammar definition
|
(lexeme[lit("-MAP") >> int_] >> attr(true))
|
||||||
|
| (lit("MAP") >> int_ >> attr(false));
|
||||||
|
|
||||||
// turn on the debugging info.
|
auto const function_def =
|
||||||
BOOST_SPIRIT_DEBUG_RULE(real);
|
fun_tok >> '(' >> expression >> ')';
|
||||||
BOOST_SPIRIT_DEBUG_RULE(const_pi);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(const_gamma_mu);
|
auto const power_def =
|
||||||
BOOST_SPIRIT_DEBUG_RULE(fun_label);
|
lit("POW") >> '(' >> expression >> ',' >> expression >> ')';
|
||||||
BOOST_SPIRIT_DEBUG_RULE(parameter);
|
|
||||||
BOOST_SPIRIT_DEBUG_RULE(map);
|
BOOST_SPIRIT_DEFINE(
|
||||||
BOOST_SPIRIT_DEBUG_RULE(function);
|
assignment,
|
||||||
BOOST_SPIRIT_DEBUG_RULE(factor);
|
expression,
|
||||||
BOOST_SPIRIT_DEBUG_RULE(term);
|
term,
|
||||||
BOOST_SPIRIT_DEBUG_RULE(expression);
|
factor,
|
||||||
BOOST_SPIRIT_DEBUG_RULE(assignment);
|
constant,
|
||||||
|
parameter,
|
||||||
|
map,
|
||||||
|
function,
|
||||||
|
power
|
||||||
|
)
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
namespace musrfit {
|
||||||
|
// Accessor for the top-level rule
|
||||||
|
inline auto const& function_grammar()
|
||||||
|
{
|
||||||
|
return grammar::assignment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rule<ScannerT, parser_context<>, parser_tag<assignmentID> > assignment;
|
|
||||||
rule<ScannerT, parser_context<>, parser_tag<expressionID> > expression;
|
|
||||||
rule<ScannerT, parser_context<>, parser_tag<termID> > term;
|
|
||||||
rule<ScannerT, parser_context<>, parser_tag<factorID> > factor;
|
|
||||||
rule<ScannerT, parser_context<>, parser_tag<functionID> > function;
|
|
||||||
rule<ScannerT, parser_context<>, parser_tag<mapID> > map;
|
|
||||||
rule<ScannerT, parser_context<>, parser_tag<parameterID> > parameter;
|
|
||||||
rule<ScannerT, parser_context<>, parser_tag<funLabelID> > fun_label;
|
|
||||||
rule<ScannerT, parser_context<>, parser_tag<constGammaMuID> > const_gamma_mu;
|
|
||||||
rule<ScannerT, parser_context<>, parser_tag<constPiID> > const_pi;
|
|
||||||
rule<ScannerT, parser_context<>, parser_tag<realID> > real;
|
|
||||||
|
|
||||||
rule<ScannerT, parser_context<>, parser_tag<assignmentID> > const&
|
|
||||||
start() const { return assignment; }
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _PFUNCTIONGRAMMAR_H_
|
#endif // _PFUNCTIONGRAMMAR_H_
|
||||||
|
|||||||
@@ -31,9 +31,8 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <algorithm>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
@@ -51,8 +50,8 @@ PFunctionHandler::PFunctionHandler(char *fln, bool debug) : fDebug(debug), fFile
|
|||||||
{
|
{
|
||||||
fValid = true;
|
fValid = true;
|
||||||
|
|
||||||
cout << endl << "in PFunctionHandler(char *fln)";
|
std::cout << std::endl << "in PFunctionHandler(char *fln)";
|
||||||
cout << endl << "fFileName = " << fFileName;
|
std::cout << std::endl << "fFileName = " << fFileName;
|
||||||
|
|
||||||
fValid = ReadFile();
|
fValid = ReadFile();
|
||||||
if (fValid)
|
if (fValid)
|
||||||
@@ -67,12 +66,12 @@ PFunctionHandler::PFunctionHandler(char *fln, bool debug) : fDebug(debug), fFile
|
|||||||
*
|
*
|
||||||
* \param lines
|
* \param lines
|
||||||
*/
|
*/
|
||||||
PFunctionHandler::PFunctionHandler(vector<string> lines)
|
PFunctionHandler::PFunctionHandler(std::vector<std::string> lines)
|
||||||
{
|
{
|
||||||
fValid = true;
|
fValid = true;
|
||||||
fFileName = "";
|
fFileName = "";
|
||||||
|
|
||||||
cout << endl << "in PFunctionHandler(vector<string> lines)";
|
std::cout << std::endl << "in PFunctionHandler(std::vector<std::string> lines)";
|
||||||
|
|
||||||
if (lines.size() == 0) {
|
if (lines.size() == 0) {
|
||||||
fValid = false;
|
fValid = false;
|
||||||
@@ -90,43 +89,43 @@ PFunctionHandler::PFunctionHandler(vector<string> lines)
|
|||||||
continue;
|
continue;
|
||||||
boost::to_upper(lines[i]);
|
boost::to_upper(lines[i]);
|
||||||
if (lines[i].find("PAR") == 0) {
|
if (lines[i].find("PAR") == 0) {
|
||||||
cout << endl << "this is a parameter line ...";
|
std::cout << std::endl << "this is a parameter line ...";
|
||||||
status = sscanf(lines[i].c_str(), "PAR %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
|
status = sscanf(lines[i].c_str(), "PAR %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
|
||||||
&dval[0], &dval[1], &dval[2], &dval[3], &dval[4],
|
&dval[0], &dval[1], &dval[2], &dval[3], &dval[4],
|
||||||
&dval[5], &dval[6], &dval[7], &dval[8], &dval[9]);
|
&dval[5], &dval[6], &dval[7], &dval[8], &dval[9]);
|
||||||
cout << endl << "status=" << status;
|
std::cout << std::endl << "status=" << status;
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
done = true;
|
done = true;
|
||||||
fValid = false;
|
fValid = false;
|
||||||
cout << endl << "invalid PAR line, sorry ...";
|
std::cout << std::endl << "invalid PAR line, sorry ...";
|
||||||
} else { // fill par
|
} else { // fill par
|
||||||
cout << endl << "PAR line, status = " << status;
|
std::cout << std::endl << "PAR line, status = " << status;
|
||||||
for (int i=0; i<status; i++)
|
for (int i=0; i<status; i++)
|
||||||
fParam.push_back(dval[i]);
|
fParam.push_back(dval[i]);
|
||||||
cout << endl << "fParam.size()=" << fParam.size() << endl;
|
std::cout << std::endl << "fParam.size()=" << fParam.size() << std::endl;
|
||||||
for (unsigned int i=0; i<fParam.size(); i++)
|
for (unsigned int i=0; i<fParam.size(); i++)
|
||||||
cout << endl << "Par" << i+1 << " = " << fParam[i];
|
std::cout << std::endl << "Par" << i+1 << " = " << fParam[i];
|
||||||
cout << endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
} else if (lines[i].find("MAP") == 0) {
|
} else if (lines[i].find("MAP") == 0) {
|
||||||
cout << endl << "this is a map line ...";
|
std::cout << std::endl << "this is a map line ...";
|
||||||
status = sscanf(lines[i].c_str(), "MAP %d %d %d %d %d %d %d %d %d %d",
|
status = sscanf(lines[i].c_str(), "MAP %d %d %d %d %d %d %d %d %d %d",
|
||||||
&val[0], &val[1], &val[2], &val[3], &val[4],
|
&val[0], &val[1], &val[2], &val[3], &val[4],
|
||||||
&val[5], &val[6], &val[7], &val[8], &val[9]);
|
&val[5], &val[6], &val[7], &val[8], &val[9]);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
done = true;
|
done = true;
|
||||||
fValid = false;
|
fValid = false;
|
||||||
cout << endl << "invalid MAP line, sorry ...";
|
std::cout << std::endl << "invalid MAP line, sorry ...";
|
||||||
} else { // fill map
|
} else { // fill map
|
||||||
cout << endl << "MAP line, status = " << status;
|
std::cout << std::endl << "MAP line, status = " << status;
|
||||||
for (int i=0; i<status; i++)
|
for (int i=0; i<status; i++)
|
||||||
fMap.push_back(val[i]);
|
fMap.push_back(val[i]);
|
||||||
}
|
}
|
||||||
} else if (lines[i].find("FUNCTIONS") == 0) {
|
} else if (lines[i].find("FUNCTIONS") == 0) {
|
||||||
cout << endl << "the functions block start ...";
|
std::cout << std::endl << "the functions block start ...";
|
||||||
inFcnBlock = true;
|
inFcnBlock = true;
|
||||||
} else if (lines[i].find("END") == 0) {
|
} else if (lines[i].find("END") == 0) {
|
||||||
cout << endl << "end tag found; rest will be ignored";
|
std::cout << std::endl << "end tag found; rest will be ignored";
|
||||||
done = true;
|
done = true;
|
||||||
} else if (inFcnBlock) {
|
} else if (inFcnBlock) {
|
||||||
fLines.push_back(lines[i]);
|
fLines.push_back(lines[i]);
|
||||||
@@ -136,20 +135,20 @@ PFunctionHandler::PFunctionHandler(vector<string> lines)
|
|||||||
// check if all blocks are given
|
// check if all blocks are given
|
||||||
if ((fMap.size() == 0) || (fParam.size() == 0) || (fLines.size() == 0)) {
|
if ((fMap.size() == 0) || (fParam.size() == 0) || (fLines.size() == 0)) {
|
||||||
if (fMap.size() == 0)
|
if (fMap.size() == 0)
|
||||||
cout << endl << "MAP block is missing ...";
|
std::cout << std::endl << "MAP block is missing ...";
|
||||||
if (fParam.size() == 0)
|
if (fParam.size() == 0)
|
||||||
cout << endl << "PAR block is missing ...";
|
std::cout << std::endl << "PAR block is missing ...";
|
||||||
if (fLines.size() == 0)
|
if (fLines.size() == 0)
|
||||||
cout << endl << "FUNCTION block is missing ...";
|
std::cout << std::endl << "FUNCTION block is missing ...";
|
||||||
fValid = false;
|
fValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fValid = MapsAreValid();
|
fValid = MapsAreValid();
|
||||||
|
|
||||||
if (fValid) {
|
if (fValid) {
|
||||||
cout << endl << "Functions: ";
|
std::cout << std::endl << "Functions: ";
|
||||||
for (unsigned int i=0; i<fLines.size(); i++)
|
for (unsigned int i=0; i<fLines.size(); i++)
|
||||||
cout << endl << fLines[i];
|
std::cout << std::endl << fLines[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +161,7 @@ PFunctionHandler::PFunctionHandler(vector<string> lines)
|
|||||||
*/
|
*/
|
||||||
PFunctionHandler::~PFunctionHandler()
|
PFunctionHandler::~PFunctionHandler()
|
||||||
{
|
{
|
||||||
cout << endl << "in ~PFunctionHandler()" << endl << endl;
|
std::cout << std::endl << "in ~PFunctionHandler()" << std::endl << std::endl;
|
||||||
fParam.clear();
|
fParam.clear();
|
||||||
fMap.clear();
|
fMap.clear();
|
||||||
fLines.clear();
|
fLines.clear();
|
||||||
@@ -179,22 +178,25 @@ PFunctionHandler::~PFunctionHandler()
|
|||||||
*/
|
*/
|
||||||
bool PFunctionHandler::DoParse()
|
bool PFunctionHandler::DoParse()
|
||||||
{
|
{
|
||||||
cout << endl << "in PFunctionHandler::DoParse() ...";
|
std::cout << std::endl << "in PFunctionHandler::DoParse() ...";
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
PFunctionGrammar function;
|
|
||||||
|
|
||||||
for (unsigned int i=0; i<fLines.size(); i++) {
|
for (unsigned int i=0; i<fLines.size(); i++) {
|
||||||
cout << endl << "fLines[" << i << "] = '" << fLines[i] << "'";
|
std::cout << std::endl << "fLines[" << i << "] = '" << fLines[i] << "'";
|
||||||
|
|
||||||
tree_parse_info<> info = ast_parse(fLines[i].c_str(), function, space_p);
|
// Convert to uppercase (grammar expects uppercase tokens)
|
||||||
|
std::string line = fLines[i];
|
||||||
|
std::transform(line.begin(), line.end(), line.begin(), ::toupper);
|
||||||
|
|
||||||
if (info.full) {
|
// Use new Qi-based PFunction constructor
|
||||||
cout << endl << "parse successfull ..." << endl;
|
PFunction func(line, fParam, fMap, fDebug);
|
||||||
PFunction func(info, fParam, fMap, fDebug);
|
|
||||||
|
if (func.IsValid()) {
|
||||||
|
std::cout << std::endl << "parse successfull ..." << std::endl;
|
||||||
fFuncs.push_back(func);
|
fFuncs.push_back(func);
|
||||||
} else {
|
} else {
|
||||||
cout << endl << "parse failed ... (" << i << ")" << endl;
|
std::cout << std::endl << "parse failed ... (" << i << ")" << std::endl;
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -205,8 +207,8 @@ bool PFunctionHandler::DoParse()
|
|||||||
if (success) {
|
if (success) {
|
||||||
for (unsigned int i=0; i<fFuncs.size(); i++) {
|
for (unsigned int i=0; i<fFuncs.size(); i++) {
|
||||||
if (!fFuncs[i].IsValid()) {
|
if (!fFuncs[i].IsValid()) {
|
||||||
cout << endl << "**ERROR**: function fun" << fFuncs[i].GetFuncNo();
|
std::cout << std::endl << "**ERROR**: function fun" << fFuncs[i].GetFuncNo();
|
||||||
cout << " has a problem with either parameter or map out of range!";
|
std::cout << " has a problem with either parameter or map out of range!";
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -218,8 +220,8 @@ bool PFunctionHandler::DoParse()
|
|||||||
for (unsigned int i=0; i<fFuncs.size(); i++) {
|
for (unsigned int i=0; i<fFuncs.size(); i++) {
|
||||||
for (unsigned int j=i+1; j<fFuncs.size(); j++) {
|
for (unsigned int j=i+1; j<fFuncs.size(); j++) {
|
||||||
if (fFuncs[i].GetFuncNo() == fFuncs[j].GetFuncNo()) {
|
if (fFuncs[i].GetFuncNo() == fFuncs[j].GetFuncNo()) {
|
||||||
cout << endl << "**ERROR**: function number " << fFuncs[i].GetFuncNo();
|
std::cout << std::endl << "**ERROR**: function number " << fFuncs[i].GetFuncNo();
|
||||||
cout << " is at least twice present! Fix this first.";
|
std::cout << " is at least twice present! Fix this first.";
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,7 +230,7 @@ bool PFunctionHandler::DoParse()
|
|||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
for (unsigned int i=0; i<fFuncs.size(); i++)
|
for (unsigned int i=0; i<fFuncs.size(); i++)
|
||||||
cout << endl << "func number = " << fFuncs[i].GetFuncNo();
|
std::cout << std::endl << "func number = " << fFuncs[i].GetFuncNo();
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
@@ -245,13 +247,10 @@ bool PFunctionHandler::DoParse()
|
|||||||
double PFunctionHandler::Eval(int i)
|
double PFunctionHandler::Eval(int i)
|
||||||
{
|
{
|
||||||
if (GetFuncIndex(i) == -1) {
|
if (GetFuncIndex(i) == -1) {
|
||||||
cout << endl << "**ERROR**: Couldn't find FUN" << i << " for evaluation";
|
std::cout << std::endl << "**ERROR**: Couldn't find FUN" << i << " for evaluation";
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << endl << "PFunctionHandler::Eval: GetFuncIndex("<<i<<") = " << GetFuncIndex(i);
|
|
||||||
cout << endl;
|
|
||||||
|
|
||||||
return fFuncs[GetFuncIndex(i)].Eval();
|
return fFuncs[GetFuncIndex(i)].Eval();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,24 +279,24 @@ unsigned int PFunctionHandler::GetFuncNo(unsigned int i)
|
|||||||
*/
|
*/
|
||||||
bool PFunctionHandler::ReadFile()
|
bool PFunctionHandler::ReadFile()
|
||||||
{
|
{
|
||||||
cout << endl << "in ~PFunctionHandler::ReadFile()";
|
std::cout << std::endl << "in ~PFunctionHandler::ReadFile()";
|
||||||
|
|
||||||
if (fFileName.length() == 0) {
|
if (fFileName.length() == 0) {
|
||||||
cout << endl << "PFunctionHandler::ReadFile(): **ERROR**";
|
std::cout << std::endl << "PFunctionHandler::ReadFile(): **ERROR**";
|
||||||
cout << endl << " no file name given :-(. Will quit";
|
std::cout << std::endl << " no file name given :-(. Will quit";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ifstream f;
|
std::ifstream f;
|
||||||
f.open(fFileName.c_str(), ifstream::in);
|
f.open(fFileName.c_str(), std::ifstream::in);
|
||||||
|
|
||||||
if (!f.is_open()) {
|
if (!f.is_open()) {
|
||||||
cout << endl << "PFunctionHandler::ReadFile(): **ERROR**";
|
std::cout << std::endl << "PFunctionHandler::ReadFile(): **ERROR**";
|
||||||
cout << endl << " File '" << fFileName.c_str() << "' couldn't being opened.";
|
std::cout << std::endl << " File '" << fFileName.c_str() << "' couldn't being opened.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string line;
|
std::string line;
|
||||||
char c_line[128];
|
char c_line[128];
|
||||||
bool done = false;
|
bool done = false;
|
||||||
bool success = true;
|
bool success = true;
|
||||||
@@ -314,41 +313,41 @@ bool PFunctionHandler::ReadFile()
|
|||||||
continue;
|
continue;
|
||||||
boost::to_upper(line);
|
boost::to_upper(line);
|
||||||
if (line.find("PAR") == 0) {
|
if (line.find("PAR") == 0) {
|
||||||
cout << endl << "this is a parameter line ...";
|
std::cout << std::endl << "this is a parameter line ...";
|
||||||
status = sscanf(line.c_str(), "PAR %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
|
status = sscanf(line.c_str(), "PAR %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
|
||||||
&dval[0], &dval[1], &dval[2], &dval[3], &dval[4],
|
&dval[0], &dval[1], &dval[2], &dval[3], &dval[4],
|
||||||
&dval[5], &dval[6], &dval[7], &dval[8], &dval[9]);
|
&dval[5], &dval[6], &dval[7], &dval[8], &dval[9]);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
done = true;
|
done = true;
|
||||||
success = false;
|
success = false;
|
||||||
cout << endl << "invalid PAR line, sorry ...";
|
std::cout << std::endl << "invalid PAR line, sorry ...";
|
||||||
} else { // fill map
|
} else { // fill map
|
||||||
cout << endl << "PAR line, status = " << status;
|
std::cout << std::endl << "PAR line, status = " << status;
|
||||||
for (int i=0; i<status; i++)
|
for (int i=0; i<status; i++)
|
||||||
fParam.push_back(dval[i]);
|
fParam.push_back(dval[i]);
|
||||||
for (unsigned int i=0; i<fParam.size(); i++)
|
for (unsigned int i=0; i<fParam.size(); i++)
|
||||||
cout << endl << "Par" << i+1 << " = " << fParam[i];
|
std::cout << std::endl << "Par" << i+1 << " = " << fParam[i];
|
||||||
cout << endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
} else if (line.find("MAP") == 0) {
|
} else if (line.find("MAP") == 0) {
|
||||||
cout << endl << "this is a map line ...";
|
std::cout << std::endl << "this is a map line ...";
|
||||||
status = sscanf(line.c_str(), "MAP %d %d %d %d %d %d %d %d %d %d",
|
status = sscanf(line.c_str(), "MAP %d %d %d %d %d %d %d %d %d %d",
|
||||||
&val[0], &val[1], &val[2], &val[3], &val[4],
|
&val[0], &val[1], &val[2], &val[3], &val[4],
|
||||||
&val[5], &val[6], &val[7], &val[8], &val[9]);
|
&val[5], &val[6], &val[7], &val[8], &val[9]);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
done = true;
|
done = true;
|
||||||
success = false;
|
success = false;
|
||||||
cout << endl << "invalid MAP line, sorry ...";
|
std::cout << std::endl << "invalid MAP line, sorry ...";
|
||||||
} else { // fill map
|
} else { // fill map
|
||||||
cout << endl << "MAP line, status = " << status;
|
std::cout << std::endl << "MAP line, status = " << status;
|
||||||
for (int i=0; i<status; i++)
|
for (int i=0; i<status; i++)
|
||||||
fMap.push_back(val[i]);
|
fMap.push_back(val[i]);
|
||||||
}
|
}
|
||||||
} else if (line.find("FUNCTIONS") == 0) {
|
} else if (line.find("FUNCTIONS") == 0) {
|
||||||
cout << endl << "the functions block start ...";
|
std::cout << std::endl << "the functions block start ...";
|
||||||
inFcnBlock = true;
|
inFcnBlock = true;
|
||||||
} else if (line.find("END") == 0) {
|
} else if (line.find("END") == 0) {
|
||||||
cout << endl << "end tag found; rest will be ignored";
|
std::cout << std::endl << "end tag found; rest will be ignored";
|
||||||
done = true;
|
done = true;
|
||||||
} else if (inFcnBlock) {
|
} else if (inFcnBlock) {
|
||||||
fLines.push_back(line);
|
fLines.push_back(line);
|
||||||
@@ -361,18 +360,18 @@ bool PFunctionHandler::ReadFile()
|
|||||||
// check if all blocks are given
|
// check if all blocks are given
|
||||||
if ((fMap.size() == 0) || (fParam.size() == 0) || (fLines.size() == 0)) {
|
if ((fMap.size() == 0) || (fParam.size() == 0) || (fLines.size() == 0)) {
|
||||||
if (fMap.size() == 0)
|
if (fMap.size() == 0)
|
||||||
cout << endl << "MAP block is missing ...";
|
std::cout << std::endl << "MAP block is missing ...";
|
||||||
if (fParam.size() == 0)
|
if (fParam.size() == 0)
|
||||||
cout << endl << "PAR block is missing ...";
|
std::cout << std::endl << "PAR block is missing ...";
|
||||||
if (fLines.size() == 0)
|
if (fLines.size() == 0)
|
||||||
cout << endl << "FUNCTION block is missing ...";
|
std::cout << std::endl << "FUNCTION block is missing ...";
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
cout << endl << "Functions: ";
|
std::cout << std::endl << "Functions: ";
|
||||||
for (unsigned int i=0; i<fLines.size(); i++)
|
for (unsigned int i=0; i<fLines.size(); i++)
|
||||||
cout << endl << fLines[i];
|
std::cout << std::endl << fLines[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
@@ -395,7 +394,7 @@ bool PFunctionHandler::MapsAreValid()
|
|||||||
success = false;
|
success = false;
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
cout << endl << "invalid MAP found ...";
|
std::cout << std::endl << "invalid MAP found ...";
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,10 @@
|
|||||||
Author: Andreas Suter
|
Author: Andreas Suter
|
||||||
e-mail: andreas.suter@psi.ch
|
e-mail: andreas.suter@psi.ch
|
||||||
|
|
||||||
$Id$
|
|
||||||
|
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Copyright (C) 2007 by Andreas Suter *
|
* Copyright (C) 2007-2026 by Andreas Suter *
|
||||||
* andreas.suter@psi.c *
|
* andreas.suter@psi.c *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
@@ -35,7 +33,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#include "PFunctionGrammar.h"
|
#include "PFunctionGrammar.h"
|
||||||
#include "PFunction.h"
|
#include "PFunction.h"
|
||||||
@@ -44,7 +41,7 @@ class PFunctionHandler
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PFunctionHandler(char *fln, bool debug);
|
PFunctionHandler(char *fln, bool debug);
|
||||||
PFunctionHandler(vector<string> lines);
|
PFunctionHandler(std::vector<std::string> lines);
|
||||||
virtual ~PFunctionHandler();
|
virtual ~PFunctionHandler();
|
||||||
|
|
||||||
virtual bool IsValid() { return fValid; }
|
virtual bool IsValid() { return fValid; }
|
||||||
@@ -57,13 +54,13 @@ class PFunctionHandler
|
|||||||
bool fDebug;
|
bool fDebug;
|
||||||
bool fValid;
|
bool fValid;
|
||||||
|
|
||||||
string fFileName;
|
std::string fFileName;
|
||||||
|
|
||||||
vector<double> fParam;
|
std::vector<double> fParam;
|
||||||
vector<int> fMap;
|
std::vector<int> fMap;
|
||||||
vector<string> fLines;
|
std::vector<std::string> fLines;
|
||||||
|
|
||||||
vector<PFunction> fFuncs;
|
std::vector<PFunction> fFuncs;
|
||||||
|
|
||||||
virtual bool ReadFile();
|
virtual bool ReadFile();
|
||||||
virtual bool MapsAreValid();
|
virtual bool MapsAreValid();
|
||||||
|
|||||||
@@ -17,17 +17,21 @@
|
|||||||
PAR 1.0 2.1 3.5 -0.87 0.87
|
PAR 1.0 2.1 3.5 -0.87 0.87
|
||||||
MAP 2 1 4 5
|
MAP 2 1 4 5
|
||||||
FUNCTIONS
|
FUNCTIONS
|
||||||
#fun0 = cos(par1)
|
fun0 = cos(par1)
|
||||||
#fun1 = sin(par3/(par1+map2))
|
fun1 = sin(par3/(par1+map2))
|
||||||
#fun0 = 1.2+pi
|
#fun0 = 1.2+pi
|
||||||
#fun1 = gamma_mu
|
#fun1 = gamma_mu
|
||||||
#fun2 = -par1*(sin(par2)*cos(par3)+((map1)))
|
fun2 = -par1*(sin(par2)*cos(par3)+((map1)))
|
||||||
#fun1 = cos(par1)
|
#fun1 = cos(par1)
|
||||||
#fun0 = par1 + map3 * cos(cos(par2 - map1))
|
#fun0 = par1 + map3 * cos(cos(par2 - map1))
|
||||||
#fun8 = -par1*log(sin(par1)) + exp(-1.0*map2)
|
#fun8 = -par1*log(sin(par1)) + exp(-1.0*map2)
|
||||||
#fun1 = par1 + map1 * (0.01355+par1*(2.1 - (-2.3 / 3.4)))
|
#fun1 = par1 + map1 * (0.01355+par1*(2.1 - (-2.3 / 3.4)))
|
||||||
#fun2 = par1 * par2 - map3
|
#fun2 = par1 * par2 - map3
|
||||||
fun3 = -3.2 + (par2-par1)/(map2+map3)
|
#fun3 = -3.2 + (par2-par1)/(map2+map3)
|
||||||
#fun7 = 1.2
|
#fun7 = 1.2
|
||||||
|
#fun1 = sin(cos(par1))*exp(-1.0*map2)+map4*par2
|
||||||
|
# Test unary map syntax - final test
|
||||||
|
fun3 = exp(-map2)
|
||||||
|
#fun2 = cos(-1.0*map1) + sin(-par1)
|
||||||
END
|
END
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
|
|||||||
@@ -2,44 +2,43 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#include "PFunctionHandler.h"
|
#include "PFunctionHandler.h"
|
||||||
|
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
void syntax()
|
void syntax()
|
||||||
{
|
{
|
||||||
cout << endl << "spirit_fcn_test [--file <filename> [--debug]] | [--help]";
|
std::cout << std::endl << "spirit_fcn_test [--file <filename> [--debug]] | [--help]";
|
||||||
cout << endl << " without arguments: interactive mode";
|
std::cout << std::endl << " without arguments: interactive mode";
|
||||||
cout << endl << " --file <filename>: function block etc. from file";
|
std::cout << std::endl << " --file <filename>: function block etc. from file";
|
||||||
cout << endl << " --help: this help";
|
std::cout << std::endl << " --help: this help";
|
||||||
cout << endl << " --debug: will print the ast tree only (no evaluatio)";
|
std::cout << std::endl << " --debug: will print the ast tree only (no evaluation)";
|
||||||
cout << endl << endl;
|
std::cout << std::endl << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
void handle_input(vector<string> &lines)
|
void handle_input(std::vector<std::string> &lines)
|
||||||
{
|
{
|
||||||
cout << endl << "will handle input ...";
|
std::cout << std::endl << "will handle input ...";
|
||||||
cout << endl << "you should provide a PAR, a MAP, and a FUNCTION block";
|
std::cout << std::endl << "you should provide a PAR, a MAP, and a FUNCTION block";
|
||||||
cout << endl << " Map block:";
|
std::cout << std::endl << " Map block:";
|
||||||
cout << endl << " MAP <map1> <map2> ... <mapM>";
|
std::cout << std::endl << " MAP <map1> <map2> ... <mapM>";
|
||||||
cout << endl << " Parameter block:";
|
std::cout << std::endl << " Parameter block:";
|
||||||
cout << endl << " PAR <par1> <par2> ... <parN>";
|
std::cout << std::endl << " PAR <par1> <par2> ... <parN>";
|
||||||
cout << endl << " Function Block:";
|
std::cout << std::endl << " Function Block:";
|
||||||
cout << endl << " FUNCTION";
|
std::cout << std::endl << " FUNCTION";
|
||||||
cout << endl << " fun1 = <function1>";
|
std::cout << std::endl << " fun1 = <function1>";
|
||||||
cout << endl << " fun2 = <function2>";
|
std::cout << std::endl << " fun2 = <function2>";
|
||||||
cout << endl << " ...";
|
std::cout << std::endl << " ...";
|
||||||
cout << endl << " funX = <functionX>";
|
std::cout << std::endl << " funX = <functionX>";
|
||||||
cout << endl << " END";
|
std::cout << std::endl << " END";
|
||||||
cout << endl << "to get out of the input handle type '.q'";
|
std::cout << std::endl << "to get out of the input handle type '.q'";
|
||||||
cout << endl;
|
std::cout << std::endl;
|
||||||
bool done = false;
|
bool done = false;
|
||||||
char str[128];
|
char str[128];
|
||||||
do {
|
do {
|
||||||
cout << ">> ";
|
std::cout << ">> ";
|
||||||
cin.getline(str, sizeof(str));
|
std::cin.getline(str, sizeof(str));
|
||||||
if (!strcmp(str, ".q"))
|
if (!strcmp(str, ".q"))
|
||||||
done = true;
|
done = true;
|
||||||
else
|
else
|
||||||
@@ -76,39 +75,33 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PFunctionHandler *fcnHandler = 0;
|
std::unique_ptr<PFunctionHandler> fcnHandler;
|
||||||
|
|
||||||
if (inputFile) {
|
if (inputFile) {
|
||||||
fcnHandler = new PFunctionHandler(argv[2], debug);
|
fcnHandler = std::make_unique<PFunctionHandler>(argv[2], debug);
|
||||||
} else {
|
} else {
|
||||||
vector<string> lines;
|
std::vector<std::string> lines;
|
||||||
handle_input(lines);
|
handle_input(lines);
|
||||||
fcnHandler = new PFunctionHandler(lines);
|
fcnHandler = std::make_unique<PFunctionHandler>(lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fcnHandler == 0) {
|
if (fcnHandler == 0) {
|
||||||
cout << endl << "Couldn't invoke function handler, sorry ..." << endl;
|
std::cout << std::endl << "Couldn't invoke function handler, sorry ..." << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool go_on = fcnHandler->IsValid();
|
bool go_on = fcnHandler->IsValid();
|
||||||
|
|
||||||
if (go_on) {
|
if (go_on) {
|
||||||
cout << endl << "will do the parsing ...";
|
std::cout << std::endl << "will do the parsing ...";
|
||||||
if (fcnHandler->DoParse()) {
|
if (fcnHandler->DoParse()) {
|
||||||
if (!debug) {
|
if (!debug) {
|
||||||
cout << endl << "will do the evaluation ...";
|
std::cout << std::endl << "will do the evaluation ...";
|
||||||
for (unsigned int i=0; i<fcnHandler->GetNoOfFuncs(); i++)
|
for (unsigned int i=0; i<fcnHandler->GetNoOfFuncs(); i++)
|
||||||
cout << endl << "FUN" << fcnHandler->GetFuncNo(i) << " = " << fcnHandler->Eval(fcnHandler->GetFuncNo(i));
|
std::cout << std::endl << "FUN" << fcnHandler->GetFuncNo(i) << " = " << fcnHandler->Eval(fcnHandler->GetFuncNo(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up
|
|
||||||
if (fcnHandler) {
|
|
||||||
delete fcnHandler;
|
|
||||||
fcnHandler = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
#-------------------------------------------------
|
|
||||||
# spirit_fcn_test.mak
|
|
||||||
#-------------------------------------------------
|
|
||||||
|
|
||||||
# Paths
|
|
||||||
STD_INC = "C:\Program Files\Microsoft Visual Studio 9.0\VC\include"
|
|
||||||
BOOST_INC = "D:\boost_1_43_0\boost_1_43_0"
|
|
||||||
|
|
||||||
LIB_PATH_1 = "C:\Program Files\Microsoft Visual Studio 9.0\VC\lib"
|
|
||||||
LIB_PATH_2 = "C:\Program Files\Microsoft SDKs\Windows\v6.0a\Lib"
|
|
||||||
LIB_PATH_3 = "D:\boost_1_43_0\boost_1_43_0\bin.v2\libs"
|
|
||||||
|
|
||||||
# Compiler etc
|
|
||||||
CC = cl
|
|
||||||
LINK32 = link
|
|
||||||
|
|
||||||
# Options
|
|
||||||
CXXFLAGS = /c /W3 /O2 /nologo /EHsc /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /I$(STD_INC) /I$(BOOST_INC)
|
|
||||||
LINK32_FLAGS = /nologo /subsystem:console /incremental:no /machine:I386
|
|
||||||
|
|
||||||
fln = spirit_fcn_test
|
|
||||||
|
|
||||||
OBJ = $(fln).obj PFunction.obj PFunctionHandler.obj
|
|
||||||
|
|
||||||
$(fln): $(OBJ)
|
|
||||||
$(LINK32) $(LINK32_FLAGS) /LIBPATH:$(LIB_PATH_1) /LIBPATH:$(LIB_PATH_2) /LIBPATH:$(LIB_PATH_3) $(OBJ) /out:$(fln).exe
|
|
||||||
|
|
||||||
.cpp.obj:
|
|
||||||
$(CC) $(CXXFLAGS) $<
|
|
||||||
|
|
||||||
clean:
|
|
||||||
@del /f *.obj
|
|
||||||
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#------------------------------------------------------
|
|
||||||
# spirit_fcn_test.pro
|
|
||||||
# qmake file for spirit_fcn_test
|
|
||||||
#
|
|
||||||
# Andreas Suter, 2007/12/10
|
|
||||||
#
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
#------------------------------------------------------
|
|
||||||
|
|
||||||
MAKEFILE = Makefile
|
|
||||||
|
|
||||||
CONFIG += warn_on debug
|
|
||||||
|
|
||||||
HEADERS = PFunctionGrammar.h \
|
|
||||||
PFunction.h \
|
|
||||||
PFunctionHandler.h
|
|
||||||
|
|
||||||
SOURCES = spirit_fcn_test.cpp \
|
|
||||||
PFunction.cpp \
|
|
||||||
PFunctionHandler.cpp
|
|
||||||
|
|
||||||
TARGET=spirit_fcn_test
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user