program: decl* ?decl: iface | node | func sep_trail{item, punc}: item (punc item)? punc? func: "fn" ident "(" ")" ("->" ty) "{" "}" iface: "iface" ident "{" sep_trail{iface_field, ","} "}" iface_field: ident ":" ident iface_ref: ident iface_refs: iface_ref* node: "node" ident ":" iface_refs "{" variants "}" variants: variant* variant: prod "=>" "{" equations "}" prod: sym* ?sym: sym_rename | sym_lit sym_lit: ESCAPED_STRING sym_rename: "<" ident ":" node_ref ">" ?node_ref: node_ref_name | node_regex node_ref_name: ident node_regex: ESCAPED_STRING equations: equation_semi* equation_semi: equation ";" // TODO: the left side should really be a separate type // called lvalue, and should NOT include literals equation: expr "=" expr // Expressions ?expr: expr2 | expr_add expr_add: expr "+" expr2 ?expr2: expr3 | expr_mul | expr_call expr_mul: expr2 "*" expr3 expr_call: expr2 "(" args ")" ?expr3: "(" expr ")" | expr_dot | expr_name expr_dot: expr3 "." ident expr_name: ident args: sep_trail{expr, ","} ty: ident ident: IDENT COMMENT: /\/\/[^\n]*/ IDENT: /([a-zA-Z][a-zA-Z0-9_]*)|(_[a-zA-Z0-9_]+)/ %import python.STRING %import common.WS %import common.ESCAPED_STRING %ignore WS %ignore COMMENT