// 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 ]
-Program = Statement+ /ws
+s = ws! Program ws!
+Program = Program::
+ (Directive ws!)*
+ CodeBagBody
-Statement = Move ";"? /ws
- | "{" Statement* "}"
- | Port "RENAMES" Port "ENDRENAME" ";" /ws
-// | "#define" Port Port /ws
+Directive = Memory:: "#memory" "{" (int +/ (ws! "," ws!)) "}" /ws
+ | Import:: "#import" [A-Za-z_.]++ /ws
+ | Ship:: "#ship" shipname ":" [A-Za-z_\.]++ /ws
-Move = Source ^"->" Destination /ws
- | Source ^"=>" Destination /ws
- | Destination ^":=" Source /ws
-Destination = Port +/ (ws "," ws)
-Source = Port
+Statement = Move ((ws ";")?)!
| CodeBag
+// | ^"#define" Port Port /ws
-CodeBag = CodeBagName? "{" Statement* "}" ";"? /ws
+Move = Source ^"->" Destination /ws
+ | Source ^"->*" Destination /ws
+ | Port ^":=" Source /ws
-// Note: this deviates from ies06
-Port = shipname ("." portname)*
-shipname = name index?
-portname = name index?
-name = [A-Za-z] [A-Za-z0-9\[\]\.]*
+Destination = Port +/ (ws! "," ws!)
+Source = Port
+ | CodeBag
+CodeBagBody = CodeBag:: (Statement +/ ws)
+CodeBag = NamedCodeBag::
+ name:(name ws! ":" ws!)?
+ "{"
+ ws! statements:(Statement +/ ws) ws!
+ "}"
+ (ws! ";")?!
+
+//Port = Port:: shipname ("." portname)*
+Port = Port:: shipname "." portname
+ | Port:: shipname
+shipname = ShipName:: name (index?)
+portname = PortName:: name (index?)
+name = [A-Za-z0-9\[\]]**
index = "[" [0-9]+ "]"
| [0-9]+
+int = [0-9]++
-
-//
-// 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
-//