%{ (* parser.ml *) (* Analyseur syntaxique Alain FRISCH *) #open "expr";; #open "topl";; #open "global";; #open "divers";; %} %token LET IN FUN REC MAPSTO OF MATCH WITH %token FIRST SECOND HEAD TAIL %token INT %token IDENT %token STR %token CHAR %token PVIRG VIRG %token DBLPVIRG %token PARG PARD %token EGAL INF SUP INFEGAL SUPEGAL %token IF THEN ELSE %token PLUS MOINS MULT DIV %token AND %token ET PIPE OU %token NOT %token TRUE FALSE %token CROCHG CROCHD CONS %token UNIT %token EXCLAM DPEGAL DIEZE %token PRIM TYPE %right prec_let %right MAPSTO %right AND %right PVIRG %right prec_list %right prec_if %right DPEGAL %left PIPE %left OU %left VIRG %left ET %left NOT %left EGAL INF SUP INFEGAL SUPEGAL %right CONS %left PLUS MOINS %left MULT DIV %right prec_uminus %left prec_app %right DIEZE EXCLAM HEAD TAIL FIRST SECOND %start Phrase %type Phrase %% Phrase: Expr0 DBLPVIRG {topl__Expr ($1)} | Decl DBLPVIRG {topl__Decl ($1)} | TYPE TypeDef EGAL TypeSomme DBLPVIRG {topl__TypeDecl ($2,$4)} Decl: LET REC ListeLet {(true,$3)} | LET ListeLet {(false,$2)} Expr0: Expr1 {$1} | Expr1 ListeExpr1 %prec prec_app { it_list (fun ex e -> exprAppl(ex,e)) $1 $2 } | Expr0 VIRG Expr0 {exprPaire($1,$3)} | MOINS Expr0 %prec prec_uminus {exprOp(OpNeg, $2)} | NOT Expr0 {exprOp(OpNot, $2)} | Expr0 DPEGAL Expr0 {exprOp(OpAffect, exprPaire($1,$3))} | Expr0 INF Expr0 {exprOp (OpInf, exprPaire($1,$3))} | Expr0 INFEGAL Expr0 {exprOp (OpInfEgal, exprPaire($1,$3))} | Expr0 SUP Expr0 {exprOp (OpInf, exprPaire($3,$1))} | Expr0 SUPEGAL Expr0 {exprOp (OpInfEgal, exprPaire($3,$1))} | Expr0 EGAL Expr0 {exprOp (OpEgal, exprPaire($1,$3))} | Expr0 PLUS Expr0 {exprOp (OpAdd, exprPaire($1,$3))} | Expr0 MOINS Expr0 {exprOp (OpMoins, exprPaire($1,$3))} | Expr0 OU Expr0 {exprOp (OpOu, exprPaire($1,$3))} | Expr0 MULT Expr0 {exprOp (OpMult, exprPaire($1,$3))} | Expr0 DIV Expr0 {exprOp (OpDiv, exprPaire($1,$3))} | Expr0 ET Expr0 {exprOp (OpEt, exprPaire($1,$3))} | Expr0 CONS Expr0 {exprOp (OpCons, exprPaire($1,$3))} | IF Expr0 THEN Expr0 ELSE Expr0 %prec prec_if {ifthenelse $2 $4 $6} | IF Expr0 THEN Expr0 %prec prec_if {ifthenelse $2 $4 (exprCst CstUnit)} | Expr0 PVIRG Expr0 {exprOp(OpSeq, exprPaire($1,$3))} | Decl IN Expr0 {exprLet(fst $1, snd $1, $3)} | FUN IDENT PARG IdentList PARD EGAL Expr0 {exprLet(true, [$2,fonction $4 $7], exprIdent $2)} | FUN IdentListNonVide MAPSTO Expr0 {fonction $2 $4} | MATCH Expr0 WITH OptBar Match { exprMatch($2,$5) } IdentList: {[]} | IDENT IdentList {$1::$2} IdentListNonVide: IDENT IdentList {$1::$2} Expr1: CROCHG ListeExpr0 CROCHD { let rec aux = function [] -> exprCst (CstListeVide) | a::b ->exprOp(OpCons, exprPaire(a,aux b)) in aux (rev $2) } | UNIT {exprCst CstUnit} | IDENT {exprIdent $1} | INT {exprCst (CstEntier $1)} | STR {exprCst (CstChaine $1)} | CHAR {exprCst (CstCar $1)} | TRUE {exprCst (CstBooleen true)} | FALSE {exprCst (CstBooleen false)} | PARG Expr0 PARD {$2} | OpUnaire Expr1 {exprOp($1,$2)} ListeExpr0: ListeExpr0 PVIRG Expr0 %prec prec_list {$3::$1} | Expr0 %prec prec_list {[$1]} | {[]} ListeExpr1: Expr1 ListeExpr1 {$1::$2} | Expr1 {[$1]} ListeLet: Let1 {[$1]} | Let1 AND ListeLet {$1::$3} Let1: IDENT IdentList EGAL Expr0 {($1, fonction $2 $4)} OpUnaire: FIRST {OpFirst} | SECOND {OpSecond} | HEAD {OpHead} | TAIL {OpTail} | NOT {OpNot} | EXCLAM {OpIndirect} | DIEZE {OpRef} /* Expressions de type */ Type: TypeSimple {$1} | Type MULT Type {TSProd ($1,$3)} | Type MAPSTO Type {TSFleche ($1,$3)} TypeSimple: PRIM IDENT {TSVar $2} | IDENT {TSConstr ($1,[])} | TypeSimple IDENT {TSConstr ($2,[$1])} | PARG Type VIRG ListeType PARD IDENT {TSConstr ($6, $2::$4)} | PARG Type PARD {$2} ListeType: Type VIRG ListeType {$1::$3} | Type { [$1] } TypeSomme: ConstrDecl { [$1] } | ConstrDecl PIPE TypeSomme { $1::$3 } ConstrDecl: IDENT OF Type { ($1,Some $3) } | IDENT { ($1, None) } TypeDef: IDENT {[],$1} | PRIM IDENT IDENT {[$2],$3} | PARG PRIM IDENT ListeTypeVar PARD IDENT {$3::$4,$6} ListeTypeVar: {[]} | VIRG PRIM IDENT ListeTypeVar {$3::$4} /* Patterns */ OptBar: PIPE { () } | { () } Action: Pattern MAPSTO Expr0 { ($1,$3) } Match: Action PIPE Match { $1::$3 } | Action { [$1] } /* Version simplifiée */ Pattern: IDENT { let x=$1 in try let c=global_constrs.find x in PatConstr (c,"") with Not_found -> PatId $1 } | IDENT IDENT { PatConstr(global_constrs.find $1,$2) } /* Pattern: PARG Pattern PARD { $2 } | UNIT { PatCst CstUnit} | INT { PatCst (CstEntier $1)} | STR { PatCst (CstChaine $1)} | CHAR { PatCst (CstCar $1)} | TRUE { PatCst (CstBooleen true)} | FALSE { PatCst (CstBooleen false)} | Pattern VIRG Pattern { PatCouple ($1,$3) } | IDENT Pattern { PatConstr ($1,$2) } | IDENT { PatId $1 } */ %%