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.



