token whitespace = /[ \n\t]+/ [ skip ]; token upper_identifier = /[A-Z_][a-z_A-Z0-9]*/; token lower_identifier = /[a-z_][a-z_A-Z0-9]*/; token kw_data = /data/; token kw_type = /type/; token kw_defn = /defn/; token tkn_ocurly = /{/; token tkn_ccurly = /}/; token tkn_oparen = /\(/; token tkn_cparen = /\)/; token tkn_eq = /=/; token tkn_comma = /,/; rule S = program; rule program = definition program? ; rule definition = kw_data upper_identifier tkn_eq data_body | kw_type upper_identifier tkn_eq type_body | kw_defn lower_identifier params? tkn_eq defn_body ; rule data_body = tkn_ocurly data_elems tkn_ccurly ; rule data_elems = data_elem | data_elem tkn_comma data_elems ; rule data_elem = upper_identifier | upper_identifier tkn_oparen data_elem_types tkn_cparen ; rule data_elem_types = type | type tkn_comma data_elem_types ; rule type_body = tkn_ocurly type tkn_ccurly ; rule params = lower_identifier params? ; rule defn_body = tkn_ocurly expr tkn_ccurly ; rule expr = lower_identifier ; rule type = upper_identifier ;