-//
// The FLEET Assembly Language Grammar
// As specified in document 2005-ucies06
-//
// comments are included where the grammar had to go beyond the strict
// "letter of the law" in ies06
-//
// Note that this is the *entire, complete* formal specification of
// the grammar. An equivalent lex+yacc grammar and support code would
// be several times as long.
-//
-Comment !::= "//" ~[\n]* "\n"
+Comment = "//" ~[\n]* "\n"
| "/*" ~[\n]* "*/"
-ws ::= w**
-w ::= [\r\n ]
- | Comment
+w = [\r\n ]*
+ws = (w | Comment)* -> ~[\r\n ]
-Statement ::= Move ";"? /ws
- | "{" Statement* "}"
- | Port "RENAMES" Port "ENDRENAME" ";" /ws
+s = !ws Program !ws
+Program = CodeBag:: statements:(Statement +/ ws)
-Move ::= Source ^"->" Destination /ws
- | Destination ^":=" Source /ws
-
-Destination ::= Port +/ (ws "," ws)
-Source ::= Port
+Statement = Move !((ws ";")?)
| CodeBag
+ | ^"#define" Port Port /ws
-CodeBag ::= CodeBagName? "{" Statement* "}" ";"? /ws
-
-// Note: this deviates from ies06
-location ::= shipname ("." portname)?
-shipname ::= name index?
-portname ::= name index?
-name ::= [A-Za-z] [A-Za-z0-9\[\]\.]*
-index ::= "[" [0-9]+ "]"
- | [0-9]+
+Move = Source ^"->" Destination /ws
+ | Source ^"->*" Destination /ws
+ | Port ^":=" Source /ws
+Destination = Port +/ (!ws "," !ws)
+Source = Port
+ | CodeBag
-//
-// The syntax should be rather self-explanatory; here are some of the
-// grammatical operators you may not have seen before:
-//
-// ^ marks the "key" token; this is used only after parsing
-// / separated-by; all preceding elements are separated by the following element
-// +/ one-or-more-with-separator; for example, "a"+/"," matches "a,a,a"
-// */ zero-or-more-with-separator
-// & intersection; a&b matches a string only if a matches it and b matches it
-// &~ negated intersection; a&~b matches a string only if a matches it and b DOES NOT match it
-//
+CodeBag = CodeBag::
+ name:(name !ws ":" !ws)?
+ "{"
+ !ws statements:(Statement +/ ws) !ws
+ "}"
+ (!ws ";")?
+
+Port = Port:: shipname ("." portname)*
+shipname = ShipName:: name index?
+portname = PortName:: name index?
+name = [A-Za-z0-9\[\]\.]**
+index = "[" [0-9]+ "]"
+ | [0-9]+