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.