/* milly's Bison grammar */ %{ #include int yylex(); void yyerror(const char *); %} %token IDENT %token PARAM_IDENT %token INT STRING %token TRUE FALSE %token CASE LET IN MATCH OF DEF DATATYPE ALIAS TYPECHECK %token ARROW /* Function constructor is right associative */ %right ARROW %start program %% program: decl | decl program /* Types syntax */ type: atomic_type | type ARROW type atomic_type: type_app | PARAM_IDENT | '(' type ')' | '(' type tuple_types ')' type_app_atom: PARAM_IDENT | '(' type ')' | '(' type tuple_types ')' | IDENT type_app: IDENT | type_app_atom type_app tuple_types: ',' type | tuple_types ',' type /* Declaration syntax */ decl: datatype_decl | alias_decl | typecheck_decl | value_decl | func_decl datatype_decl: DATATYPE def_type_params IDENT '{' datatype_alts '}' /* type parameters of a definition */ def_type_params: %empty | PARAM_IDENT def_type_params datatype_alts: %empty | IDENT OF type datatype_alts_cont | IDENT datatype_alts_cont datatype_alts_cont: %empty | ',' IDENT type datatype_alts_cont | ',' IDENT datatype_alts_cont alias_decl: ALIAS def_type_params IDENT '=' type typecheck_decl: TYPECHECK IDENT ':' type value_decl: DEF IDENT '=' expr func_decl: DEF IDENT param_patterns '=' expr fun_alts param_patterns: pattern | pattern param_patterns fun_alts: %empty | '|' IDENT param_patterns '=' expr fun_alts /* Expressions */ atomic_expr: IDENT | INT | TRUE | FALSE | STRING | '[' list_elems ']' | '(' expr ',' expr list_elems_cont ')' | '(' expr ')' list_elems: %empty | expr list_elems_cont list_elems_cont: %empty | ',' expr list_elems_cont fun_app_expr: atomic_expr | fun_app_expr atomic_expr expr: fun_app_expr | MATCH expr '{' case_alts '}' | LET let_decls IN expr case_alts: %empty | CASE pattern ARROW expr case_alts let_decls: decl | decl let_decls /* Pattern language */ pattern: IDENT | INT | TRUE | FALSE | STRING | '<' IDENT ctor_param_patterns '>' | '(' pattern ',' pattern pattern_list_cont ')' | '[' pattern_list ']' ctor_param_patterns: %empty | param_patterns pattern_list: %empty | pattern pattern_list_cont pattern_list_cont: %empty | ',' pattern pattern_list_cont %% void yyerror(const char *err) { fprintf(stderr, "Error: %s", err); }