Operators

Operators are just another methods with priorities defined by the Grammar. OpenL has 2 major types of operators: unary and binary. In addition, there are other operator types used in special cases. Here is a complete list of OpenL operators used in org.openl.j Grammar - the one that is used by default in OpenL Tablets product.

When we say that OpenL has a modular structure, we not only refer to the fact that OpenL has configurable, high-level separate components like Parser and Binder, it as also, that each node type can have it's own NodeBinder. At the same time, we can assign the single NodeBinder to a group of operators, like we do in the case of the prefix op.binary.

NOTE: (op.binary.or '||' and op.binary.and '&&' have separate NodeBinders to provide short-circuiting for boolean operands). For all other binary operators OpenL uses a simple algorithm, based on the operator's node type name. For example, if the node type is 'op.binary.add', the algorithm looks for the method named 'add()' in the following order:

The found method is then being executed in the runtime. So, if you need to override binary operator t1 OP t2 (where t1, t2 are objects of classes T1, T2 ), you need to do the following steps:

  1. Check the Operators Table and find the operator's type name.
  2. The last part of the type name will give you the name of the method that you need to implement
  3. Now you have the following options for implementing operators:

Usually, if T1 and T2 are different, you need to define both OP(T1, T2) and OP(T2, T1), unless you can rely on autocast() operator or Binary Operators' Semantic Map. Autocast can help you skip implementation when you already have an operator implemented for the autocasted type. For example, if you have OP(T1, double), you don't have to implement OP(T1, int), because int is autocasted to double. You may incur some performance penalty by doing this though. Binary Operator Semantic Map is described next.