Skip to content
Snippets Groups Projects
Commit e8d13423 authored by Augustin Jaujay's avatar Augustin Jaujay
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
README 0 → 100644
AUTHORS
-------
- NAME1
- NAME2
===============
Description of the project
--------------------------
This μ-project is a very simple compiler…
===============
Sources
-------
Git repository: https://redmine-df.telecom-bretagne.eu/git/PROJECTNAME
(obviously, you _will_ use a version control system such as Git, IMT
Atlantique provides a project management platform: use it!)
Release : tag 1.0 or commit acdeacdacdacdacd
===============
How to…
-------
…retrieve the sources?
git clone https://redmine-df.telecom-bretagne.eu/git/PROJECTNAME
…compile?
dune …
…execute and test?
dune exec ./pfxVM.exe -- TESTFILE.pfx
===============
Structure of the project
------------------------
The project is organized as following:
Explain here the organization of your project, what is the use of each file or
group of files, etc.
You may also show the file tree as the following example:
project
├── README
├── dune-project
├── expr: the expr compiler
│ ├── README
│ ├── basic
│ │ ├── ast.ml
│ │ ├── ast.mli
│ │ ├── dune
│ │ ├── eval.ml
│ │ ├── eval.mli
│ │ ├── lexer.mll
│ │ ├── parser.mly
│ │ ├── tests: for tests
│ │ │ └── an_example.expr
│ │ ├── toPfx.ml <- To edit
│ │ └── toPfx.mli
│ ├── common
│ │ ├── binOp.ml
│ │ ├── binOp.mli
│ │ └── dune
│ ├── compiler.ml: main file for the expr compiler
│ ├── dune
│ ├── fun: the expr parser for section 7
│ │ ├── ast.ml
│ │ ├── ast.mli
│ │ ├── lexer.mll
│ │ └── parser.mly
│ └── main.ml
├── pfx: the pfx VM
│ ├── basic
│ │ ├── ast.ml <- To edit
│ │ ├── ast.mli
│ │ ├── dune
│ │ ├── eval.ml <- To edit
│ │ ├── eval.mli
│ │ ├── lexer.mll <- To edit
│ │ ├── parser.mly <- To edit
│ │ └── tests: for tests
│ │ └── ok_prog.pfx
│ └── pfxVM.ml: main file for the pfx VM
└── utils
├── dune
├── location.ml: module offering a data type for a location in a file
└── location.mli
===============
Progress
--------
- We stopped at question 10.1 (proof of derivation)
- There is still a bug in question 8.3 (new version of generate function)
- …
===============
Know bugs and issues
--------------------
- We were not able to manage xxx…
- Compiler fails when xxx…
- …
===============
Helpful resources
-----------------
- we used Stack Overflow to solve the problem of xxx :
https://stackoverflow/xxxxxxi
https://stackoverflow/yyyyyy
- someone on GitHub provided an interesting example very similar to the answer of the question x.y : https://github.com/xxxx
- …
===============
Difficulties
------------
- team programming: having to use a VCS such as git and avoiding conflicts
- thinking functional
- changing habits by using an unknown language
- Not a single difficulty: the project was so easy that my 8-old brother did it
completely; the Ocaml language is so nice I enjoyed the project, …
- …
(lang dune 2.5)
(name langlog)
(using menhir 2.0)
You can test the provided code in utop by
dune utop .
and then, for example
utop # open BasicExpr;;
utop # let expr_prog = Parser.expression Lexer.token (Lexing.from_string "5 + 6");;
val expr_prog : Ast.expression =
BasicExpr.Ast.Binop (BinOp.Badd, BasicExpr.Ast.Const 5,
BasicExpr.Ast.Const 6)
utop # Ast.string_of_expr expr_prog;;
- : string = "(5+6)"
utop # Eval.eval [] expr_prog;;
- : int = 11
type expression =
| Const of int
| Var of string
| Binop of BinOp.t * expression * expression
| Uminus of expression
let rec string_of_expr exp =
match exp with
| Const c -> string_of_int c
| Var v -> v
| Binop(op, e1, e2) ->
"(" ^(string_of_expr e1)^ (BinOp.string_of op) ^(string_of_expr e2)^ ")"
| Uminus e -> "( -"^(string_of_expr e)^ ")"
(* The expression type *)
type expression =
Const of int
| Var of string
| Binop of BinOp.t * expression * expression
| Uminus of expression
(* Converting an expression to a string for printing *)
val string_of_expr : expression -> string
(library
(name basicExpr)
(libraries utils common basicPfx)
(modules Ast Lexer Parser Eval toPfx))
(ocamllex lexer)
(menhir
(modules parser)
(flags --explain))
open Ast
exception RuntimeError of string
let rec eval env = function
| Const c -> c
| Var v -> (try List.assoc v env with Not_found -> raise(RuntimeError("Unbound variable "^v)))
| Binop(op,e1,e2) ->
begin
match op,eval env e2 with
| (Bdiv | Bmod), 0 -> raise(RuntimeError("division by zero"))
| _, v -> (BinOp.eval op) (eval env e1) v
end
| Uminus e -> - (eval env e)
(* Exception that may be raised on error at run time by the function eval *)
exception RuntimeError of string
(* Function that evaluates an expression in a given environment *)
val eval : (string * int) list -> Ast.expression -> int
{
open Parser
open Utils
let mk_int nb loc =
try INT (int_of_string nb)
with Failure _ -> raise (Location.Error(Printf.sprintf "Illegal integer '%s': " nb,loc))
}
let newline = (['\n' '\r'] | "\r\n")
let blank = [' ' '\014' '\t' '\012']
let not_newline_char = [^ '\n' '\r']
let digit = ['0'-'9']
let integer = digit+
let letter = ['a'-'z' 'A'-'Z']
let ident = letter (letter | digit | '_')*
rule token = parse
(* newlines *)
| newline { Location.incr_line lexbuf; token lexbuf }
(* blanks *)
| blank + { token lexbuf }
(* end of file *)
| eof { EOF }
(* comments *)
| "--" not_newline_char* { token lexbuf }
(* integers *)
| integer as nb { mk_int nb (Location.curr lexbuf)}
(* commands *)
| "+" { PLUS }
| "-" { MINUS }
| "/" { DIV }
| "*" { TIMES }
| "%" { MOD }
| "(" { LPAR }
| ")" { RPAR }
(* identifiers *)
| ident as id { IDENT id }
(* illegal characters *)
| _ as c { raise (Location.Error(Printf.sprintf "Illegal character '%c': " c, Location.curr lexbuf)) }
%{
open Ast
open BinOp
%}
%token EOF PLUS MINUS TIMES DIV MOD LPAR RPAR
%token <int> INT
%token <string> IDENT
%start < Ast.expression > expression
%left PLUS MINUS
%left TIMES DIV MOD
%right UMINUS
%%
expression:
| e=expr EOF { e }
expr:
| MINUS e=expr %prec UMINUS { Uminus e }
| e1=expr o=bop e2=expr { Binop(o,e1,e2) }
| e=simple_expr { e }
simple_expr:
| LPAR e=expr RPAR { e }
| id=IDENT { Var id }
| i=INT { Const i }
%inline bop:
| MINUS { Bsub }
| PLUS { Badd }
| TIMES { Bmul }
| DIV { Bdiv }
| MOD { Bmod }
%%
(5 / 1) + (8 * -9)
open Ast
let generate = function
| Const _ -> failwith "To implement"
| Binop(_,_,_) -> failwith "To implement"
| Uminus _ -> failwith "To implement"
| Var _ -> failwith "Not yet supported"
(* Function that generate a Pfx program from an Expr program *)
val generate : Ast.expression -> BasicPfx.Ast.command list
type t = Badd | Bsub | Bmul | Bdiv | Bmod
let string_of = function
| Badd -> "+"
| Bsub -> "-"
| Bmul -> "*"
| Bdiv -> "/"
| Bmod -> "%"
let eval op x y =
match op with
| Badd -> x + y
| Bsub -> x - y
| Bmul -> x * y
| Bdiv -> x / y
| Bmod -> x mod y
type t = Badd | Bsub | Bmul | Bdiv | Bmod
val string_of : t -> string
val eval : t -> int -> int -> int
(library
(name common)
(modules BinOp)
(wrapped false))
open BasicExpr
open Utils
(* The main function *)
let parse_eval file =
print_string ("File "^file^" is being treated!\n");
try
let input_file = open_in file in
let lexbuf = Lexing.from_channel input_file in
begin
try
let expr_prog = Parser.expression Lexer.token lexbuf in
let pfx_prog = 0, ToPfx.generate expr_prog in
print_endline (BasicPfx.Ast.string_of_program pfx_prog);
BasicPfx.Eval.eval_program pfx_prog []
with
| BasicPfx.Parser.Error ->
print_string "Syntax error: ";
Location.print (Location.curr lexbuf)
| Location.Error(e,l) ->
print_string e;
Location.print l
end;
close_in (input_file)
with Sys_error _ ->
print_endline ("Can't find file '" ^ file ^ "'")
(* Here we add the parsing of the command line and link to the main function *)
let _ =
Arg.parse [] parse_eval ""
(executables
(names main compiler)
(libraries utils basicExpr))
type expression =
| Const of int
| Var of string
| Binop of BinOp.t * expression * expression
| Uminus of expression
(* For function support *)
| App of expression * expression
| Fun of string * expression
let rec string_of_expr exp =
match exp with
| Const c -> string_of_int c
| Var v -> v
| Binop(op, e1, e2) ->
"(" ^(string_of_expr e1)^ (BinOp.string_of op) ^(string_of_expr e2)^ ")"
| Uminus e -> "( -"^(string_of_expr e)^ ")"
(* For function support *)
| App(e1,e2) -> (string_of_expr e1)^" "^(string_of_expr e2)
| Fun(v,e) -> "fun "^v^" -> "^(string_of_expr e)
(* The expression type *)
type expression =
Const of int
| Var of string
| Binop of BinOp.t * expression * expression
| Uminus of expression
(* For function support *)
| App of expression * expression
| Fun of string * expression
(* Converting an expression to a string for printing *)
val string_of_expr : expression -> string
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment