add missing files.
This commit is contained in:
parent
cbbe1d21a7
commit
34d2e0c9cc
103
src/musredit_qt5/mupp/var/include/PAnnotation.hpp
Normal file
103
src/musredit_qt5/mupp/var/include/PAnnotation.hpp
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
PAnnotation.hpp
|
||||||
|
|
||||||
|
Author: Andreas Suter
|
||||||
|
e-mail: andreas.suter@psi.ch
|
||||||
|
|
||||||
|
Based on Joel de Guzman example on calc7,
|
||||||
|
see https://github.com/boostorg/spirit
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2020 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 _PANNOTATION_HPP_
|
||||||
|
#define _PANNOTATION_HPP_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <boost/variant/apply_visitor.hpp>
|
||||||
|
#include <boost/type_traits/is_base_of.hpp>
|
||||||
|
#include <boost/mpl/bool.hpp>
|
||||||
|
#include "PAst.hpp"
|
||||||
|
|
||||||
|
namespace mupp
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// The annotation handler links the AST to a map of iterator positions
|
||||||
|
// for the purpose of subsequent semantic error handling when the
|
||||||
|
// program is being compiled.
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename Iterator>
|
||||||
|
struct PAnnotation
|
||||||
|
{
|
||||||
|
template <typename, typename>
|
||||||
|
struct result { typedef void type; };
|
||||||
|
|
||||||
|
std::vector<Iterator>& iters;
|
||||||
|
PAnnotation(std::vector<Iterator>& iters) : iters(iters) {}
|
||||||
|
|
||||||
|
struct set_id
|
||||||
|
{
|
||||||
|
typedef void result_type;
|
||||||
|
|
||||||
|
int id;
|
||||||
|
set_id(int id) : id(id) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void operator()(T& x) const
|
||||||
|
{
|
||||||
|
this->dispatch(x, boost::is_base_of<ast::tagged, T>());
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will catch all nodes except those inheriting from ast::tagged
|
||||||
|
template <typename T>
|
||||||
|
void dispatch(T& x, boost::mpl::false_) const
|
||||||
|
{
|
||||||
|
// (no-op) no need for tags
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will catch all nodes inheriting from ast::tagged
|
||||||
|
template <typename T>
|
||||||
|
void dispatch(T& x, boost::mpl::true_) const
|
||||||
|
{
|
||||||
|
x.id = id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void operator()(ast::operand& ast, Iterator pos) const
|
||||||
|
{
|
||||||
|
int id = iters.size();
|
||||||
|
iters.push_back(pos);
|
||||||
|
boost::apply_visitor(set_id(id), ast);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(ast::assignment& ast, Iterator pos) const
|
||||||
|
{
|
||||||
|
int id = iters.size();
|
||||||
|
iters.push_back(pos);
|
||||||
|
ast.lhs.id = id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _PANNOTATION_HPP_
|
||||||
|
|
113
src/musredit_qt5/mupp/var/include/PErrorHandler.hpp
Normal file
113
src/musredit_qt5/mupp/var/include/PErrorHandler.hpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
PErrorHandler.hpp
|
||||||
|
|
||||||
|
Author: Andreas Suter
|
||||||
|
e-mail: andreas.suter@psi.ch
|
||||||
|
|
||||||
|
Based on Joel de Guzman example on calc7,
|
||||||
|
see https://github.com/boostorg/spirit
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2020 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 _PERROR_HANDLER_HPP_
|
||||||
|
#define _PERROR_HANDLER_HPP_
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace mupp
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// The error handler
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename Iterator>
|
||||||
|
struct PErrorHandler
|
||||||
|
{
|
||||||
|
template <typename, typename, typename>
|
||||||
|
struct result { typedef void type; };
|
||||||
|
|
||||||
|
PErrorHandler(Iterator first, Iterator last)
|
||||||
|
: first(first), last(last) {}
|
||||||
|
|
||||||
|
template <typename Message, typename What>
|
||||||
|
void operator()(
|
||||||
|
Message const& message,
|
||||||
|
What const& what,
|
||||||
|
Iterator err_pos) const
|
||||||
|
{
|
||||||
|
int line;
|
||||||
|
Iterator line_start = get_pos(err_pos, line);
|
||||||
|
if (err_pos != last) {
|
||||||
|
std::cout << message << what << ':' << std::endl;
|
||||||
|
std::cout << get_line(line_start) << std::endl;
|
||||||
|
for (; line_start != err_pos; ++line_start)
|
||||||
|
std::cout << ' ';
|
||||||
|
std::cout << "^~~" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "**ERROR** Unexpected end of file. ";
|
||||||
|
std::cout << message << what << " line " << line << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator get_pos(Iterator err_pos, int& line) const
|
||||||
|
{
|
||||||
|
line = 1;
|
||||||
|
Iterator i = first;
|
||||||
|
Iterator line_start = first;
|
||||||
|
while (i != err_pos) {
|
||||||
|
bool eol = false;
|
||||||
|
if (i != err_pos && *i == '\r') { // CR
|
||||||
|
eol = true;
|
||||||
|
line_start = ++i;
|
||||||
|
}
|
||||||
|
if (i != err_pos && *i == '\n') { // LF
|
||||||
|
eol = true;
|
||||||
|
line_start = ++i;
|
||||||
|
}
|
||||||
|
if (eol)
|
||||||
|
++line;
|
||||||
|
else
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return line_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_line(Iterator err_pos) const
|
||||||
|
{
|
||||||
|
Iterator i = err_pos;
|
||||||
|
// position i to the next EOL
|
||||||
|
while (i != last && (*i != '\r' && *i != '\n'))
|
||||||
|
++i;
|
||||||
|
return std::string(err_pos, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator first;
|
||||||
|
Iterator last;
|
||||||
|
std::vector<Iterator> iters;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //_PERROR_HANDLER_HPP_
|
||||||
|
|
83
src/musredit_qt5/mupp/var/include/PExpression.hpp
Normal file
83
src/musredit_qt5/mupp/var/include/PExpression.hpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
PExpression.hpp
|
||||||
|
|
||||||
|
Author: Andreas Suter
|
||||||
|
e-mail: andreas.suter@psi.ch
|
||||||
|
|
||||||
|
Based on Joel de Guzman example on calc7,
|
||||||
|
see https://github.com/boostorg/spirit
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2020 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 _PEXPRESSION_HPP_
|
||||||
|
#define _PEXPRESSION_HPP_
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Spirit v2.5 allows you to suppress automatic generation
|
||||||
|
// of predefined terminals to speed up complation. With
|
||||||
|
// BOOST_SPIRIT_NO_PREDEFINED_TERMINALS defined, you are
|
||||||
|
// responsible in creating instances of the terminals that
|
||||||
|
// you need (e.g. see qi::uint_type uint_ below).
|
||||||
|
#define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Uncomment this if you want to enable debugging
|
||||||
|
// #define BOOST_SPIRIT_QI_DEBUG
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <boost/spirit/include/qi.hpp>
|
||||||
|
#include "PAst.hpp"
|
||||||
|
#include "PErrorHandler.hpp"
|
||||||
|
#include "PSkipper.hpp"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace mupp { namespace parser
|
||||||
|
{
|
||||||
|
namespace qi = boost::spirit::qi;
|
||||||
|
namespace ascii = boost::spirit::ascii;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// The expression grammar
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename Iterator>
|
||||||
|
struct PExpression : qi::grammar<Iterator, ast::expression(), PSkipper<Iterator> >
|
||||||
|
{
|
||||||
|
PExpression(PErrorHandler<Iterator>& error_handler);
|
||||||
|
|
||||||
|
qi::symbols<char, ast::optoken> additive_op, multiplicative_op, unary_op;
|
||||||
|
qi::symbols<char, ast::funid> fun_tok;
|
||||||
|
|
||||||
|
qi::rule<Iterator, ast::expression(), PSkipper<Iterator> > expr;
|
||||||
|
qi::rule<Iterator, ast::expression(), PSkipper<Iterator> > additive_expr;
|
||||||
|
qi::rule<Iterator, ast::expression(), PSkipper<Iterator> > multiplicative_expr;
|
||||||
|
qi::rule<Iterator, ast::operand(), PSkipper<Iterator> > unary_expr;
|
||||||
|
qi::rule<Iterator, ast::operand(), PSkipper<Iterator> > primary_expr;
|
||||||
|
qi::rule<Iterator, std::string(), PSkipper<Iterator> > identifier;
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif // _PEXPRESSION_HPP_
|
||||||
|
|
||||||
|
|
155
src/musredit_qt5/mupp/var/include/PExpressionDef.hpp
Normal file
155
src/musredit_qt5/mupp/var/include/PExpressionDef.hpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
PExpressionDef.hpp
|
||||||
|
|
||||||
|
Author: Andreas Suter
|
||||||
|
e-mail: andreas.suter@psi.ch
|
||||||
|
|
||||||
|
Based on Joel de Guzman example on calc7,
|
||||||
|
see https://github.com/boostorg/spirit
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2020 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. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "PExpression.hpp"
|
||||||
|
#include "PErrorHandler.hpp"
|
||||||
|
#include "PAnnotation.hpp"
|
||||||
|
#include <boost/spirit/include/phoenix_function.hpp>
|
||||||
|
|
||||||
|
namespace mupp { namespace parser
|
||||||
|
{
|
||||||
|
template <typename Iterator>
|
||||||
|
PExpression<Iterator>::PExpression(PErrorHandler<Iterator>& error_handler)
|
||||||
|
: PExpression::base_type(expr)
|
||||||
|
{
|
||||||
|
qi::_1_type _1;
|
||||||
|
qi::_2_type _2;
|
||||||
|
qi::_3_type _3;
|
||||||
|
qi::_4_type _4;
|
||||||
|
|
||||||
|
qi::char_type char_;
|
||||||
|
qi::double_type double_;
|
||||||
|
qi::_val_type _val;
|
||||||
|
qi::raw_type raw;
|
||||||
|
qi::lexeme_type lexeme;
|
||||||
|
qi::alpha_type alpha;
|
||||||
|
qi::alnum_type alnum;
|
||||||
|
|
||||||
|
using qi::on_error;
|
||||||
|
using qi::on_success;
|
||||||
|
using qi::fail;
|
||||||
|
using boost::phoenix::function;
|
||||||
|
|
||||||
|
typedef function<mupp::PErrorHandler<Iterator> > error_handler_function;
|
||||||
|
typedef function<mupp::PAnnotation<Iterator> > annotation_function;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// Tokens
|
||||||
|
additive_op.add
|
||||||
|
("+", ast::op_plus)
|
||||||
|
("-", ast::op_minus)
|
||||||
|
;
|
||||||
|
|
||||||
|
multiplicative_op.add
|
||||||
|
("*", ast::op_times)
|
||||||
|
("/", ast::op_divide)
|
||||||
|
;
|
||||||
|
|
||||||
|
unary_op.add
|
||||||
|
("+", ast::op_positive)
|
||||||
|
("-", ast::op_negative)
|
||||||
|
;
|
||||||
|
|
||||||
|
fun_tok.add
|
||||||
|
("max", ast::fun_max)
|
||||||
|
("min", ast::fun_min)
|
||||||
|
("abs", ast::fun_abs)
|
||||||
|
("sin", ast::fun_sin)
|
||||||
|
("cos", ast::fun_cos)
|
||||||
|
("tan", ast::fun_tan)
|
||||||
|
("exp", ast::fun_exp)
|
||||||
|
("log", ast::fun_log)
|
||||||
|
("ln", ast::fun_ln)
|
||||||
|
;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// Grammar
|
||||||
|
expr =
|
||||||
|
additive_expr.alias()
|
||||||
|
;
|
||||||
|
|
||||||
|
additive_expr =
|
||||||
|
multiplicative_expr
|
||||||
|
>> *(additive_op > multiplicative_expr)
|
||||||
|
;
|
||||||
|
|
||||||
|
multiplicative_expr =
|
||||||
|
unary_expr
|
||||||
|
>> *(multiplicative_op > unary_expr)
|
||||||
|
;
|
||||||
|
|
||||||
|
unary_expr =
|
||||||
|
primary_expr
|
||||||
|
| (unary_op > primary_expr)
|
||||||
|
;
|
||||||
|
|
||||||
|
primary_expr =
|
||||||
|
double_
|
||||||
|
| identifier
|
||||||
|
| fun_tok > '(' > expr > ')'
|
||||||
|
| "pow(" > expr > ',' > expr > ')'
|
||||||
|
| '(' > expr > ')'
|
||||||
|
;
|
||||||
|
|
||||||
|
identifier =
|
||||||
|
raw[lexeme['$' >> *(alnum | '_')]]
|
||||||
|
;
|
||||||
|
|
||||||
|
// name all the rules
|
||||||
|
additive_expr.name("additive_expr");
|
||||||
|
multiplicative_expr.name("multiplicative_expr");
|
||||||
|
unary_expr.name("unary_expr");
|
||||||
|
primary_expr.name("primary_expr");
|
||||||
|
identifier.name("identifier");
|
||||||
|
|
||||||
|
// Debugging and error handling and reporting support.
|
||||||
|
BOOST_SPIRIT_DEBUG_NODES(
|
||||||
|
(expr)
|
||||||
|
(additive_expr)
|
||||||
|
(multiplicative_expr)
|
||||||
|
(unary_expr)
|
||||||
|
(primary_expr)
|
||||||
|
(identifier)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Error handling: on error in expr, call error_handler.
|
||||||
|
on_error<fail>(expr,
|
||||||
|
error_handler_function(error_handler)(
|
||||||
|
"**ERROR** Expecting ", _4, _3));
|
||||||
|
|
||||||
|
// Annotation: on success in primary_expr, call annotation.
|
||||||
|
on_success(primary_expr,
|
||||||
|
annotation_function(error_handler.iters)(_val, _1));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
159
src/musredit_qt5/mupp/var/include/PProgram.hpp
Normal file
159
src/musredit_qt5/mupp/var/include/PProgram.hpp
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
PProgram.hpp
|
||||||
|
|
||||||
|
Author: Andreas Suter
|
||||||
|
e-mail: andreas.suter@psi.ch
|
||||||
|
|
||||||
|
Based on Joel de Guzman example on calc7,
|
||||||
|
see https://github.com/boostorg/spirit
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2020 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 _PPROGRAM_HPP_
|
||||||
|
#define _PPROGRAM_HPP_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "PAst.hpp"
|
||||||
|
#include "PErrorHandler.hpp"
|
||||||
|
|
||||||
|
#include <boost/function.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/spirit/include/phoenix_core.hpp>
|
||||||
|
#include <boost/spirit/include/phoenix_function.hpp>
|
||||||
|
#include <boost/spirit/include/phoenix_operator.hpp>
|
||||||
|
|
||||||
|
namespace mupp { namespace prog {
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Variable Handler
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
class PVarHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PVarHandler() : fName("") {}
|
||||||
|
|
||||||
|
void SetName(std::string name) { fName = name; }
|
||||||
|
void SetValue(std::vector<double> &dval) { fValue = dval; }
|
||||||
|
void SetValue(double dval, unsigned idx);
|
||||||
|
void SetError(std::vector<double> &dval) { fError = dval; }
|
||||||
|
void SetError(double dval, unsigned idx);
|
||||||
|
|
||||||
|
std::string GetName() { return fName; }
|
||||||
|
unsigned int GetSize() { return (fValue.size() == fError.size()) ? fValue.size() : 0; }
|
||||||
|
std::vector<double> GetValue() { return fValue; }
|
||||||
|
double GetValue(unsigned int idx) { return (idx < fValue.size()) ? fValue[idx] : 0; }
|
||||||
|
std::vector<double> GetError() { return fError; }
|
||||||
|
double GetError(unsigned int idx) { return (idx < fError.size()) ? fError[idx] : 0; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string fName;
|
||||||
|
std::vector<double> fValue;
|
||||||
|
std::vector<double> fError;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Program Semantic Analysis
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
struct PProgram
|
||||||
|
{
|
||||||
|
typedef bool result_type;
|
||||||
|
|
||||||
|
template <typename PErrorHandler>
|
||||||
|
PProgram(PErrorHandler& error_handler_)
|
||||||
|
{
|
||||||
|
using namespace boost::phoenix::arg_names;
|
||||||
|
namespace phx = boost::phoenix;
|
||||||
|
using boost::phoenix::function;
|
||||||
|
error_handler = function<PErrorHandler>(error_handler_)(
|
||||||
|
"**ERROR** ", _2, phx::cref(error_handler_.iters)[_1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(ast::nil) { BOOST_ASSERT(0); return false; }
|
||||||
|
bool operator()(double x);
|
||||||
|
bool operator()(ast::assignment const &x);
|
||||||
|
bool operator()(ast::expression const &x);
|
||||||
|
bool operator()(ast::function const &x);
|
||||||
|
bool operator()(ast::operation const &x);
|
||||||
|
bool operator()(ast::power const &x);
|
||||||
|
bool operator()(ast::statement const &x);
|
||||||
|
bool operator()(ast::statement_list const &x);
|
||||||
|
bool operator()(ast::unary const &x);
|
||||||
|
bool operator()(ast::variable const &x);
|
||||||
|
bool operator()(ast::variable_declaration const &x);
|
||||||
|
|
||||||
|
void add_predef_var_values(const std::string &name,
|
||||||
|
std::vector<double> &val,
|
||||||
|
std::vector<double> &err);
|
||||||
|
|
||||||
|
void add_var(std::string const& name);
|
||||||
|
bool find_var(std::string const &name);
|
||||||
|
bool find_var(std::string const &name, unsigned int &idx);
|
||||||
|
std::string pos_to_var(std::string const &name, bool &ok);
|
||||||
|
|
||||||
|
std::vector<PVarHandler> getVars() { return fVariable; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<PVarHandler> fVariable;
|
||||||
|
std::map<int, std::string> fVarPos;
|
||||||
|
|
||||||
|
boost::function<
|
||||||
|
void(int tag, std::string const& what)>
|
||||||
|
error_handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Program Evaluation
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
struct PProgEval
|
||||||
|
{
|
||||||
|
typedef std::vector<double> result_type;
|
||||||
|
|
||||||
|
PProgEval(std::vector<PVarHandler> var) : fVariable(var) {}
|
||||||
|
|
||||||
|
std::vector<double> operator()(ast::nil);
|
||||||
|
std::vector<double> operator()(double x);
|
||||||
|
std::vector<double> operator()(ast::assignment const &x);
|
||||||
|
std::vector<double> operator()(ast::expression const &x);
|
||||||
|
std::vector<double> operator()(ast::function const &x);
|
||||||
|
std::vector<double> operator()(ast::operation const &x, std::vector<double> lhs);
|
||||||
|
std::vector<double> operator()(ast::power const &x);
|
||||||
|
std::vector<double> operator()(ast::statement const &x);
|
||||||
|
std::vector<double> operator()(ast::statement_list const &x);
|
||||||
|
std::vector<double> operator()(ast::unary const &x);
|
||||||
|
std::vector<double> operator()(ast::variable const &x);
|
||||||
|
std::vector<double> operator()(ast::variable_declaration const &x);
|
||||||
|
|
||||||
|
PVarHandler getVar(const std::string name, bool &ok);
|
||||||
|
void print_result();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<PVarHandler> fVariable;
|
||||||
|
|
||||||
|
unsigned int find_var(std::string const &name);
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif // _PPROGRAM_HPP_
|
73
src/musredit_qt5/mupp/var/include/PSkipper.hpp
Normal file
73
src/musredit_qt5/mupp/var/include/PSkipper.hpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
PSkipper.hpp
|
||||||
|
|
||||||
|
Author: Andreas Suter
|
||||||
|
e-mail: andreas.suter@psi.ch
|
||||||
|
|
||||||
|
Based on Joel de Guzman example on a mini_c,
|
||||||
|
see https://github.com/boostorg/spirit
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2020 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 _PSKIPPER_HPP_
|
||||||
|
#define _PSKIPPER_HPP_
|
||||||
|
|
||||||
|
#include <boost/spirit/include/qi.hpp>
|
||||||
|
|
||||||
|
namespace mupp { namespace parser
|
||||||
|
{
|
||||||
|
namespace qi = boost::spirit::qi;
|
||||||
|
namespace ascii = boost::spirit::ascii;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// The skipper grammar
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename Iterator>
|
||||||
|
struct PSkipper : qi::grammar<Iterator>
|
||||||
|
{
|
||||||
|
PSkipper() : PSkipper::base_type(start)
|
||||||
|
{
|
||||||
|
qi::char_type char_;
|
||||||
|
qi::lit_type lit;
|
||||||
|
qi::eol_type eol;
|
||||||
|
ascii::space_type space;
|
||||||
|
ascii::print_type print;
|
||||||
|
|
||||||
|
single_line_comment = (lit('%') | lit('#') | lit("//")) >> *print >> eol;
|
||||||
|
|
||||||
|
start =
|
||||||
|
space // tab/space/cr/lf
|
||||||
|
| "/*" >> *(char_ - "*/") >> "*/" // C-style comments
|
||||||
|
| single_line_comment
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
qi::rule<Iterator> single_line_comment;
|
||||||
|
qi::rule<Iterator> start;
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif // _PSKIPPER_HPP_
|
||||||
|
|
||||||
|
|
58
src/musredit_qt5/mupp/var/include/PStatement.hpp
Normal file
58
src/musredit_qt5/mupp/var/include/PStatement.hpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
PStatement.hpp
|
||||||
|
|
||||||
|
Author: Andreas Suter
|
||||||
|
e-mail: andreas.suter@psi.ch
|
||||||
|
|
||||||
|
Based on Joel de Guzman example on calc7,
|
||||||
|
see https://github.com/boostorg/spirit
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2020 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 _PSTATEMENT_HPP_
|
||||||
|
#define _PSTATEMENT_HPP_
|
||||||
|
|
||||||
|
#include "PExpression.hpp"
|
||||||
|
|
||||||
|
namespace mupp { namespace parser
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// The statement grammar
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename Iterator>
|
||||||
|
struct PStatement : qi::grammar<Iterator, ast::statement_list(), PSkipper<Iterator> >
|
||||||
|
{
|
||||||
|
PStatement(PErrorHandler<Iterator>& error_handler);
|
||||||
|
|
||||||
|
PExpression<Iterator> expr;
|
||||||
|
qi::rule<Iterator, ast::statement_list(), PSkipper<Iterator> > statement_list;
|
||||||
|
qi::rule<Iterator, ast::variable_declaration(), PSkipper<Iterator> > variable_declaration;
|
||||||
|
qi::rule<Iterator, ast::assignment(), PSkipper<Iterator> > assignment;
|
||||||
|
qi::rule<Iterator, std::string(), PSkipper<Iterator> > identifier;
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif // _PSTATEMENT_HPP_
|
||||||
|
|
||||||
|
|
107
src/musredit_qt5/mupp/var/include/PStatementDef.hpp
Normal file
107
src/musredit_qt5/mupp/var/include/PStatementDef.hpp
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
PStatementDef.hpp
|
||||||
|
|
||||||
|
Author: Andreas Suter
|
||||||
|
e-mail: andreas.suter@psi.ch
|
||||||
|
|
||||||
|
Based on Joel de Guzman example on calc7,
|
||||||
|
see https://github.com/boostorg/spirit
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2020 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. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "PStatement.hpp"
|
||||||
|
#include "PErrorHandler.hpp"
|
||||||
|
#include "PAnnotation.hpp"
|
||||||
|
|
||||||
|
namespace mupp { namespace parser
|
||||||
|
{
|
||||||
|
template <typename Iterator>
|
||||||
|
PStatement<Iterator>::PStatement(PErrorHandler<Iterator>& error_handler)
|
||||||
|
: PStatement::base_type(statement_list), expr(error_handler)
|
||||||
|
{
|
||||||
|
qi::_1_type _1;
|
||||||
|
qi::_2_type _2;
|
||||||
|
qi::_3_type _3;
|
||||||
|
qi::_4_type _4;
|
||||||
|
|
||||||
|
qi::_val_type _val;
|
||||||
|
qi::raw_type raw;
|
||||||
|
qi::lexeme_type lexeme;
|
||||||
|
qi::alpha_type alpha;
|
||||||
|
qi::alnum_type alnum;
|
||||||
|
|
||||||
|
using qi::on_error;
|
||||||
|
using qi::on_success;
|
||||||
|
using qi::fail;
|
||||||
|
using boost::phoenix::function;
|
||||||
|
|
||||||
|
typedef function<mupp::PErrorHandler<Iterator> > error_handler_function;
|
||||||
|
typedef function<mupp::PAnnotation<Iterator> > annotation_function;
|
||||||
|
|
||||||
|
statement_list =
|
||||||
|
+(variable_declaration | assignment)
|
||||||
|
;
|
||||||
|
|
||||||
|
identifier =
|
||||||
|
raw[lexeme[(alpha | '_') >> *(alnum | '_')]]
|
||||||
|
;
|
||||||
|
|
||||||
|
variable_declaration =
|
||||||
|
lexeme["var" >> !(alnum | '_')] // make sure we have whole words
|
||||||
|
> identifier
|
||||||
|
> -('=' > expr)
|
||||||
|
;
|
||||||
|
|
||||||
|
assignment =
|
||||||
|
identifier
|
||||||
|
> '='
|
||||||
|
> expr
|
||||||
|
;
|
||||||
|
|
||||||
|
// name all the rules
|
||||||
|
statement_list.name("statement_list");
|
||||||
|
identifier.name("identifier");
|
||||||
|
variable_declaration.name("variable_declaration");
|
||||||
|
assignment.name("assignment");
|
||||||
|
|
||||||
|
// Debugging and error handling and reporting support.
|
||||||
|
BOOST_SPIRIT_DEBUG_NODES(
|
||||||
|
(statement_list)
|
||||||
|
(identifier)
|
||||||
|
(variable_declaration)
|
||||||
|
(assignment)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Error handling: on error in statement_list, call error_handler.
|
||||||
|
on_error<fail>(statement_list,
|
||||||
|
error_handler_function(error_handler)(
|
||||||
|
"**ERROR** Expecting ", _4, _3));
|
||||||
|
|
||||||
|
// Annotation: on success in assignment, call annotation.
|
||||||
|
on_success(assignment,
|
||||||
|
annotation_function(error_handler.iters)(_val, _1));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
40
src/musredit_qt5/mupp/var/src/PExpression.cpp
Normal file
40
src/musredit_qt5/mupp/var/src/PExpression.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
PExpression.hpp
|
||||||
|
|
||||||
|
Author: Andreas Suter
|
||||||
|
e-mail: andreas.suter@psi.ch
|
||||||
|
|
||||||
|
Based on Joel de Guzman example on calc7,
|
||||||
|
see https://github.com/boostorg/spirit
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2020 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. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma warning(disable: 4345)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "PExpressionDef.hpp"
|
||||||
|
|
||||||
|
typedef std::string::const_iterator iterator_type;
|
||||||
|
template struct mupp::parser::PExpression<iterator_type>;
|
661
src/musredit_qt5/mupp/var/src/PProgram.cpp
Normal file
661
src/musredit_qt5/mupp/var/src/PProgram.cpp
Normal file
@ -0,0 +1,661 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
PProgram.cpp
|
||||||
|
|
||||||
|
Author: Andreas Suter
|
||||||
|
e-mail: andreas.suter@psi.ch
|
||||||
|
|
||||||
|
Based on Joel de Guzman example on calc7,
|
||||||
|
see https://github.com/boostorg/spirit
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2020 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. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "PProgram.hpp"
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/variant/apply_visitor.hpp>
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
namespace mupp { namespace prog {
|
||||||
|
void PVarHandler::SetValue(double dval, unsigned idx)
|
||||||
|
{
|
||||||
|
if (idx >= fValue.size()) {
|
||||||
|
std::cerr << "**ERROR** SetValue: idx=" << idx << " is out-of-range." << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fValue[idx] = dval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PVarHandler::SetError(double dval, unsigned idx)
|
||||||
|
{
|
||||||
|
if (idx >= fError.size()) {
|
||||||
|
std::cerr << "**ERROR** SetError: idx=" << idx << " is out-of-range." << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fError[idx] = dval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PProgram::operator()(double x)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PProgram::operator()(ast::assignment const &x)
|
||||||
|
{
|
||||||
|
// check that the variable exists
|
||||||
|
if (!find_var(x.lhs.name)) {
|
||||||
|
error_handler(0, "Undeclared variable: " + x.lhs.name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(*this)(x.rhs)) {
|
||||||
|
std::cout << "**SEM ERROR** in var assignment of var: " << x.lhs.name << std::endl;
|
||||||
|
std::cout << " rhs is missing or has an error." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PProgram::operator()(ast::expression const &x)
|
||||||
|
{
|
||||||
|
if (!boost::apply_visitor(*this, x.first))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
BOOST_FOREACH(ast::operation const& oper, x.rest) {
|
||||||
|
if (!(*this)(oper))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PProgram::operator()(ast::function const &x)
|
||||||
|
{
|
||||||
|
switch (x.func_id) {
|
||||||
|
case ast::fun_max:
|
||||||
|
case ast::fun_min:
|
||||||
|
case ast::fun_abs:
|
||||||
|
case ast::fun_sin:
|
||||||
|
case ast::fun_cos:
|
||||||
|
case ast::fun_tan:
|
||||||
|
case ast::fun_exp:
|
||||||
|
case ast::fun_log:
|
||||||
|
case ast::fun_ln:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(*this)(x.arg)) {
|
||||||
|
std::cout << "**SEM ERROR** in function: arg is missing or has an error." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PProgram::operator()(ast::operation const &x)
|
||||||
|
{
|
||||||
|
if (!boost::apply_visitor(*this, x.operand_))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (x.operator_) {
|
||||||
|
case ast::op_plus:
|
||||||
|
break;
|
||||||
|
case ast::op_minus:
|
||||||
|
break;
|
||||||
|
case ast::op_times:
|
||||||
|
break;
|
||||||
|
case ast::op_divide:
|
||||||
|
break;
|
||||||
|
case ast::op_positive:
|
||||||
|
break;
|
||||||
|
case ast::op_negative:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PProgram::operator()(ast::power const &x)
|
||||||
|
{
|
||||||
|
if (!(*this)(x.base)) {
|
||||||
|
std::cout << "**SEM ERROR** in power: base argument is missing or has an error." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(*this)(x.pow)) {
|
||||||
|
std::cout << "**SEM ERROR** in power: power argument is missing or has an error." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PProgram::operator()(ast::statement const &x)
|
||||||
|
{
|
||||||
|
return boost::apply_visitor(*this, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PProgram::operator()(ast::statement_list const &x)
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(ast::statement const& s, x) {
|
||||||
|
if (!(*this)(s))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PProgram::operator()(ast::unary const &x)
|
||||||
|
{
|
||||||
|
if (!boost::apply_visitor(*this, x.operand_))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (x.operator_) {
|
||||||
|
case ast::op_negative:
|
||||||
|
break;
|
||||||
|
case ast::op_positive:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PProgram::operator()(ast::variable const &x)
|
||||||
|
{
|
||||||
|
bool ok(false);
|
||||||
|
std::string var_name;
|
||||||
|
|
||||||
|
var_name = pos_to_var(x.name, ok);
|
||||||
|
if (!ok) {
|
||||||
|
error_handler(0, "Position variable out-of-range: " + x.name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!find_var(var_name)) {
|
||||||
|
error_handler(0, "Undeclared variable: " + var_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PProgram::operator()(ast::variable_declaration const &x)
|
||||||
|
{
|
||||||
|
if (find_var(x.lhs.name)) {
|
||||||
|
error_handler(0, "Duplicate variable: " + x.lhs.name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x.rhs) { // if there's a RHS initializer
|
||||||
|
bool r = (*this)(*x.rhs);
|
||||||
|
if (r) { // don't add the variable if the RHS fails
|
||||||
|
add_var(x.lhs.name);
|
||||||
|
} else {
|
||||||
|
std::cout << "**SEM ERROR** rhs of var decl, name: " << x.lhs.name << ", failed" << std::endl;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
add_var(x.lhs.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PProgram::add_predef_var_values(const std::string &name,
|
||||||
|
std::vector<double> &val,
|
||||||
|
std::vector<double> &err)
|
||||||
|
{
|
||||||
|
unsigned int idx;
|
||||||
|
if (!find_var(name, idx)) {
|
||||||
|
std::cerr << "**ERROR** couldn't find pre-def variable : " << name << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fVariable[idx].SetValue(val);
|
||||||
|
fVariable[idx].SetError(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PProgram::add_var(std::string const& name)
|
||||||
|
{
|
||||||
|
PVarHandler var;
|
||||||
|
var.SetName(name);
|
||||||
|
fVariable.push_back(var);
|
||||||
|
// add map var <-> pos
|
||||||
|
std::size_t n = fVarPos.size();
|
||||||
|
fVarPos[n] = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PProgram::find_var(std::string const &name)
|
||||||
|
{
|
||||||
|
unsigned int idx;
|
||||||
|
return find_var(name, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PProgram::find_var(std::string const &name, unsigned int &idx)
|
||||||
|
{
|
||||||
|
bool result=false;
|
||||||
|
|
||||||
|
// remove leading '$' of identifier
|
||||||
|
std::string id("");
|
||||||
|
if (name[0] == '$')
|
||||||
|
id = name.substr(1);
|
||||||
|
else
|
||||||
|
id = name;
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<fVariable.size(); i++) {
|
||||||
|
if (id == fVariable[i].GetName()) {
|
||||||
|
idx = i;
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PProgram::pos_to_var(std::string const &name, bool &ok)
|
||||||
|
{
|
||||||
|
std::string result("??");
|
||||||
|
ok = true;
|
||||||
|
|
||||||
|
// remove leading '$' if present
|
||||||
|
if (name[0] == '$')
|
||||||
|
result = name.substr(1);
|
||||||
|
else
|
||||||
|
result = name;
|
||||||
|
|
||||||
|
// check if number
|
||||||
|
char *p;
|
||||||
|
int num = strtol(result.c_str(), &p, 10);
|
||||||
|
if (*p == 0) {
|
||||||
|
if (num >= fVarPos.size())
|
||||||
|
ok = false;
|
||||||
|
else
|
||||||
|
result = fVarPos[num];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<double> PProgEval::operator()(ast::nil)
|
||||||
|
{
|
||||||
|
std::vector<double> result;
|
||||||
|
result.resize(fVariable[0].GetSize());
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<result.size(); i++)
|
||||||
|
result[i] = 0.0;
|
||||||
|
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> PProgEval::operator()(double x)
|
||||||
|
{
|
||||||
|
std::vector<double> result;
|
||||||
|
result.resize(fVariable[0].GetSize());
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<result.size(); i++)
|
||||||
|
result[i] = x;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> PProgEval::operator()(ast::assignment const &x)
|
||||||
|
{
|
||||||
|
std::vector<double> result;
|
||||||
|
result.resize(fVariable[0].GetSize());
|
||||||
|
|
||||||
|
result = (*this)(x.rhs);
|
||||||
|
|
||||||
|
// keep all data under <varName> not <varName>Err.
|
||||||
|
// <varName>Err data go to <varName> error, whereas
|
||||||
|
// <varName> data go to <varName> value
|
||||||
|
std::string name = x.lhs.name;
|
||||||
|
bool errorVal(false);
|
||||||
|
|
||||||
|
// check for error variable
|
||||||
|
std::size_t pos = name.find("Err");
|
||||||
|
if (pos != std::string::npos) { // it is an error variable
|
||||||
|
name = name.substr(0, pos);
|
||||||
|
errorVal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int idx = find_var(name);
|
||||||
|
if (errorVal)
|
||||||
|
fVariable[idx].SetError(result);
|
||||||
|
else
|
||||||
|
fVariable[idx].SetValue(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> PProgEval::operator()(ast::expression const &x)
|
||||||
|
{
|
||||||
|
std::vector<double> vec = boost::apply_visitor(*this, x.first);
|
||||||
|
|
||||||
|
BOOST_FOREACH(ast::operation const& oper, x.rest) {
|
||||||
|
vec = (*this)(oper, vec);
|
||||||
|
}
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> PProgEval::operator()(ast::function const &x)
|
||||||
|
{
|
||||||
|
std::vector<double> vec = (*this)(x.arg);
|
||||||
|
|
||||||
|
double dval;
|
||||||
|
switch(x.func_id) {
|
||||||
|
case ast::fun_max:
|
||||||
|
dval = -1.0e10;
|
||||||
|
for (unsigned int i=0; i<vec.size(); i++) {
|
||||||
|
if (vec[i] > dval)
|
||||||
|
dval = vec[i];
|
||||||
|
}
|
||||||
|
for (unsigned int i=0; i<vec.size(); i++)
|
||||||
|
vec[i] = dval;
|
||||||
|
break;
|
||||||
|
case ast::fun_min:
|
||||||
|
dval = 1.0e10;
|
||||||
|
for (unsigned int i=0; i<vec.size(); i++) {
|
||||||
|
if (vec[i] < dval)
|
||||||
|
dval = vec[i];
|
||||||
|
}
|
||||||
|
for (unsigned int i=0; i<vec.size(); i++)
|
||||||
|
vec[i] = dval;
|
||||||
|
break;
|
||||||
|
case ast::fun_abs:
|
||||||
|
for (unsigned int i=0; i<vec.size(); i++)
|
||||||
|
vec[i] = fabs(vec[i]);
|
||||||
|
break;
|
||||||
|
case ast::fun_sin:
|
||||||
|
for (unsigned int i=0; i<vec.size(); i++)
|
||||||
|
vec[i] = sin(vec[i]);
|
||||||
|
break;
|
||||||
|
case ast::fun_cos:
|
||||||
|
for (unsigned int i=0; i<vec.size(); i++)
|
||||||
|
vec[i] = cos(vec[i]);
|
||||||
|
break;
|
||||||
|
case ast::fun_tan:
|
||||||
|
for (unsigned int i=0; i<vec.size(); i++)
|
||||||
|
vec[i] = tan(vec[i]);
|
||||||
|
break;
|
||||||
|
case ast::fun_exp:
|
||||||
|
for (unsigned int i=0; i<vec.size(); i++)
|
||||||
|
vec[i] = exp(vec[i]);
|
||||||
|
break;
|
||||||
|
case ast::fun_log:
|
||||||
|
for (unsigned int i=0; i<vec.size(); i++) {
|
||||||
|
if (vec[i] <= 0.0) {
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
vec[i] = log10(vec[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ast::fun_ln:
|
||||||
|
for (unsigned int i=0; i<vec.size(); i++) {
|
||||||
|
if (vec[i] <= 0.0) {
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
vec[i] = log(vec[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> PProgEval::operator()(ast::operation const &x, std::vector<double> lhs)
|
||||||
|
{
|
||||||
|
std::vector<double> rhs = boost::apply_visitor(*this, x.operand_);
|
||||||
|
|
||||||
|
// make sure both vectors have the same size
|
||||||
|
if (lhs.size() != rhs.size()) {
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (x.operator_) {
|
||||||
|
case ast::op_plus:
|
||||||
|
for (unsigned int i=0; i<lhs.size(); i++)
|
||||||
|
lhs[i] = lhs[i] + rhs[i];
|
||||||
|
break;
|
||||||
|
case ast::op_minus:
|
||||||
|
for (unsigned int i=0; i<lhs.size(); i++)
|
||||||
|
lhs[i] = lhs[i] - rhs[i];
|
||||||
|
break;
|
||||||
|
case ast::op_times:
|
||||||
|
for (unsigned int i=0; i<lhs.size(); i++)
|
||||||
|
lhs[i] = lhs[i] * rhs[i];
|
||||||
|
break;
|
||||||
|
case ast::op_divide:
|
||||||
|
for (unsigned int i=0; i<lhs.size(); i++) {
|
||||||
|
if (rhs[i] == 0.0) {
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return lhs;
|
||||||
|
} else {
|
||||||
|
lhs[i] = lhs[i] / rhs[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> PProgEval::operator()(ast::power const &x)
|
||||||
|
{
|
||||||
|
std::vector<double> baseV = (*this)(x.base);
|
||||||
|
std::vector<double> powV = (*this)(x.pow);
|
||||||
|
|
||||||
|
if (baseV.size() != powV.size()) {
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return baseV;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> result;
|
||||||
|
result.resize(baseV.size());
|
||||||
|
for (unsigned int i=0; i<baseV.size(); i++)
|
||||||
|
result[i] = pow(baseV[i], powV[i]);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> PProgEval::operator()(ast::statement const &x)
|
||||||
|
{
|
||||||
|
// as35: not-yet-implemented
|
||||||
|
std::vector<double> result;
|
||||||
|
result.resize(fVariable[0].GetSize());
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<result.size(); i++)
|
||||||
|
result[i] = 0.0;
|
||||||
|
|
||||||
|
boost::apply_visitor(*this, x);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> PProgEval::operator()(ast::statement_list const &x)
|
||||||
|
{
|
||||||
|
// as35: not-yet-implemented
|
||||||
|
std::vector<double> result;
|
||||||
|
result.resize(fVariable[0].GetSize());
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<result.size(); i++)
|
||||||
|
result[i] = 0.0;
|
||||||
|
|
||||||
|
BOOST_FOREACH(ast::statement const& s, x) {
|
||||||
|
(*this)(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> PProgEval::operator()(ast::unary const &x)
|
||||||
|
{
|
||||||
|
std::vector<double> vec = boost::apply_visitor(*this, x.operand_);
|
||||||
|
|
||||||
|
if (x.operator_ == ast::op_negative) {
|
||||||
|
for (unsigned int i=0; i<vec.size(); i++) {
|
||||||
|
vec[i] *= -1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> PProgEval::operator()(ast::variable const &x)
|
||||||
|
{
|
||||||
|
std::string name = x.name;
|
||||||
|
bool errorVal(false);
|
||||||
|
|
||||||
|
// check for injected error variable
|
||||||
|
std::size_t pos = name.find("Err");
|
||||||
|
if (pos != std::string::npos) { // it is an error variable
|
||||||
|
name = name.substr(0, pos);
|
||||||
|
errorVal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned idx = find_var(name);
|
||||||
|
|
||||||
|
if (errorVal)
|
||||||
|
return fVariable[idx].GetError();
|
||||||
|
else
|
||||||
|
return fVariable[idx].GetValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> PProgEval::operator()(ast::variable_declaration const &x)
|
||||||
|
{
|
||||||
|
std::vector<double> result;
|
||||||
|
result.resize(fVariable[0].GetSize());
|
||||||
|
|
||||||
|
// keep all data under <varName> not <varName>Err.
|
||||||
|
// <varName>Err data go to <varName> error, whereas
|
||||||
|
// <varName> data go to <varName> value
|
||||||
|
std::string name = x.lhs.name;
|
||||||
|
bool errorVal(false);
|
||||||
|
|
||||||
|
// check for error variable
|
||||||
|
std::size_t pos = name.find("Err");
|
||||||
|
if (pos != std::string::npos) { // it is an error variable
|
||||||
|
name = name.substr(0, pos);
|
||||||
|
errorVal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int idx = find_var(name);
|
||||||
|
|
||||||
|
if (x.rhs) { // if there's a RHS initializer
|
||||||
|
result = (*this)(*x.rhs);
|
||||||
|
} else {
|
||||||
|
// injected variable content
|
||||||
|
if (errorVal)
|
||||||
|
result = fVariable[idx].GetError();
|
||||||
|
else
|
||||||
|
result = fVariable[idx].GetValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorVal)
|
||||||
|
fVariable[idx].SetError(result);
|
||||||
|
else
|
||||||
|
fVariable[idx].SetValue(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int PProgEval::find_var(std::string const &name)
|
||||||
|
{
|
||||||
|
// remove leading '$' of identifier
|
||||||
|
std::string id("");
|
||||||
|
if (name[0] == '$')
|
||||||
|
id = name.substr(1);
|
||||||
|
else
|
||||||
|
id = name;
|
||||||
|
|
||||||
|
unsigned idx = 0;
|
||||||
|
for (unsigned int i=0; i<fVariable.size(); i++) {
|
||||||
|
if (id == fVariable[i].GetName()) {
|
||||||
|
idx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
PVarHandler PProgEval::getVar(const std::string name, bool &ok)
|
||||||
|
{
|
||||||
|
PVarHandler var = fVariable[0];
|
||||||
|
ok = false;
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<fVariable.size(); i++) {
|
||||||
|
if (fVariable[i].GetName() == name) {
|
||||||
|
var = fVariable[i];
|
||||||
|
ok = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PProgEval::print_result()
|
||||||
|
{
|
||||||
|
std::vector<double> val, err;
|
||||||
|
for (unsigned int i=0; i<fVariable.size(); i++) {
|
||||||
|
if (!strstr(fVariable[i].GetName().c_str(), "Err")) {
|
||||||
|
std::cout << "+++++" << std::endl;
|
||||||
|
std::cout << "var Name: " << fVariable[i].GetName() << std::endl;
|
||||||
|
val = fVariable[i].GetValue();
|
||||||
|
err = fVariable[i].GetError();
|
||||||
|
for (unsigned int j=0; j<val.size(); j++) {
|
||||||
|
if (j<err.size())
|
||||||
|
std::cout << " " << j << ": " << val[j] << " +- " << err[j] << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << " " << j << ": " << val[j] << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << "+++++" << std::endl;
|
||||||
|
}
|
||||||
|
}}
|
40
src/musredit_qt5/mupp/var/src/PStatement.cpp
Normal file
40
src/musredit_qt5/mupp/var/src/PStatement.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
PStatement.cpp
|
||||||
|
|
||||||
|
Author: Andreas Suter
|
||||||
|
e-mail: andreas.suter@psi.ch
|
||||||
|
|
||||||
|
Based on Joel de Guzman example on calc7,
|
||||||
|
see https://github.com/boostorg/spirit
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2020 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. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# pragma warning(disable: 4345)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "PStatementDef.hpp"
|
||||||
|
|
||||||
|
typedef std::string::const_iterator iterator_type;
|
||||||
|
template struct mupp::parser::PStatement<iterator_type>;
|
Loading…
x
Reference in New Issue
Block a user