Cours 02
This commit is contained in:
parent
d005428cf1
commit
abf23ab803
10 changed files with 128 additions and 0 deletions
6
cours/cours-02/ast.ml
Normal file
6
cours/cours-02/ast.ml
Normal file
|
@ -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)" *)
|
7
cours/cours-02/dune
Normal file
7
cours/cours-02/dune
Normal file
|
@ -0,0 +1,7 @@
|
|||
(executable
|
||||
(name marthe)
|
||||
)
|
||||
|
||||
(ocamllex (modules lexer))
|
||||
(menhir (modules parser) (infer true) (flags --explain))
|
||||
|
3
cours/cours-02/dune-project
Normal file
3
cours/cours-02/dune-project
Normal file
|
@ -0,0 +1,3 @@
|
|||
(lang dune 2.2)
|
||||
(using menhir 2.1)
|
||||
|
15
cours/cours-02/lexer.mll
Normal file
15
cours/cours-02/lexer.mll
Normal file
|
@ -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 *)
|
||||
}
|
55
cours/cours-02/marthe.ml
Normal file
55
cours/cours-02/marthe.ml
Normal file
|
@ -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
|
33
cours/cours-02/parser.mly
Normal file
33
cours/cours-02/parser.mly
Normal file
|
@ -0,0 +1,33 @@
|
|||
%{
|
||||
(* Prelude *)
|
||||
open Ast
|
||||
%}
|
||||
|
||||
(* Zone des déclarations *)
|
||||
%token EOF PLUS STAR
|
||||
%token<int> INT
|
||||
%start<Ast.e> 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)
|
||||
}
|
BIN
cours/cours-flap.pdf
Normal file
BIN
cours/cours-flap.pdf
Normal file
Binary file not shown.
BIN
cours/cours-parsing.pdf
Normal file
BIN
cours/cours-parsing.pdf
Normal file
Binary file not shown.
|
@ -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.
|
||||
|
|
BIN
tp/tp-menhir/sujet/tp-menhir.pdf
Normal file
BIN
tp/tp-menhir/sujet/tp-menhir.pdf
Normal file
Binary file not shown.
Reference in a new issue