The Rules
Expr::= ExprOR | ExprOR "," Expr | ExprOR Expr
ExprOR::= ExprAND | ExprAND "OR" ExprOR
ExprAND::= ExprCompare | ExprCompare "AND" ExprAND
ExprCompare::= ExprPlusMinus | ExprPlusMinus CompareOp ExprCompare
ExprPlusMinus::= ExprMultDiv | ExprMultDiv PlusMinusOp ExprPlusMinus
ExprMultDiv::= ExprNot | ExprNot MultDivOp ExprMultDiv
ExprNot::== ExprFundamental | "!" ExprFundamental
ExprFundamental::= Literal | "(" ExprInParens | FuncCall
ExprInParens::= ExprOR | ExprOR "," ExprInParens | ExprOR ExprInParens
FuncCall::== Func ParmList
ParmList::= ")" | ExprParm ")" | ExprParm "," ParmList | "," ParmList
ExprParm::= ExprOR | ExprOR ExprParm
CompareOp::= "<" | ">" | "=" | "<=" | ">=" | "==" 
PlusMinusOp::= "+" | "-"
MultDivOp::= "*" | "%"
Func::= Identifier "("
Literal::= QuotedLiteral | BareToken
QuotedLiteral::= SingleQuoted | DoubleQuoted
SingleQuoted::= SQuote SingleQuotedChars
DoubleQuoted::= DQuote DoubleQuotedChars
SQuote::= '
DQuote::= "
Escape::= \
SingleQuotedChars::= SQuote | PlainChar SingleQuotedChars| DQuote
SingleQuotedChars | EscapedChar SingleQuotedChars
DoubleQuotedChars::= DQuote | PlainChar DoubleQuotedChars| SQuote
DoubleQuotedChars | EscapedChar DoubleQuotedChars
PlainChar::= AnyChar except SQuote, DQuote, Escape
EscapedChar::= Escape AnyChar
BareToken::= Sequence of unquoted characters containing no recognized
special characters nor keywords

The iFL language has implicit concatenation of adjacent expressions, at top level, within parentheses and within a function parameter. Adjacent literals are concatenated at compile time to form a single value.

Spaces around operators are ignored. Spaces after comma are ignored. At top level and within parentheses, a comma is a literal comma, except it also ignores spaces to the right.

A parameter might be empty in a parameter list, it means empty literal "", e.g. fn(,a,,b,) is the same as fn("",a,"",b,"")

The escape character is an operator only within quoted literals, this is because unquoted Windows paths make use of the backslash as a component separator. For the same reason, there is no math division operator; standard path names use the forward slash as a component separator. Use _div() or _idiv() instead.

Functions are recognized even if the function identifier is immediately preceded with other characters, e.g. abcsreg(reg) is "abc" followed by sreg(reg). There is no space allowed between a function identifier and the open parenthesis.

The named operators AND and OR must be complete identifiers to be recognized unlike functions, e.g. (1<2)AND""2<3 is the AND operator, but 1<2AND2<3 is not. This is the exception to the automatic concatenation rule.

Function names and named operators are case-insensitive and follow the Java Identifier rules. All built-in functions start with an underscore by convention. A handful of legacy functions are also available without the underscore. No additional functions will be made available in this form.

Minus is always a binary operator, this is to disambiguate implicit concatenation. You can obtain unary minus by quoting it or writing 0-expr.

All binary operators are left-associative, A op B op C is ((A op B) op C). Comparison operators are also associative. For example, the expression "1 < 2 < 3" is the same as "true < 3" because clearly one is less than two. The binding is from left to right.

The following is the binding precedence from tightest to loosest:

  1. Explicit grouping: ()
  2. Multiplicative: *, % i.e. multiply, modulo
  3. Additive: +, -
  4. Comparison: <, >, =, <=, >=, ==
  5. Conjunction: AND
  6. Disjunction: OR
  7. Concatenation: implicit or ,

iWay Software