diff --git a/cours/cours-02/ast.ml b/cours/cours-02/ast.ml new file mode 100644 index 0000000..7e70617 --- /dev/null +++ b/cours/cours-02/ast.ml @@ -0,0 +1,6 @@ +type e = + | EInt of int (** Ex: "42", "31" *) + | EVar of string (** Ex: "x", "y", "foo" *) + | EPlus of e * e (** Ex: "1 + 2", "2 * 3 + 4" *) + | EMult of e * e (** Ex: "1 * 2", "(1 + 2) * 3" *) + | ESum of string * e * e * e (** Ex: "sum (x, 1, 10, x * x)" *) diff --git a/cours/cours-02/dune b/cours/cours-02/dune new file mode 100644 index 0000000..2ab964e --- /dev/null +++ b/cours/cours-02/dune @@ -0,0 +1,7 @@ +(executable + (name marthe) + ) + +(ocamllex (modules lexer)) +(menhir (modules parser) (infer true) (flags --explain)) + diff --git a/cours/cours-02/dune-project b/cours/cours-02/dune-project new file mode 100644 index 0000000..521634c --- /dev/null +++ b/cours/cours-02/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.2) +(using menhir 2.1) + diff --git a/cours/cours-02/lexer.mll b/cours/cours-02/lexer.mll new file mode 100644 index 0000000..5bdf448 --- /dev/null +++ b/cours/cours-02/lexer.mll @@ -0,0 +1,15 @@ +{ + (* Prelude *) + open Parser +} + +rule token = parse +| ['0'-'9']+ as x { INT (int_of_string x) } +| '+' { PLUS } +| '*' { STAR } +| ' ' { token lexbuf } +| eof { EOF } + +{ + (* Postlude *) +} diff --git a/cours/cours-02/marthe.ml b/cours/cours-02/marthe.ml new file mode 100644 index 0000000..b0b0aa6 --- /dev/null +++ b/cours/cours-02/marthe.ml @@ -0,0 +1,55 @@ +open Ast + +let parse lexbuf = Parser.phrase Lexer.token lexbuf + +let interpret : e -> int = + (* Le paramètre [env] est une liste associative contenant la valeur associée + aux indices de sommation. + + La fonction d'évaluation est définie par cas sur la forme de l'arbre. *) + let rec aux env = function + (* Pour évaluer une expression de la forme "e1 + e2", on évalue [e1] en un + entier, on évalue [e2] en un autre entier, puis on fait la somme des deux + entiers. *) + | EPlus (e1, e2) -> aux env e1 + aux env e2 + + (* Même raisonnement pour la multiplication. *) + | EMult (e1, e2) -> aux env e1 * aux env e2 + + (* Une expression qui est un entier s'évalue en cet entier. *) + | EInt x -> x + + (* Pour évaluer une expression de la forme "sum (x, start, stop, body)". *) + | ESum (x, start, stop, body) -> + (* On évalue [start]. *) + let vstart = aux env start + (* On évalue [stop]. *) + and vstop = aux env stop + in + (* On itère sur toutes les valeurs [i] de [start] à [stop] et on accumule + les sommes intermédiaires dans la variable [accu]. *) + let rec iter i accu = + if i > vstop then + accu + else + (* L'évaluation de [body] se fait dans un environnement où l'indice + [x] est associé à la valeur [i]. *) + iter (i + 1) (accu + aux ((x, i) :: env) body) + in + iter vstart 0 + + (* Une expression qui est variable s'évalue en la valeur associée à cette + variable dans l'environnement. *) + | EVar x -> + List.assoc x env + in + aux [] + +let process filename = + let cin = open_in filename in + let ast = parse (Lexing.from_channel cin) in + let x = interpret ast in + Printf.printf "Result: %d\n%!" x + +let main = + Array.iteri (fun i filename -> if i >= 1 then process filename) Sys.argv diff --git a/cours/cours-02/parser.mly b/cours/cours-02/parser.mly new file mode 100644 index 0000000..76190cc --- /dev/null +++ b/cours/cours-02/parser.mly @@ -0,0 +1,33 @@ +%{ + (* Prelude *) + open Ast +%} + +(* Zone des déclarations *) +%token EOF PLUS STAR +%token INT +%start phrase + +%% + +(* Cette grammaire a un conflit avancer-réduire. Comment le régler ? *) + +(* Ici on écrit les règles de grammaire. *) + +phrase: e=expression EOF +{ + e +} + +expression: x=INT +{ + EInt x +} +| lhs=expression PLUS rhs=expression +{ + EPlus (lhs, rhs) +} +| lhs=expression STAR rhs=expression +{ + EMult (lhs, rhs) +} diff --git a/cours/cours-flap.pdf b/cours/cours-flap.pdf new file mode 100644 index 0000000..1be1c8c Binary files /dev/null and b/cours/cours-flap.pdf differ diff --git a/cours/cours-parsing.pdf b/cours/cours-parsing.pdf new file mode 100644 index 0000000..bd537b1 Binary files /dev/null and b/cours/cours-parsing.pdf differ diff --git a/cours/journal.org b/cours/journal.org index 0c0217d..9713c19 100644 --- a/cours/journal.org +++ b/cours/journal.org @@ -31,3 +31,12 @@ https://listes.u-paris.fr/wws/info/m1.2023.compilation.info *** TODO Prochain séance de cours - Finir la gestion des commentaires dans ~marthe.ml~. +* Cours 02 <2023-09-27> +** Analyse syntaxique appliquée + Voir les [[file:cours-parsing.pdf][transparents]]. +** Aperçu de flap + Voir les [[file:cours-flap.pdf][transparents]]. +** La semaine prochaine + - En TP : une initiation à Menhir. + + - En cours : le démarrage du jalon 1. diff --git a/tp/tp-menhir/sujet/tp-menhir.pdf b/tp/tp-menhir/sujet/tp-menhir.pdf new file mode 100644 index 0000000..15e2bae Binary files /dev/null and b/tp/tp-menhir/sujet/tp-menhir.pdf differ