10#include <Teuchos_MathExpr.hpp> 
   16Language make_language() {
 
   20  prods[PROD_PROGRAM](
"program") >> 
"statements", 
"expr?";
 
   21  prods[PROD_NO_STATEMENTS](
"statements");
 
   22  prods[PROD_NEXT_STATEMENT](
"statements") >> 
"statements", 
"statement", 
";", 
"S?";
 
   23  prods[PROD_ASSIGN](
"statement") >> 
"name", 
"S?", 
"=", 
"S?", 
"expr";
 
   24  prods[PROD_NO_EXPR](
"expr?");
 
   25  prods[PROD_YES_EXPR](
"expr?") >> 
"expr";
 
   26  prods[PROD_EXPR](
"expr") >> 
"ternary";
 
   27  prods[PROD_TERNARY_DECAY](
"ternary") >> 
"add_sub";
 
   28  prods[PROD_OR_DECAY](
"or") >> 
"and";
 
   29  prods[PROD_AND_DECAY](
"and") >> 
"comp";
 
   30  prods[PROD_ADD_SUB_DECAY](
"add_sub") >> 
"mul_div";
 
   31  prods[PROD_MUL_DIV_DECAY](
"mul_div") >> 
"neg";
 
   32  prods[PROD_NEG_DECAY](
"neg") >> 
"pow";
 
   33  prods[PROD_POW_DECAY](
"pow") >> 
"scalar";
 
   34  prods[PROD_TERNARY](
"ternary")
 
   35    >> 
"or", 
"?", 
"S?", 
"add_sub", 
":", 
"S?", 
"add_sub";
 
   36  prods[PROD_OR](
"or") >> 
"or", 
"||", 
"S?", 
"and";
 
   37  prods[PROD_AND](
"and") >> 
"and", 
"&&", 
"S?", 
"comp";
 
   38  prods[PROD_GT](
"comp") >> 
"add_sub", 
">", 
"S?", 
"add_sub";
 
   39  prods[PROD_LT](
"comp") >> 
"add_sub", 
"<", 
"S?", 
"add_sub";
 
   40  prods[PROD_GEQ](
"comp") >> 
"add_sub", 
">=", 
"S?", 
"add_sub";
 
   41  prods[PROD_LEQ](
"comp") >> 
"add_sub", 
"<=", 
"S?", 
"add_sub";
 
   42  prods[PROD_EQ](
"comp") >> 
"add_sub", 
"==", 
"S?", 
"add_sub";
 
   43  prods[PROD_BOOL_PARENS](
"comp") >> 
"(", 
"S?", 
"or", 
")", 
"S?";
 
   44  prods[PROD_ADD](
"add_sub") >> 
"add_sub", 
"+", 
"S?", 
"mul_div";
 
   45  prods[PROD_SUB](
"add_sub") >> 
"add_sub", 
"-", 
"S?", 
"mul_div";
 
   46  prods[PROD_MUL](
"mul_div") >> 
"mul_div", 
"*", 
"S?", 
"pow";
 
   47  prods[PROD_DIV](
"mul_div") >> 
"mul_div", 
"/", 
"S?", 
"pow";
 
   48  prods[PROD_POW](
"pow") >> 
"scalar", 
"^", 
"S?", 
"pow";
 
   49  prods[PROD_CALL](
"scalar")
 
   50    >> 
"name", 
"S?", 
"(", 
"S?", 
"args?", 
")", 
"S?";
 
   51  prods[PROD_NO_ARGS](
"args?");
 
   52  prods[PROD_SOME_ARGS](
"args?") >> 
"args";
 
   53  prods[PROD_FIRST_ARG](
"args") >> 
"ternary";
 
   54  prods[PROD_NEXT_ARG](
"args") >> 
"args", 
",", 
"S?", 
"ternary";
 
   55  prods[PROD_NEG](
"neg") >> 
"-", 
"S?", 
"neg";
 
   56  prods[PROD_VAL_PARENS](
"scalar") >> 
"(", 
"S?", 
"ternary", 
")", 
"S?";
 
   57  prods[PROD_CONST](
"scalar") >> 
"constant", 
"S?";
 
   58  prods[PROD_VAR](
"scalar") >> 
"name", 
"S?";
 
   59  prods[PROD_NO_SPACES](
"S?");
 
   60  prods[PROD_SPACES](
"S?") >> 
"spaces";
 
   61  out.tokens.resize(NTOKS);
 
   62  out.tokens[TOK_SPACE](
"spaces", 
"[ \t\n\r]+");
 
   63  out.tokens[TOK_NAME](
"name", 
"[_a-zA-Z][_a-zA-Z0-9]*");
 
   64  out.tokens[TOK_ADD](
"+", 
"\\+");
 
   65  out.tokens[TOK_SUB](
"-", 
"\\-");
 
   66  out.tokens[TOK_MUL](
"*", 
"\\*");
 
   67  out.tokens[TOK_DIV](
"/", 
"\\/");
 
   68  out.tokens[TOK_POW](
"^", 
"\\^");
 
   69  out.tokens[TOK_LPAREN](
"(", 
"\\(");
 
   70  out.tokens[TOK_RPAREN](
")", 
"\\)");
 
   71  out.tokens[TOK_COMMA](
",", 
",");
 
   72  out.tokens[TOK_CHECK](
"?", 
"\\?");
 
   73  out.tokens[TOK_CHOOSE](
":", 
":");
 
   74  out.tokens[TOK_GT](
">", 
">");
 
   75  out.tokens[TOK_LT](
"<", 
"<");
 
   76  out.tokens[TOK_GEQ](
">=", 
">=");
 
   77  out.tokens[TOK_LEQ](
"<=", 
"<=");
 
   78  out.tokens[TOK_EQ](
"==", 
"==");
 
   79  out.tokens[TOK_AND](
"&&", 
"&&");
 
   80  out.tokens[TOK_OR](
"||", 
"\\|\\|");
 
   81  out.tokens[TOK_CONST](
"constant",
 
   82      "(0|([1-9][0-9]*))(\\.[0-9]*)?([eE]\\-?[1-9][0-9]*)?");
 
   83  out.tokens[TOK_SEMICOLON](
";", 
";");
 
   84  out.tokens[TOK_ASSIGN](
"=", 
"=");
 
   90  if (ptr.strong_count() == 0) {
 
   91    ptr.
reset(
new Language(make_language()));
 
   98  if (ptr.strong_count() == 0) {
 
  105SymbolSetReader::SymbolSetReader():
 
  106  Reader(ask_reader_tables())
 
  110SymbolSetReader::~SymbolSetReader()
 
  114void SymbolSetReader::at_shift(any& result, 
int token, std::string& text) {
 
  115  if (token == TOK_NAME) result = text;
 
  118void SymbolSetReader::at_reduce(any& , 
int prod, std::vector<any>& rhs) {
 
  119  if (prod == PROD_VAR) {
 
  120    std::string& name = any_ref_cast<std::string>(rhs.at(0));
 
  121    variable_names.insert(name);
 
  122  } 
else if (prod == PROD_CALL) {
 
  123    std::string& name = any_ref_cast<std::string>(rhs.at(0));
 
  124    function_names.insert(name);
 
  128std::set<std::string> get_variables_used(std::string 
const& expr) {
 
  129  SymbolSetReader reader;
 
  131  reader.read_string(result, expr, 
"get_variables_used");
 
  132  return reader.variable_names;
 
  135std::set<std::string> get_symbols_used(std::string 
const& expr) {
 
  136  SymbolSetReader reader;
 
  138  reader.read_string(result, expr, 
"get_symbols_used");
 
  139  auto set = std::move(reader.variable_names);
 
  140  set.insert(reader.function_names.begin(), reader.function_names.end());
 
  144class CalcReader : 
public Reader {
 
  146  CalcReader():Reader(MathExpr::ask_reader_tables()) {
 
  147    unary_function_map[
"sqrt"] = &std::sqrt;
 
  148    unary_function_map[
"sin"] = &std::sin;
 
  149    unary_function_map[
"cos"] = &std::cos;
 
  150    unary_function_map[
"tan"] = &std::tan;
 
  151    unary_function_map[
"asin"] = &std::asin;
 
  152    unary_function_map[
"acos"] = &std::acos;
 
  153    unary_function_map[
"atan"] = &std::atan;
 
  154    unary_function_map[
"exp"] = &std::exp;
 
  155    unary_function_map[
"log"] = &std::log;
 
  156    unary_function_map[
"log10"] = &std::log10;
 
  157    binary_function_map[
"atan2"] = &std::atan2;
 
  159  virtual ~CalcReader() = 
default;
 
  166  virtual void at_shift(any& result_any, 
int token, std::string& text) {
 
  169      case MathExpr::TOK_NAME: {
 
  170        std::string& result = make_any_ref<std::string>(result_any);
 
  174      case MathExpr::TOK_CONST: {
 
  175        result_any = std::atof(text.c_str());
 
  180  virtual void at_reduce(any& result, 
int prod, std::vector<any>& rhs) {
 
  183      case MathExpr::PROD_PROGRAM: {
 
  185          "Calculator needs an expression to evaluate!");
 
  186        swap(result, rhs.at(1));
 
  189      case MathExpr::PROD_NO_STATEMENTS:
 
  190      case MathExpr::PROD_NO_EXPR:
 
  191      case MathExpr::PROD_NEXT_STATEMENT: {
 
  194      case MathExpr::PROD_ASSIGN: {
 
  195        std::string 
const& name = any_ref_cast<std::string>(rhs.at(0));
 
  196        double value = any_cast<double>(rhs.at(4));
 
  197        variable_map[name] = value;
 
  200      case MathExpr::PROD_YES_EXPR:
 
  201      case MathExpr::PROD_EXPR:
 
  202      case MathExpr::PROD_TERNARY_DECAY:
 
  203      case MathExpr::PROD_OR_DECAY:
 
  204      case MathExpr::PROD_AND_DECAY:
 
  205      case MathExpr::PROD_ADD_SUB_DECAY:
 
  206      case MathExpr::PROD_MUL_DIV_DECAY:
 
  207      case MathExpr::PROD_POW_DECAY:
 
  208      case MathExpr::PROD_NEG_DECAY:
 
  209      case MathExpr::PROD_SOME_ARGS:
 
  210        swap(result, rhs.at(0));
 
  212      case MathExpr::PROD_TERNARY:
 
  213        result = any_cast<bool>(rhs.at(0)) ?
 
  214                 any_cast<double>(rhs.at(3)) :
 
  215                 any_cast<double>(rhs.at(6));
 
  217      case MathExpr::PROD_OR:
 
  218        result = any_cast<bool>(rhs.at(0)) || any_cast<bool>(rhs.at(3));
 
  220      case MathExpr::PROD_AND:
 
  221        result = any_cast<bool>(rhs.at(0)) && any_cast<bool>(rhs.at(3));
 
  223      case MathExpr::PROD_GT:
 
  224        result = any_cast<double>(rhs.at(0)) > any_cast<double>(rhs.at(3));
 
  226      case MathExpr::PROD_LT:
 
  227        result = any_cast<double>(rhs.at(0)) < any_cast<double>(rhs.at(3));
 
  229      case MathExpr::PROD_GEQ:
 
  230        result = any_cast<double>(rhs.at(0)) >= any_cast<double>(rhs.at(3));
 
  232      case MathExpr::PROD_LEQ:
 
  233        result = any_cast<double>(rhs.at(0)) <= any_cast<double>(rhs.at(3));
 
  235      case MathExpr::PROD_EQ:
 
  236        result = any_cast<double>(rhs.at(0)) == any_cast<double>(rhs.at(3));
 
  238      case MathExpr::PROD_BOOL_PARENS:
 
  239        result = any_cast<bool>(rhs.at(2));
 
  241      case MathExpr::PROD_ADD:
 
  242        result = any_cast<double>(rhs.at(0)) + any_cast<double>(rhs.at(3));
 
  244      case MathExpr::PROD_SUB:
 
  245        result = any_cast<double>(rhs.at(0)) - any_cast<double>(rhs.at(3));
 
  247      case MathExpr::PROD_MUL:
 
  248        result = any_cast<double>(rhs.at(0)) * any_cast<double>(rhs.at(3));
 
  250      case MathExpr::PROD_DIV:
 
  251        result = any_cast<double>(rhs.at(0)) / any_cast<double>(rhs.at(3));
 
  253      case MathExpr::PROD_POW:
 
  254        result = std::pow(any_cast<double>(rhs.at(0)), any_cast<double>(rhs.at(3)));
 
  256      case MathExpr::PROD_CALL: {
 
  257        std::string& name = any_ref_cast<std::string>(rhs.at(0));
 
  258        CallArgs& args = any_ref_cast<CallArgs>(rhs.at(4));
 
  260            "Only unary and binary functions supported!\n");
 
  263              "Unknown unary function name \"" << name << 
"\"\n");
 
  264          Unary fptr = unary_function_map[name];
 
  265          result = (*fptr)(args.a0);
 
  268              "Unknown binary function name \"" << name << 
"\"\n");
 
  269          Binary fptr = binary_function_map[name];
 
  270          result = (*fptr)(args.a0, args.a1);
 
  274      case MathExpr::PROD_NO_ARGS: {
 
  275        CallArgs& args = make_any_ref<CallArgs>(result);
 
  279      case MathExpr::PROD_FIRST_ARG: {
 
  280        CallArgs& args = make_any_ref<CallArgs>(result);
 
  281        args.a0 = any_cast<double>(rhs.at(0));
 
  285      case MathExpr::PROD_NEXT_ARG: {
 
  286        CallArgs& args = any_ref_cast<CallArgs>(rhs.at(0));
 
  287        args.a1 = any_cast<double>(rhs.at(3));
 
  289        swap(result, rhs.at(0));
 
  292      case MathExpr::PROD_NEG:
 
  293        result = - any_cast<double>(rhs.at(2));
 
  295      case MathExpr::PROD_VAL_PARENS:
 
  296        result = any_cast<double>(rhs.at(2));
 
  298      case MathExpr::PROD_CONST:
 
  299        result = any_cast<double>(rhs.at(0));
 
  301      case MathExpr::PROD_VAR:
 
  302        std::string 
const& name = any_ref_cast<std::string>(rhs.at(0));
 
  303        auto it = variable_map.find(name);
 
  305            "variable " << name << 
" not defined!");
 
  306        double value = it->second;
 
  312  typedef double (*Unary)(double);
 
  313  typedef double (*Binary)(double, double);
 
  314  std::map<std::string, Unary> unary_function_map;
 
  315  std::map<std::string, Binary> binary_function_map;
 
  316  std::map<std::string, double> variable_map;
 
  319Reader* new_calc_reader() {
 
  320  return new CalcReader();
 
void reset()
Reset to null.
 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
 
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
 
RCP< const ReaderTables > ReaderTablesPtr
an RCP to a const ReaderTables
 
RCP< const Language > LanguagePtr
an RCP to a const Language
 
ReaderTablesPtr make_reader_tables(Language const &language)
constructs ReaderTables for the given Language.
 
Productions productions
vector of productions