+strict_info :: { HsStrictnessInfo RdrName }
+strict_info : STRICT_PART qvar_name OCURLY qdata_names CCURLY { HsStrictnessInfo $1 (Just ($2,$4)) }
+ | STRICT_PART qvar_name { HsStrictnessInfo $1 (Just ($2,[])) }
+ | STRICT_PART { HsStrictnessInfo $1 Nothing }
+
+core_expr :: { UfExpr RdrName }
+ : LAM core_val_bndrs RARROW core_expr { foldr UfLam $4 $2 }
+ | BIGLAM core_tv_bndrs RARROW core_expr { foldr UfLam $4 $2 }
+ | CASE core_expr OF
+ OCURLY alg_alts core_default CCURLY { UfCase $2 (UfAlgAlts $5 $6) }
+ | PRIM_CASE core_expr OF
+ OCURLY prim_alts core_default CCURLY { UfCase $2 (UfPrimAlts $5 $6) }
+
+ | LET OCURLY core_val_bndr EQUAL core_expr CCURLY
+ IN core_expr { UfLet (UfNonRec $3 $5) $8 }
+ | LETREC OCURLY rec_binds CCURLY
+ IN core_expr { UfLet (UfRec $3) $6 }
+
+ | CCALL ccall_string
+ OBRACK atype atypes CBRACK core_args { let
+ (is_casm, may_gc) = $1
+ in
+ UfPrim (UfCCallOp $2 is_casm may_gc $5 $4)
+ $7
+ }
+
+ | INLINE_CALL core_expr { UfNote UfInlineCall $2 }
+ | COERCE atype core_expr { UfNote (UfCoerce $2) $3 }
+ | SCC core_expr { UfNote (UfSCC $1) $2 }
+ | fexpr { $1 }
+
+fexpr :: { UfExpr RdrName }
+fexpr : fexpr core_arg { UfApp $1 $2 }
+ | fexpr ATSIGN atype { UfApp $1 (UfTyArg $3) }
+ | aexpr { $1 }
+
+aexpr :: { UfExpr RdrName }
+aexpr : qvar_name { UfVar $1 }
+ | qdata_name { UfVar $1 }
+ | core_lit { UfLit $1 }
+ | OPAREN core_expr CPAREN { $2 }
+ | qdata_name OCURLY data_args CCURLY { UfCon $1 $3 }