TP-traduction-langages/parser.mly
2021-11-24 18:23:17 +01:00

101 lines
3.5 KiB
OCaml
Executable file

%{
open Ast
%}
%token <int> NumberToken
%token <string> IdentToken
%token FunctionToken
%token BodyToken
%token IfToken
%token ThenToken
%token ElseToken
%token LetToken
%token InToken
%token TrueToken
%token FalseToken
%token RecToken
%token LeftParenthesisToken
%token RightParenthesisToken
%token EOF
%token OrToken, AndToken, DifferentToken, EqualToken
%token LesserToken, GreaterToken, LesserEqualToken, GreaterEqualToken
%token PlusToken, MinusToken
%token StarToken, SlashToken
%token UMinusToken
(* priorité et associativité *)
(* Plus faible priorité au début *)
(* http://caml.inria.fr/pub/docs/manual-ocaml/expr.html#sec116 *)
%nonassoc BodyToken, ElseToken, InToken, RightParenthesisToken
(* %nonassoc IfToken *)
%right OrToken
%right AndToken
%left DifferentToken, EqualToken
%nonassoc LesserToken, GreaterToken, LesserEqualToken, GreaterEqualToken
%left PlusToken, MinusToken
%left StarToken, SlashToken
%left UMinusToken
(* Type de l'attribut synthétisé des non-terminaux *)
%type <Ast.ast> expr
(* Type et définition de l'axiome *)
%start <Ast.ast> main
%%
(*
La grammaire n'est pas LR , on joue avec les priorités
E -> fun ident -> E
E -> let ident = E in E
E -> letrec ident = E in E
E -> if E then E else E
E -> (E) E
E -> (E)
E -> - E
E -> E = E
E -> E != E
E -> E >= E
E -> E > E
E -> E <= E
E -> E < E
E -> E & E
E -> E | E
E -> E * E
E -> E / E
E -> E - E
E -> E + E
E -> Ident
E -> Const
*)
main : a = expr EOF {a}
expr :
| FunctionToken n = IdentToken BodyToken e = expr {FunctionNode (n,e)}
| LetToken n = IdentToken EqualToken e1 = expr InToken e2 = expr {LetNode (n,e1,e2)}
| RecToken n = IdentToken EqualToken e1 = expr InToken e2 = expr {LetrecNode (n,e1,e2)}
| IfToken c= expr ThenToken t = expr ElseToken e = expr {IfthenelseNode (c,t,e)}
| LeftParenthesisToken f = expr RightParenthesisToken p =expr {CallNode (f,p)}
| LeftParenthesisToken e = expr RightParenthesisToken {e}
| MinusToken e = expr %prec UMinusToken {UnaryNode (Negate,e)}
| e1 = expr EqualToken e2 = expr {BinaryNode (Equal,e1,e2)}
| e1 = expr DifferentToken e2 = expr {BinaryNode (Different,e1,e2)}
| e1 = expr LesserToken e2 = expr {BinaryNode (Lesser,e1,e2)}
| e1 = expr GreaterToken e2 = expr {BinaryNode (Greater,e1,e2)}
| e1 = expr LesserEqualToken e2 = expr {BinaryNode (LesserEqual,e1,e2)}
| e1 = expr GreaterEqualToken e2 = expr {BinaryNode (GreaterEqual,e1,e2)}
| e1 = expr AndToken e2 = expr {BinaryNode (And,e1,e2)}
| e1 = expr OrToken e2 = expr {BinaryNode (Or,e1,e2)}
| e1 = expr PlusToken e2 = expr {BinaryNode (Add,e1,e2)}
| e1 = expr MinusToken e2 = expr {BinaryNode (Substract,e1,e2)}
| e1 = expr StarToken e2 = expr {BinaryNode (Multiply,e1,e2)}
| e1 = expr SlashToken e2 = expr {BinaryNode (Divide,e1,e2)}
| n = IdentToken {AccessNode n}
| i = NumberToken {IntegerNode i}
| TrueToken {TrueNode}
| FalseToken {FalseNode}