From e2e80bf55c8a894a0ede3b4fe33304c1b0c1eec7 Mon Sep 17 00:00:00 2001 From: Marwan Date: Tue, 9 Apr 2024 11:09:33 +0200 Subject: [PATCH] initial commit --- README.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ affichage.ml | 21 +++++++++++++++++++++ dune | 14 ++++++++++++++ dune-project | 3 +++ expr.ml | 9 +++++++++ lexer.mll | 29 +++++++++++++++++++++++++++++ main.ml | 19 +++++++++++++++++++ parser.mly | 40 ++++++++++++++++++++++++++++++++++++++++ tests/basic.ml | 1 + 9 files changed, 180 insertions(+) create mode 100644 README.md create mode 100644 affichage.ml create mode 100644 dune create mode 100644 dune-project create mode 100644 expr.ml create mode 100644 lexer.mll create mode 100644 main.ml create mode 100644 parser.mly create mode 100644 tests/basic.ml diff --git a/README.md b/README.md new file mode 100644 index 0000000..6f7d8cb --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +Ce répertoire contient un sequelette de départ à partir duquel vous +pouvez programmer votre fouine. + +## Compilation et execution + +pour (re)compiler, lancer +``` +dune build +``` + +pour compiler et executer le programme, lancer +``` +dune exec ./main.exe +``` + +pour executer le programme, lancer +``` +./_build/default/main.exe +``` + +entrez ensuite une expression arithmetique, avec juste `+` et `*`, comme par exemple `4+3*5` +et vous obtiendrez: +``` +Add(4, Mul(3, 5)) +19 +``` + +vous pouvez aussi faire: +``` +dune exec ./main.exe < tests/basic.ml +``` +pour lancer fouine sur le fichier `basic.ml` + +main.ml : fichier principal +expr.ml : définition des expressions et de l'évaluation +affichage.ml : fonctions d'affichage +lexer.mll : lexèmes, analyse lexicale +parser.mly : règles de grammaire, analyse syntaxique +tests/ : sous-répertoire de tests +dune, dune-project : pour la compilation, à ne pas modifier a priori + +## Erreurs à la compilation en lien avec le lexer et le parser : + référez-vous à l'archive disponible depuis la page du portail des études + diff --git a/affichage.ml b/affichage.ml new file mode 100644 index 0000000..16e32db --- /dev/null +++ b/affichage.ml @@ -0,0 +1,21 @@ +open Expr + +(* fonction d'affichage *) +let rec affiche_expr e = + let aff_aux s a b = + begin + print_string s; + affiche_expr a; + print_string ", "; + affiche_expr b; + print_string ")" + end + in + match e with + | Const k -> print_int k + | Add(e1,e2) -> aff_aux "Add(" e1 e2 + | Mul(e1,e2) -> aff_aux "Mul(" e1 e2 + | Min(e1,e2) -> aff_aux "Min(" e1 e2 + +let affiche_val v = print_string "TODO" + diff --git a/dune b/dune new file mode 100644 index 0000000..ca7b91a --- /dev/null +++ b/dune @@ -0,0 +1,14 @@ +(executable + (name main)) + +(ocamllex lexer) +(menhir + (flags --explain --dump) + (modules parser)) + + + +(env + (dev + (flags (:standard -warn-error -A)))) + diff --git a/dune-project b/dune-project new file mode 100644 index 0000000..cbb90e6 --- /dev/null +++ b/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.9) + +(using menhir 2.1) diff --git a/expr.ml b/expr.ml new file mode 100644 index 0000000..72e7192 --- /dev/null +++ b/expr.ml @@ -0,0 +1,9 @@ +type id = string + +type ty_annot = id * string + +type expr = + Fun of ty_annot * expr + | App of expr * expr + | Var of id + | Exf of expr * string diff --git a/lexer.mll b/lexer.mll new file mode 100644 index 0000000..bb8468f --- /dev/null +++ b/lexer.mll @@ -0,0 +1,29 @@ +{ + open Parser + exception Eof +} + +let lowercase = ['a'-'z'] +let uppercase = ['A'-'Z'] +let digit = ['0'-'9'] +let word = (lowercase | uppercase)* + +let var_id = lowercase lowercase* digit* +let ty_id = uppercase word digit* + +rule token = parse + | [' ' '\t'] { token lexbuf } + | '\n' { EOL } + | '+' { PLUS } + | '*' { TIMES } + | '1' { TOP } + | '0' { BOTTOM } + | '(' { LPAREN } + | ')' { RPAREN } + | "FUN" { FUN } + | ':' { COLON } + | "=>" { ARR } + | "exf" { EXFALSO } + | var_id as s { VARID(s) } + | ty_id as s { TYID(s) } + | eof { raise Eof } diff --git a/main.ml b/main.ml new file mode 100644 index 0000000..df9ea64 --- /dev/null +++ b/main.ml @@ -0,0 +1,19 @@ +open Expr + +let interpret e = + begin + affiche_expr e; + print_newline(); + print_int (eval e); + print_newline() + end + +let lexbuf = Lexing.from_channel stdin + +let parse () = Parser.main Lexer.token lexbuf + +let calc () = + let result = parse () in + interpret result; flush stdout + +let _ = calc() diff --git a/parser.mly b/parser.mly new file mode 100644 index 0000000..68f5a10 --- /dev/null +++ b/parser.mly @@ -0,0 +1,40 @@ +%{ +open Expr +%} + +%token PLUS TIMES +%token TOP BOTTOM EXFALSO +%token LPAREN RPAREN +%token FUN ARR COLON +%token VARID +%token TYID + +%token EOL + +%start main +%type main + +%% +main: +e=expression EOL { e } + + +ty: + | id=TYID { id } + +ty_annot: + | id=VARID COLON t=ty { (id, t) } + +expression: + | FUN LPAREN annot=ty_annot RPAREN ARR e=expression + { Fun (annot, e) } + | e=app_expr { e } + +app_expr: + | e=app_expr a=atomic { App (e, a) } + | a=atomic { a } + +atomic: + | id=VARID { Var id } + | LPAREN e=expression RPAREN + { e } diff --git a/tests/basic.ml b/tests/basic.ml new file mode 100644 index 0000000..b494a3c --- /dev/null +++ b/tests/basic.ml @@ -0,0 +1 @@ +fun (x:A) => x