This formal grammar describes expressions. Terminal symbols are in quotes, or described in text. Nonterminals are underlined.
Whenever an expression is required, PCC accepts a sequence. The only exception is the Bind elementary command, which takes or-exprs (because it has assignments := as part of its syntax).
sequence:
    assignment
    sequence ";" assignment
assignment:
    or-expr
    assignment ":=" or-expr
or-expr:
    and-expr
    or-expr "Or" and-expr
    or-expr "Xor" and-expr
and-expr:
    not-expr
    and-expr "And" not-expr
not-expr:
    comparison
    "Not" not-expr
comparison:
    concat-expr
    comparison "=" concat-expr
    comparison "<" concat-expr
    comparison ">" concat-expr
    comparison "<=" concat-expr
    comparison ">=" concat-expr
    comparison "<>" concat-expr
concat-expr:
    add-expr
    concat-expr "#" add-expr
    concat-expr "&" add-expr
add-expr:
    mult-expr
    add-expr "+" mult-expr
    add-expr "-" mult-expr
mult-expr:
    neg-expr
    mult-expr "*" neg-expr
    mult-expr "/" neg-expr
    mult-expr "\" neg-expr
    mult-expr "Mod" neg-expr
neg-expr:
    pow-expr
    "-" neg-expr
    "+" neg-expr
    "Not" neg-expr          % Note 1
pow-expr:
    primary-expr
    primary-expr "^" neg-expr
primary-expr:
    "(" sequence ")"
    string-literal
    integer-literal
    float-literal
    "True"                  % Note 2
    "False"                 % Note 2
    "Pi"                    % Note 3
    identifier invocation*
invocation:
    "(" arguments ")"
    "." identifier          % Note 4
    "->" identifier         % Note 4
arguments:
    nothing
    sequence ("," sequence)*
identifier:
    sequence of letters, "$", "_", digits, ".",
      not starting with a digit or period
      not ending with a period
string-literal:
    "'" (any character except for "'")* "'"
    """ (any character except for """ and "\",
         or "\" followed by any character) """
integer-literal:
    digit digit*
      A value is an integer if it fits into 32 bits.
      Otherwise, it's float.
float-literal:
    integer-literal
    digit digit* "."
    digit* "." digit digit*Notes:
- 1: Not a=b is always interpreted as a not-expr, binding as Not (a=b). This grammar rule just allows -Not a=b, which is interpreted as (-(Not a)) = b.
 - 2: these are the boolean literals
 - 3: this is a float literal
 - 4: . and -> have essentially the same meaning. However, because the dot can also be part of names, a.b is always interpreted as a single identifier. To access member b of object a, use a->b.
 



