milly/ref_parser/parser.y

123 lines
2.3 KiB
Plaintext

/* milly's Bison grammar */
%{
#include <stdio.h>
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
%right ':'
%start program
%%
program: decl
| decl program
/* Types syntax */
type: atomic_type
| type ARROW type
atomic_type: type_app
| PARAM_IDENT
| '(' type ')'
| '(' tuple_types ')'
type_app_atom: PARAM_IDENT
| '(' type ')'
| '(' tuple_types ')'
| IDENT
type_app: IDENT
| type_app_atom type_app
tuple_types: type ',' type
| type ',' tuple_types
/* 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 type ',' datatype_alts
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 ',' list_elems ')'
| '(' expr ')'
list_elems: %empty
| expr ',' list_elems
fun_app_expr: atomic_expr
| fun_app_expr atomic_expr
infix_expr: fun_app_expr
| infix_expr ':' infix_expr /* List cons */
/* TODO: | infix_expr IDENT infix_expr */
expr: infix_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 param_patterns '>'
| '(' pattern ',' pattern_list ')'
| '[' pattern_list ']'
pattern_list: %empty
| pattern ',' pattern_list
%%
void yyerror(const char *err) {
fprintf(stderr, "Error: %s", err);
}