Annex A The whole grammar (normative)
(1) This annex collects the syntax rules of the clauses in one place. The notation is that of ISO/IEC 14977: a b is sequence, a | b choice, [ a ] optional, { a } zero or more times, (* … *) a remark, ? … ? a rule stated in words. Names in capitals are the tokens of clause 6. Any number of spaces and remarks may stand between tokens, except right before a new name (6.3 (4)).
(2) The grammar is read with one token of lookahead. The exception is a parameter of a signature, where the token after it tells whether it is a name or a type. What a name refers to (a local, a global, a word) and the types on the stack are settled by the declarations and checks, not by the grammar.
(* 6: tokens *)
NAME = letter { letter | digit } ; (* not a reserved word *)
PATH = NAME "." member { "." member } ; (* member: a run of letters and digits *)
INT = [ "+" | "-" ] ( digits | "0x" hex-digits | "0b" bit-digits ) ;
DEC = [ "+" | "-" ] digits "." digits ; (* 7.5 *)
CHAR = [ "U" ] "'" ( char-byte | escape ) "'" ;
STRING = '"' { string-byte | escape } '"' ;
RAWSTRING = "r" '"' { raw-byte } '"' ;
TEXT = "text" TAG newline { text-line newline } TAG ;
BOOL = "true" | "false" ;
literal = INT | DEC | CHAR | STRING | RAWSTRING | TEXT | BOOL ;
(* 6.7, 13: a source *)
source = [ "pinax" INT ] { item } ;
item = import | search | forward | declaration | definition | row-item | assign-item | body ;
import = "use" NAME [ "as" NAME ] ;
search = "search" ( "(" [ NAME { "," NAME } ] ")" | "none" ) ; (* 13.5 *)
forward = "forward" ( "array" | "list" | "pool" ) NAME
| "forward" "word" NAME "(" effect ")" ;
(* 8: declarations *)
declaration = [ "export" ] ( [ "bound" ] bindable | "shared" shareable | decl ) ;
bindable = "global" NAME type | "array" NAME type capacity | "buffer" NAME capacity ;
shareable = bindable | "list" NAME type capacity | "index" NAME NAME PATH ;
decl = "const" NAME literal
| "err" NAME
| "list" NAME type capacity | "queue" NAME type capacity | "pool" NAME NAME capacity
| "record" NAME { field | "big_endian" } "end"
| "type" NAME ( "int" | "bool" | "str" | "dec" "(" INT ")" )
| "index" NAME NAME PATH
| "tasks" NAME capacity [ size [ size [ size ] ] ] [ "apart" ]
| "extern" c-name "(" effect ")" "from" STRING [ "as" NAME ]
| "test" NAME { body } "end" ;
capacity = size | "host" ;
size = INT | NAME ;
field = NAME NAME [ "(" size ")" ] ;
c-name = NAME | reserved-word | STRING ;
row-item = [ "export" ] "row" NAME [ NAME ] "(" value { "," value } ")" ;
assign-item = "assign" NAME "(" value { "," value } ")" ;
value = literal | NAME ;
(* 9: words *)
definition = [ "export" ] "word" NAME "(" effect ")" { body } "end" ;
effect = [ params ] [ "gives" params ] [ "or" "fail" ] ;
params = param { "," param } ;
param = [ NAME ] ( type | coll-type ) ;
type = [ "owned" ] ( NAME [ "(" size ")" ] | "word" "(" effect ")" ) ;
coll-type = ( "array" | "list" | "queue" ) NAME [ "(" size ")" ] | "buffer" ; (* an input, 9.9 *)
(* 9 to 11: the body *)
body = literal | NAME | PATH | store | set | fits | block | cat | guard | control | defer
| "," | "." (* the end of a statement, 10.8 *)
| "return" | "fail" | ( "while" | "until" | "break" ) [ "(" NAME ")" ] ;
store = "to" ( NAME | PATH | "(" NAME { "," NAME } ")" ) ; (* a local, or a field *)
set = "set" ( NAME | PATH ) ; (* a global, 9.4 *)
fits = "fits" ( NAME | PATH ) ; (* a str(N) place, 7.3 *)
block = "do" [ "(" effect ")" ] { body } "end" ;
cat = "cat" "(" phrase { "," phrase } ")" ;
phrase = body { body } ;
guard = "or_fail" | "or_return" | "or_else" [ "(" NAME ")" ] { body } "end" ;
control = "if" { body } [ "else" { body } ] "end"
| "loop" [ "(" NAME ")" ] { body } "end"
| "case" { branch } [ "otherwise" { body } "end" ] "end" ;
defer = "defer" { body } "end" ; (* 10.7 *)
branch = ( case-value | "(" case-value { "," case-value } ")" ) "of" { body } "end" ;
case-value = literal | NAME | PATH ;(3) A source read by data load follows data-source of 13.4.