Sources du TP Menhir
This commit is contained in:
parent
abf23ab803
commit
475b52957b
8 changed files with 131 additions and 0 deletions
8
tp/tp-menhir/code/AST.ml
Normal file
8
tp/tp-menhir/code/AST.ml
Normal file
|
@ -0,0 +1,8 @@
|
|||
type exp =
|
||||
| Id of identifier
|
||||
| LInt of int
|
||||
| Add of exp * exp
|
||||
| Mul of exp * exp
|
||||
| Sum of identifier * exp * exp * exp
|
||||
|
||||
and identifier = string
|
9
tp/tp-menhir/code/Makefile
Normal file
9
tp/tp-menhir/code/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
.PHONY: all clean
|
||||
|
||||
all:
|
||||
dune build marthe.exe
|
||||
ln -sf _build/default/marthe.exe marthe
|
||||
|
||||
clean:
|
||||
dune clean
|
||||
rm -fr *~ marthe
|
11
tp/tp-menhir/code/dune
Normal file
11
tp/tp-menhir/code/dune
Normal file
|
@ -0,0 +1,11 @@
|
|||
(ocamllex lexer)
|
||||
|
||||
(menhir
|
||||
(flags --explain --inspection --table)
|
||||
(modules parser))
|
||||
|
||||
(executable
|
||||
(name marthe)
|
||||
(ocamlopt_flags :standard)
|
||||
(libraries menhirLib)
|
||||
)
|
2
tp/tp-menhir/code/dune-project
Normal file
2
tp/tp-menhir/code/dune-project
Normal file
|
@ -0,0 +1,2 @@
|
|||
(lang dune 1.4)
|
||||
(using menhir 2.0)
|
17
tp/tp-menhir/code/lexer.mll
Normal file
17
tp/tp-menhir/code/lexer.mll
Normal file
|
@ -0,0 +1,17 @@
|
|||
{ (* Emacs, open this file with -*- tuareg -*- *)
|
||||
open Parser
|
||||
}
|
||||
|
||||
let layout = ' ' | '\t' | '\n'
|
||||
let number = ['0'-'9']+
|
||||
let identifier = ['a'-'z']['A'-'Z' '0'-'9' 'a'-'z' '_']*
|
||||
|
||||
rule token = parse
|
||||
| eof { EOF }
|
||||
| layout { token lexbuf }
|
||||
| number as i { INT (int_of_string i) }
|
||||
| identifier as s { ID s }
|
||||
| "+" { PLUS }
|
||||
| _ as c {
|
||||
failwith (Printf.sprintf "Invalid character: %c\n" c)
|
||||
}
|
36
tp/tp-menhir/code/marthe.ml
Normal file
36
tp/tp-menhir/code/marthe.ml
Normal file
|
@ -0,0 +1,36 @@
|
|||
let rec interactive_loop () =
|
||||
welcome_message ();
|
||||
let rec loop () =
|
||||
begin try
|
||||
read () |> eval |> print
|
||||
with exn ->
|
||||
Printf.printf "Error: %s\n%!" (Printexc.to_string exn)
|
||||
end;
|
||||
loop ()
|
||||
in
|
||||
loop ()
|
||||
|
||||
and welcome_message () =
|
||||
Printf.printf "
|
||||
====================================================\n
|
||||
Welcome to the incredible Marthe interactive loop! \n
|
||||
====================================================\n
|
||||
"
|
||||
|
||||
and read () =
|
||||
invite (); input_line stdin |> parse
|
||||
|
||||
and invite () =
|
||||
Printf.printf "> %!"
|
||||
|
||||
and parse input =
|
||||
let lexbuf = Lexing.from_string input in
|
||||
Parser.phrase Lexer.token lexbuf
|
||||
|
||||
and print e =
|
||||
Printf.printf ":- %s\n%!" (Printer.string_of_exp e)
|
||||
|
||||
and eval e =
|
||||
e
|
||||
|
||||
let main = interactive_loop ()
|
31
tp/tp-menhir/code/parser.mly
Normal file
31
tp/tp-menhir/code/parser.mly
Normal file
|
@ -0,0 +1,31 @@
|
|||
%{ (* Emacs, open this with -*- tuareg -*- *)
|
||||
open AST
|
||||
%}
|
||||
|
||||
%token<int> INT
|
||||
%token<string> ID
|
||||
%token PLUS EOF
|
||||
|
||||
%start<AST.exp> phrase
|
||||
|
||||
%left PLUS
|
||||
|
||||
%%
|
||||
|
||||
phrase: e=exp EOF
|
||||
{
|
||||
e
|
||||
}
|
||||
|
||||
exp: x=INT
|
||||
{
|
||||
LInt x
|
||||
}
|
||||
| x=ID
|
||||
{
|
||||
Id x
|
||||
}
|
||||
| e1=exp PLUS e2=exp
|
||||
{
|
||||
Add (e1, e2)
|
||||
}
|
17
tp/tp-menhir/code/printer.ml
Normal file
17
tp/tp-menhir/code/printer.ml
Normal file
|
@ -0,0 +1,17 @@
|
|||
open AST
|
||||
|
||||
let string_of_exp e =
|
||||
let rec aux = function
|
||||
| Id x ->
|
||||
x
|
||||
| LInt x ->
|
||||
string_of_int x
|
||||
| Add (e1, e2) ->
|
||||
Printf.sprintf "(%s + %s)" (aux e1) (aux e2)
|
||||
| Mul (e1, e2) ->
|
||||
Printf.sprintf "(%s * %s)" (aux e1) (aux e2)
|
||||
| Sum (x, start, stop, exp) ->
|
||||
Printf.sprintf "sum(%s, %s, %s, %s)"
|
||||
x (aux start) (aux stop) (aux exp)
|
||||
in
|
||||
aux e
|
Reference in a new issue