%code requires { #include #include #include "ast.hpp" #include "definition.hpp" #include "parser.hpp" #include "parsed_type.hpp" class parse_driver; using yyscan_t = void*; } %param { yyscan_t scanner } %param { parse_driver& drv } %code { #include "parse_driver.hpp" } %token BACKSLASH %token PLUS %token TIMES %token MINUS %token DIVIDE %token INT %token DEFN %token DATA %token CASE %token OF %token LET %token IN %token OCURLY %token CCURLY %token OPAREN %token CPAREN %token COMMA %token ARROW %token EQUAL %token LID %token UID %language "c++" %define api.value.type variant %define api.token.constructor %locations %type > lowercaseParams %type > branches %type > constructors %type > typeList %type definitions %type type nonArrowType typeListElement %type aAdd aMul case let lambda app appBase %type data %type defn %type branch %type pattern %type constructor %start program %% program : definitions { $1.vis = visibility::global; std::swap(drv.get_global_defs(), $1); } ; definitions : definitions defn { $$ = std::move($1); auto name = $2->name; $$.defs_defn[name] = std::move($2); } | definitions data { $$ = std::move($1); auto name = $2->name; $$.defs_data[name] = std::move($2); } | %empty { $$ = definition_group(); } ; defn : DEFN LID lowercaseParams EQUAL OCURLY aAdd CCURLY { $$ = definition_defn_ptr( new definition_defn(std::move($2), std::move($3), std::move($6), @$)); } ; lowercaseParams : %empty { $$ = std::vector(); } | lowercaseParams LID { $$ = std::move($1); $$.push_back(std::move($2)); } ; aAdd : aAdd PLUS aMul { $$ = ast_ptr(new ast_binop(PLUS, std::move($1), std::move($3), @$)); } | aAdd MINUS aMul { $$ = ast_ptr(new ast_binop(MINUS, std::move($1), std::move($3), @$)); } | aMul { $$ = std::move($1); } ; aMul : aMul TIMES app { $$ = ast_ptr(new ast_binop(TIMES, std::move($1), std::move($3), @$)); } | aMul DIVIDE app { $$ = ast_ptr(new ast_binop(DIVIDE, std::move($1), std::move($3), @$)); } | app { $$ = std::move($1); } ; app : app appBase { $$ = ast_ptr(new ast_app(std::move($1), std::move($2), @$)); } | appBase { $$ = std::move($1); } ; appBase : INT { $$ = ast_ptr(new ast_int($1, @$)); } | LID { $$ = ast_ptr(new ast_lid(std::move($1), @$)); } | UID { $$ = ast_ptr(new ast_uid(std::move($1), @$)); } | OPAREN aAdd CPAREN { $$ = std::move($2); } | case { $$ = std::move($1); } | let { $$ = std::move($1); } | lambda { $$ = std::move($1); } ; let : LET OCURLY definitions CCURLY IN OCURLY aAdd CCURLY { $$ = ast_ptr(new ast_let(std::move($3), std::move($7), @$)); } ; lambda : BACKSLASH lowercaseParams ARROW OCURLY aAdd CCURLY { $$ = ast_ptr(new ast_lambda(std::move($2), std::move($5), @$)); } ; case : CASE aAdd OF OCURLY branches CCURLY { $$ = ast_ptr(new ast_case(std::move($2), std::move($5), @$)); } ; branches : branches branch { $$ = std::move($1); $$.push_back(std::move($2)); } | branch { $$ = std::vector(); $$.push_back(std::move($1));} ; branch : pattern ARROW OCURLY aAdd CCURLY { $$ = branch_ptr(new branch(std::move($1), std::move($4))); } ; pattern : LID { $$ = pattern_ptr(new pattern_var(std::move($1), @$)); } | UID lowercaseParams { $$ = pattern_ptr(new pattern_constr(std::move($1), std::move($2), @$)); } ; data : DATA UID lowercaseParams EQUAL OCURLY constructors CCURLY { $$ = definition_data_ptr(new definition_data(std::move($2), std::move($3), std::move($6), @$)); } ; constructors : constructors COMMA constructor { $$ = std::move($1); $$.push_back(std::move($3)); } | constructor { $$ = std::vector(); $$.push_back(std::move($1)); } ; constructor : UID typeList { $$ = constructor_ptr(new constructor(std::move($1), std::move($2))); } ; type : nonArrowType ARROW type { $$ = parsed_type_ptr(new parsed_type_arr(std::move($1), std::move($3))); } | nonArrowType { $$ = std::move($1); } ; nonArrowType : UID typeList { $$ = parsed_type_ptr(new parsed_type_app(std::move($1), std::move($2))); } | LID { $$ = parsed_type_ptr(new parsed_type_var(std::move($1))); } | OPAREN type CPAREN { $$ = std::move($2); } ; typeListElement : OPAREN type CPAREN { $$ = std::move($2); } | UID { $$ = parsed_type_ptr(new parsed_type_app(std::move($1), {})); } | LID { $$ = parsed_type_ptr(new parsed_type_var(std::move($1))); } ; typeList : %empty { $$ = std::vector(); } | typeList typeListElement { $$ = std::move($1); $$.push_back(std::move($2)); } ;