https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ExpressionBuilder.h
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#pragma once
11
12#include <vector>
13#include <ostream>
14#include <sstream>
15#include <iomanip>
16
17#include "MooseError.h"
18#include "libmesh/libmesh_common.h"
19
46{
47public:
49
50 // forward delcarations
51 class EBTerm;
52 class EBTermNode;
53 class EBFunction;
54 class EBSubstitutionRule;
55 typedef std::vector<EBTerm> EBTermList;
56 typedef std::vector<EBTermNode *> EBTermNodeList;
57 typedef std::vector<const EBSubstitutionRule *> EBSubstitutionRuleList;
58
61 {
62 public:
63 virtual ~EBTermNode() {}
64 virtual EBTermNode * clone() const = 0;
65
66 virtual std::string stringify() const = 0;
67 virtual unsigned int substitute(const EBSubstitutionRuleList & /*rule*/) { return 0; }
68 virtual int precedence() const = 0;
69 friend std::ostream & operator<<(std::ostream & os, const EBTermNode & node)
70 {
71 return os << node.stringify();
72 }
73 };
74
76 template <typename T>
77 class EBNumberNode : public EBTermNode
78 {
80
81 public:
82 EBNumberNode(T value) : _value(value) {}
83 virtual EBNumberNode<T> * clone() const { return new EBNumberNode(_value); }
84
85 virtual std::string stringify() const;
86 virtual int precedence() const { return 0; }
87 };
88
90 class EBSymbolNode : public EBTermNode
91 {
92 std::string _symbol;
93
94 public:
95 EBSymbolNode(std::string symbol) : _symbol(symbol) {}
96 virtual EBSymbolNode * clone() const { return new EBSymbolNode(_symbol); }
97
98 virtual std::string stringify() const;
99 virtual int precedence() const { return 0; }
100 };
101
107 {
108 unsigned long _id;
109
110 public:
111 EBTempIDNode(unsigned int id) : _id(id) {}
112 virtual EBTempIDNode * clone() const { return new EBTempIDNode(_id); }
113
114 virtual std::string stringify() const; // returns "[idnumber]"
115 virtual int precedence() const { return 0; }
116 };
117
120 {
121 public:
122 EBUnaryTermNode(EBTermNode * subnode) : _subnode(subnode) {}
123 virtual ~EBUnaryTermNode() { delete _subnode; };
124
125 virtual unsigned int substitute(const EBSubstitutionRuleList & rule);
126 const EBTermNode * getSubnode() const { return _subnode; }
127
128 protected:
130 };
131
134 {
135 public:
150
152 {
153 }
154 virtual EBUnaryFuncTermNode * clone() const
155 {
156 return new EBUnaryFuncTermNode(_subnode->clone(), _type);
157 };
158
159 virtual std::string stringify() const;
160 virtual int precedence() const { return 2; }
161 };
162
165 {
166 public:
168 {
172
173 EBUnaryOpTermNode(EBTermNode * subnode, NodeType type) : EBUnaryTermNode(subnode), _type(type)
174 {
175 }
176 virtual EBUnaryOpTermNode * clone() const
177 {
178 return new EBUnaryOpTermNode(_subnode->clone(), _type);
179 };
180
181 virtual std::string stringify() const;
182 virtual int precedence() const { return 3; }
183 };
184
187 {
188 public:
189 EBBinaryTermNode(EBTermNode * left, EBTermNode * right) : _left(left), _right(right) {}
191 {
192 delete _left;
193 delete _right;
194 };
195
196 virtual unsigned int substitute(const EBSubstitutionRuleList & rule);
197
198 protected:
201 };
202
205 {
206 public:
222
224 : EBBinaryTermNode(left, right), _type(type)
225 {
226 }
227 virtual EBBinaryOpTermNode * clone() const
228 {
229 return new EBBinaryOpTermNode(_left->clone(), _right->clone(), _type);
230 };
231
232 virtual std::string stringify() const;
233 virtual int precedence() const;
234
235 protected:
237 };
238
241 {
242 public:
251
253 : EBBinaryTermNode(left, right), _type(type)
254 {
255 }
256 virtual EBBinaryFuncTermNode * clone() const
257 {
258 return new EBBinaryFuncTermNode(_left->clone(), _right->clone(), _type);
259 };
260
261 virtual std::string stringify() const;
262 virtual int precedence() const { return 2; }
263 };
264
267 {
268 public:
270 : EBBinaryTermNode(left, right), _middle(middle)
271 {
272 }
273 virtual ~EBTernaryTermNode() { delete _middle; };
274
275 virtual unsigned int substitute(const EBSubstitutionRuleList & rule);
276
277 protected:
279 };
280
283 {
284 public:
286 {
289
291 : EBTernaryTermNode(left, middle, right), _type(type)
292 {
293 }
294 virtual EBTernaryFuncTermNode * clone() const
295 {
297 };
298
299 virtual std::string stringify() const;
300 virtual int precedence() const { return 2; }
301 };
302
307 {
308 public:
309 virtual EBTermNode * apply(const EBTermNode *) const = 0;
311 };
312
316 template <class Node_T>
318 {
319 public:
320 virtual EBTermNode * apply(const EBTermNode *) const;
321
322 protected:
323 // on successful substitution this returns a new node to replace the old one, otherwise it
324 // returns NULL
325 virtual EBTermNode * substitute(const Node_T &) const = 0;
326 };
327
332 class EBTermSubstitution : public EBSubstitutionRuleTyped<EBSymbolNode>
333 {
334 public:
335 EBTermSubstitution(const EBTerm & find, const EBTerm & replace);
336 virtual ~EBTermSubstitution() { delete _replace; }
337
338 protected:
339 virtual EBTermNode * substitute(const EBSymbolNode &) const;
340 std::string _find;
342 };
343
348 class EBLogPlogSubstitution : public EBSubstitutionRuleTyped<EBUnaryFuncTermNode>
349 {
350 public:
351 EBLogPlogSubstitution(const EBTerm & epsilon) : _epsilon(epsilon.cloneRoot())
352 {
353 mooseAssert(_epsilon != NULL, "Epsilon must not be an empty term in EBLogPlogSubstitution");
354 }
355 virtual ~EBLogPlogSubstitution() { delete _epsilon; }
356
357 protected:
358 virtual EBTermNode * substitute(const EBUnaryFuncTermNode &) const;
360 };
361
368 class EBTerm
369 {
370 public:
371 // the default constructor assigns a temporary id node to root we use the address of the
372 // current EBTerm object as the ID. This could be problematic if we create and destroy terms,
373 // but then we should not expect the substitution to do sane things anyways.
374 __attribute__((noinline)) EBTerm()
375 : _root(new EBTempIDNode(reinterpret_cast<unsigned long long>(this)))
376 {
377 }
378
379 EBTerm(const EBTerm & term) : _root(term.cloneRoot()) {}
380 ~EBTerm() { delete _root; };
381
382 private:
383 // construct a term from a node
384 EBTerm(EBTermNode * root) : _root(root) {}
385
386 public:
387 // construct from number or string
388 EBTerm(int number) : _root(new EBNumberNode<int>(number)) {}
389 EBTerm(Real number) : _root(new EBNumberNode<Real>(number)) {}
390 EBTerm(const char * symbol) : _root(new EBSymbolNode(symbol)) {}
391
392 // concatenate terms to form a parameter list with (()) syntax (those need to be out-of-class!)
394 const ExpressionBuilder::EBTerm & rarg);
396 const ExpressionBuilder::EBTermList & rargs);
398 const ExpressionBuilder::EBTerm & rarg);
399
400 // dump term as FParser expression
401 friend std::ostream & operator<<(std::ostream & os, const EBTerm & term);
402 // cast into a string
403 operator std::string() const { return _root->stringify(); }
404
405 // assign a term
406 EBTerm & operator=(const EBTerm & term)
407 {
408 delete _root;
409 _root = term.cloneRoot();
410 return *this;
411 }
412
413 // perform a substitution (returns substituton count)
414 unsigned int substitute(const EBSubstitutionRule & rule);
415 unsigned int substitute(const EBSubstitutionRuleList & rules);
416
417 const EBTermNode * getRoot() const { return _root; }
418 EBTermNode * cloneRoot() const { return _root == NULL ? NULL : _root->clone(); }
419
420 protected:
422
423 public:
427#define UNARY_OP_IMPLEMENT(op, OP) \
428 EBTerm operator op() const \
429 { \
430 mooseAssert(_root != NULL, "Empty term provided for unary operator " #op); \
431 return EBTerm(new EBUnaryOpTermNode(cloneRoot(), EBUnaryOpTermNode::OP)); \
432 }
434 UNARY_OP_IMPLEMENT(!, LOGICNOT)
435
436
439 friend EBTerm sin(const EBTerm &);
440 friend EBTerm cos(const EBTerm &);
441 friend EBTerm tan(const EBTerm &);
442 friend EBTerm abs(const EBTerm &);
443 friend EBTerm log(const EBTerm &);
444 friend EBTerm log2(const EBTerm &);
445 friend EBTerm log10(const EBTerm &);
446 friend EBTerm exp(const EBTerm &);
447 friend EBTerm sinh(const EBTerm &);
448 friend EBTerm cosh(const EBTerm &);
449 friend EBTerm tanh(const EBTerm &);
450
451/*
452 * Binary operators (including number,term operations)
453 */
454#define BINARY_OP_IMPLEMENT(op, OP) \
455 EBTerm operator op(const EBTerm & term) const \
456 { \
457 mooseAssert(_root != NULL, "Empty term provided on left side of operator " #op); \
458 mooseAssert(term._root != NULL, "Empty term provided on right side of operator " #op); \
459 return EBTerm(new EBBinaryOpTermNode(cloneRoot(), term.cloneRoot(), EBBinaryOpTermNode::OP)); \
460 } \
461 friend EBTerm operator op(int left, const EBTerm & right) \
462 { \
463 mooseAssert(right._root != NULL, "Empty term provided on right side of operator " #op); \
464 return EBTerm(new EBBinaryOpTermNode( \
465 new EBNumberNode<int>(left), right.cloneRoot(), EBBinaryOpTermNode::OP)); \
466 } \
467 friend EBTerm operator op(Real left, const EBTerm & right) \
468 { \
469 mooseAssert(right._root != NULL, "Empty term provided on right side of operator " #op); \
470 return EBTerm(new EBBinaryOpTermNode( \
471 new EBNumberNode<Real>(left), right.cloneRoot(), EBBinaryOpTermNode::OP)); \
472 } \
473 friend EBTerm operator op(const EBFunction & left, const EBTerm & right) \
474 { \
475 mooseAssert(EBTerm(left)._root != NULL, "Empty term provided on left side of operator " #op); \
476 mooseAssert(right._root != NULL, "Empty term provided on right side of operator " #op); \
477 return EBTerm(new EBBinaryOpTermNode( \
478 EBTerm(left).cloneRoot(), right.cloneRoot(), EBBinaryOpTermNode::OP)); \
479 } \
480 friend EBTerm operator op(const EBFunction & left, const EBFunction & right); \
481 friend EBTerm operator op(int left, const EBFunction & right); \
482 friend EBTerm operator op(Real left, const EBFunction & right);
484 BINARY_OP_IMPLEMENT(-, SUB)
485 BINARY_OP_IMPLEMENT(*, MUL)
487 BINARY_OP_IMPLEMENT(%, MOD)
489 BINARY_OP_IMPLEMENT(>, GREATER)
491 BINARY_OP_IMPLEMENT(>=, GREATEREQ)
493 BINARY_OP_IMPLEMENT(!=, NOTEQ)
494
495/*
496 * Compound assignment operators
497 */
498#define BINARYCOMP_OP_IMPLEMENT(op, OP) \
499 EBTerm & operator op(const EBTerm & term) \
500 { \
501 mooseAssert(_root != NULL, "Empty term provided on left side of operator " #op); \
502 mooseAssert(term._root != NULL, "Empty term provided on right side of operator " #op); \
503 if (dynamic_cast<EBTempIDNode *>(_root)) \
504 mooseError("Using compound assignment operator on anonymous term. Set it to 0 first!"); \
505 _root = new EBBinaryOpTermNode(_root, term.cloneRoot(), EBBinaryOpTermNode::OP); \
506 return *this; \
507 }
513
518 friend EBTerm min(const EBTerm &, const EBTerm &);
519 friend EBTerm max(const EBTerm &, const EBTerm &);
520 friend EBTerm pow(const EBTerm &, const EBTerm &);
521 template <typename T>
522 friend EBTerm pow(const EBTerm &, T exponent);
523 friend EBTerm atan2(const EBTerm &, const EBTerm &);
524 friend EBTerm hypot(const EBTerm &, const EBTerm &);
525 friend EBTerm plog(const EBTerm &, const EBTerm &);
527
531 friend EBTerm conditional(const EBTerm &, const EBTerm &, const EBTerm &);
532 };
533
536 {
537 public:
539
543 EBFunction & operator()(const EBTerm & arg);
544 EBFunction & operator()(const EBTermList & args);
546
549 EBFunction & operator()(const EBTerm & a1, const EBTerm & a2) { return (*this)((a1, a2)); }
550 EBFunction & operator()(const EBTerm & a1, const EBTerm & a2, const EBTerm & a3)
551 {
552 return (*this)((a1, a2, a3));
553 }
554 EBFunction &
555 operator()(const EBTerm & a1, const EBTerm & a2, const EBTerm & a3, const EBTerm & a4)
556 {
557 return (*this)((a1, a2, a3, a4));
558 }
560 const EBTerm & a2,
561 const EBTerm & a3,
562 const EBTerm & a4,
563 const EBTerm & a5)
564 {
565 return (*this)((a1, a2, a3, a4, a5));
566 }
568 const EBTerm & a2,
569 const EBTerm & a3,
570 const EBTerm & a4,
571 const EBTerm & a5,
572 const EBTerm & a6)
573 {
574 return (*this)((a1, a2, a3, a4, a5, a6));
575 }
577 const EBTerm & a2,
578 const EBTerm & a3,
579 const EBTerm & a4,
580 const EBTerm & a5,
581 const EBTerm & a6,
582 const EBTerm & a7)
583 {
584 return (*this)((a1, a2, a3, a4, a5, a6, a7));
585 }
587 const EBTerm & a2,
588 const EBTerm & a3,
589 const EBTerm & a4,
590 const EBTerm & a5,
591 const EBTerm & a6,
592 const EBTerm & a7,
593 const EBTerm & a8)
594 {
595 return (*this)((a1, a2, a3, a4, a5, a6, a7, a8));
596 }
598 const EBTerm & a2,
599 const EBTerm & a3,
600 const EBTerm & a4,
601 const EBTerm & a5,
602 const EBTerm & a6,
603 const EBTerm & a7,
604 const EBTerm & a8,
605 const EBTerm & a9)
606 {
607 return (*this)((a1, a2, a3, a4, a5, a6, a7, a8, a9));
608 }
610
612 operator EBTerm() const;
613
615 operator std::string() const;
616
619 EBFunction & operator=(const EBTerm &);
622
624 std::string args();
625
628 EBTerm operator-() { return -EBTerm(*this); }
629 EBTerm operator!() { return !EBTerm(*this); }
631
632 // perform a substitution (returns substituton count)
633 unsigned int substitute(const EBSubstitutionRule & rule);
634 unsigned int substitute(const EBSubstitutionRuleList & rules);
635
636 protected:
641
642 // underlying term that the _eval_arguments are substituted in
644 };
645
646/*
647 * Binary operators
648 */
649#define BINARYFUNC_OP_IMPLEMENT(op, OP) \
650 friend EBTerm operator op(const EBFunction & left, const EBFunction & right) \
651 { \
652 mooseAssert(EBTerm(left)._root != NULL, "Empty term provided on left side of operator " #op); \
653 mooseAssert(EBTerm(right)._root != NULL, \
654 "Empty term provided on right side of operator " #op); \
655 return EBTerm(new EBBinaryOpTermNode( \
656 EBTerm(left).cloneRoot(), EBTerm(right).cloneRoot(), EBBinaryOpTermNode::OP)); \
657 } \
658 friend EBTerm operator op(int left, const EBFunction & right) \
659 { \
660 mooseAssert(EBTerm(right)._root != NULL, \
661 "Empty term provided on right side of operator " #op); \
662 return EBTerm(new EBBinaryOpTermNode( \
663 new EBNumberNode<int>(left), EBTerm(right).cloneRoot(), EBBinaryOpTermNode::OP)); \
664 } \
665 friend EBTerm operator op(Real left, const EBFunction & right) \
666 { \
667 mooseAssert(EBTerm(right)._root != NULL, \
668 "Empty term provided on right side of operator " #op); \
669 return EBTerm(new EBBinaryOpTermNode( \
670 new EBNumberNode<Real>(left), EBTerm(right).cloneRoot(), EBBinaryOpTermNode::OP)); \
671 }
678 BINARYFUNC_OP_IMPLEMENT(>, GREATER)
680 BINARYFUNC_OP_IMPLEMENT(>=, GREATEREQ)
682 BINARYFUNC_OP_IMPLEMENT(!=, NOTEQ)
683};
684
685// convenience function for numeric exponent
686template <typename T>
695
696// convert a number node into a string
697template <typename T>
698std::string
700{
701 std::ostringstream s;
702 s << std::setprecision(12) << _value;
703 return s.str();
704}
705
706template <class Node_T>
709 const ExpressionBuilder::EBTermNode * node) const
710{
711 const Node_T * match_node = dynamic_cast<const Node_T *>(node);
712 if (match_node == NULL)
713 return NULL;
714 else
715 return substitute(*match_node);
716}
const double T
void ErrorVector unsigned int
Node representing a function with two arguments.
enum ExpressionBuilder::EBBinaryFuncTermNode::NodeType _type
virtual std::string stringify() const
EBBinaryFuncTermNode(EBTermNode *left, EBTermNode *right, NodeType type)
virtual EBBinaryFuncTermNode * clone() const
Node representing a binary operator.
EBBinaryOpTermNode(EBTermNode *left, EBTermNode *right, NodeType type)
virtual EBBinaryOpTermNode * clone() const
virtual std::string stringify() const
Base class for nodes with two sub nodes (i.e. functions or operators taking two arguments)
virtual unsigned int substitute(const EBSubstitutionRuleList &rule)
EBBinaryTermNode(EBTermNode *left, EBTermNode *right)
User facing host object for a function. This combines a term with an argument list.
EBFunction & operator()(const EBTerm &a1, const EBTerm &a2)
EBFunction & operator()(const EBTerm &a1, const EBTerm &a2, const EBTerm &a3, const EBTerm &a4, const EBTerm &a5, const EBTerm &a6, const EBTerm &a7, const EBTerm &a8, const EBTerm &a9)
EBFunction & operator()(const EBTerm &a1, const EBTerm &a2, const EBTerm &a3, const EBTerm &a4, const EBTerm &a5, const EBTerm &a6, const EBTerm &a7, const EBTerm &a8)
EBFunction & operator()(const EBTerm &a1, const EBTerm &a2, const EBTerm &a3, const EBTerm &a4, const EBTerm &a5, const EBTerm &a6)
EBFunction & operator()(const EBTerm &a1, const EBTerm &a2, const EBTerm &a3, const EBTerm &a4)
EBTermList _eval_arguments
argument list passed in when evaluating the function
EBTermList _arguments
argument list the function is declared with
EBFunction & operator()(const EBTerm &a1, const EBTerm &a2, const EBTerm &a3, const EBTerm &a4, const EBTerm &a5)
EBFunction & operator()(const EBTerm &a1, const EBTerm &a2, const EBTerm &a3, const EBTerm &a4, const EBTerm &a5, const EBTerm &a6, const EBTerm &a7)
EBFunction & operator()(const EBTerm &a1, const EBTerm &a2, const EBTerm &a3)
Substitution rule to replace all occurences of log(x) with plog(x, epsilon) with a user defined term ...
virtual EBTermNode * substitute(const EBUnaryFuncTermNode &) const
Template class for leaf nodes holding numbers in the expression tree.
virtual EBNumberNode< T > * clone() const
virtual std::string stringify() const
Substitution rule base class that applies to nodes of type Node_T.
virtual EBTermNode * substitute(const Node_T &) const =0
virtual EBTermNode * apply(const EBTermNode *) const
Substitution rule functor base class to perform flexible term substitutions.
virtual EBTermNode * apply(const EBTermNode *) const =0
Template class for leaf nodes holding symbols (i.e. variables) in the expression tree.
virtual EBSymbolNode * clone() const
virtual std::string stringify() const
Template class for leaf nodes holding anonymous IDs in the expression tree.
virtual EBTempIDNode * clone() const
virtual std::string stringify() const
Base class for nodes in the expression tree.
virtual int precedence() const =0
friend std::ostream & operator<<(std::ostream &os, const EBTermNode &node)
virtual std::string stringify() const =0
virtual EBTermNode * clone() const =0
virtual unsigned int substitute(const EBSubstitutionRuleList &)
Generic Substitution rule to replace all occurences of a given symbol node term with a user defined t...
virtual EBTermNode * substitute(const EBSymbolNode &) const
User facing host object for an expression tree.
__attribute__((noinline)) EBTerm()
unsigned int substitute(const EBSubstitutionRule &rule)
friend EBTerm sinh(const EBTerm &)
friend EBTerm atan2(const EBTerm &, const EBTerm &)
friend EBTerm pow(const EBTerm &, const EBTerm &)
friend EBTerm plog(const EBTerm &, const EBTerm &)
LOGICNOT friend EBTerm sin(const EBTerm &)
Unary functions.
BINARY_OP_IMPLEMENT(+, ADD) BINARY_OP_IMPLEMENT(-
friend EBTerm log2(const EBTerm &)
SUB BINARY_OP_IMPLEMENT MUL MOD BINARY_OP_IMPLEMENT(<, LESS) BINARY_OP_IMPLEMENT(>
friend EBTerm log10(const EBTerm &)
friend EBTerm cosh(const EBTerm &)
friend EBTerm abs(const EBTerm &)
friend EBTermList operator,(const ExpressionBuilder::EBTerm &larg, const ExpressionBuilder::EBTerm &rarg)
friend EBTerm tanh(const EBTerm &)
const EBTermNode * getRoot() const
EBTerm & operator=(const EBTerm &term)
BINARYCOMP_OP_IMPLEMENT(+=, ADD) BINARYCOMP_OP_IMPLEMENT(-
friend EBTerm hypot(const EBTerm &, const EBTerm &)
friend std::ostream & operator<<(std::ostream &os, const EBTerm &term)
friend EBTerm exp(const EBTerm &)
friend EBTerm log(const EBTerm &)
friend EBTerm tan(const EBTerm &)
EBTermNode * cloneRoot() const
friend EBTerm cos(const EBTerm &)
SUB BINARYCOMP_OP_IMPLEMENT MUL MOD friend EBTerm min(const EBTerm &, const EBTerm &)
Binary functions.
friend EBTerm max(const EBTerm &, const EBTerm &)
friend EBTerm conditional(const EBTerm &, const EBTerm &, const EBTerm &)
Ternary functions.
UNARY_OP_IMPLEMENT(-, NEG) UNARY_OP_IMPLEMENT(!
Node representing a function with three arguments.
virtual EBTernaryFuncTermNode * clone() const
EBTernaryFuncTermNode(EBTermNode *left, EBTermNode *middle, EBTermNode *right, NodeType type)
enum ExpressionBuilder::EBTernaryFuncTermNode::NodeType _type
Base class for nodes with two sub nodes (i.e. functions or operators taking two arguments)
virtual unsigned int substitute(const EBSubstitutionRuleList &rule)
EBTernaryTermNode(EBTermNode *left, EBTermNode *middle, EBTermNode *right)
Node representing a function with two arguments.
virtual std::string stringify() const
enum ExpressionBuilder::EBUnaryFuncTermNode::NodeType _type
virtual EBUnaryFuncTermNode * clone() const
EBUnaryFuncTermNode(EBTermNode *subnode, NodeType type)
Node representing a unary operator.
enum ExpressionBuilder::EBUnaryOpTermNode::NodeType _type
EBUnaryOpTermNode(EBTermNode *subnode, NodeType type)
virtual std::string stringify() const
virtual EBUnaryOpTermNode * clone() const
Base class for nodes with a single sub node (i.e. functions or operators taking one argument)
const EBTermNode * getSubnode() const
virtual unsigned int substitute(const EBSubstitutionRuleList &rule)
ExpressionBuilder adds an interface to derived classes that enables convenient construction of FParse...
std::vector< const EBSubstitutionRule * > EBSubstitutionRuleList
SUB BINARYFUNC_OP_IMPLEMENT MUL MOD BINARYFUNC_OP_IMPLEMENT(<, LESS) BINARYFUNC_OP_IMPLEMENT(>
std::vector< EBTermNode * > EBTermNodeList
BINARYFUNC_OP_IMPLEMENT(+, ADD) BINARYFUNC_OP_IMPLEMENT(-
std::vector< EBTerm > EBTermList