2. Grammar

Synod is parsed in two stages:

  1. Structure. The grammar below turns a file into lines, blocks and sentences. It knows nothing about meaning.
  2. Resolution. Each sentence is matched against the language forms and the phrases in scope: the package's own phrases and the exported phrases of imported packages (see spec/03).

2.1 Structure grammar

Taught in 10. Faults

file         = { line } ;
line         = sentence [ block { continuation } ] NEWLINE ;
block        = NEWLINE INDENT line { line } DEDENT ;
continuation = word block ;                  (* a continuation line, see below *)
sentence     = items { "," items } ;
items        = item { item } ;
item         = word | member | value | hole | "(" sentence ")" | list ;
hole         = "[" word ":" type "]" ;      (* in define patterns and in when *)
type         = word | word "." word
             | "list" "of" type
             | "map" "of" type "to" type ;
value        = number | duration | text | color | "true" | "false" ;
list         = "{" [ item { "," item } ] "}" ;

2.2 Language word grammar

Taught in 6. Decisions

Every language word belongs to a built-in form. Its exact shape, using arg for "one item that is not a hole":

arg        = item ;

(* files and entries *)
import     = "use" path [ "as" word ] ;
definition = "define" pattern ( block | "native" text ) ;
pattern    = [ hole ] head { word | hole } ;     (* first hole: the receiver; rules in spec/03 *)
head       = word ;                              (* never a reserved word *)
main       = "define" "main" block ;
start      = "define" hole "start" block ;       (* hole: the receiver [n: Node] *)

(* state and records *)
typedecl   = word "has" block ;                  (* block holds only "set" word "to" arg lines *)
assignment = "set" place "to" arg ;
place      = word | member | "item" arg "of" ( word | member ) ;

(* events *)
handler    = "when" [ hole ] arg block ;         (* the receiver: present exactly on node events *)
delay      = "after" arg block ;
delivery   = "deliver" arg "to" arg ;
emission   = "emit" arg "by" arg ;               (* the one form of emit; spec/05 *)

(* control *)
choice     = "if" arg block [ "else" block ] ;   (* else is a continuation line *)
loop       = "each" word [ "," word ] "in" arg block ;
return     = "result" arg ;

(* checking *)
invariant  = "always" arg ;

(* visual *)
drawing    = "draw" arg "as" word [ "for" arg ] [ block ] ;
attachment = word "of" arg ;                     (* look context: a shape attached with draw … for *)

(* values *)
record     = "message" ( word | word "." word ) "with" setting { "," setting } ;
setting    = word arg ;
element    = "item" arg "of" arg ;
compare    = arg ( "is" | "is not" | "is in" | "is not in"
                 | "less than" | "more than" | "at least" | "at most" ) arg ;
logic      = arg ( "and" | "or" ) arg | "not" arg ;
arithmetic = arg ( "plus" | "minus" | "times" | "divided by" ) arg ;

2.3 Consequences of the grammar

Taught in 2. Values, 6. Decisions