Commit ba25fa50 authored by Nicaudie Charlotte's avatar Nicaudie Charlotte

Merge branch 'develop'

parents bb1dc412 db07539a
all:
ocamlbuild -pkgs unix -use-menhir -menhir "menhir --explain --dump" main.native
mv main.native turtle-js
clean:
ocamlbuild -clean
rm -f turtle-js
\ No newline at end of file
(*
Float range for XY coordinates
X between float1 and float2
Y between float3 and float4
*)
type init = float * float * float * float
type stmt =
| Translation of float * float
| Rotation of float * float * float
| StmtList of stmt list
| Or of stmt * stmt * float (* Float is the left-member's random weightening *)
| Iter of stmt * int * int (* Min and max number of iteration *)
type program = init * stmt
(* Analyseur lexical pour mini-Turtle *)
{
open Lexing
open Parser
exception Lexing_error of string
(*
Table of keywords (only identifying keywords)
*)
let keyword_table =
["init", INIT;
"iter", ITER;
"translation", TRANSLATION;
"rotation", ROTATION;
"or", OR;
(* "if", IF;
"else", ELSE;
"def", DEF;
"repeat", REPEAT;
"penup", PENUP;
"pendown", PENDOWN;
"forward", FORWARD;
"turnleft", TURNLEFT;
"turnright", TURNRIGHT;
"color", COLOR;
"black", BLACK;
"white", WHITE;
"red", RED;
"green", GREEN;
"blue", BLUE;
*) ]
let id_or_kwd =
let h = Hashtbl.create 17 in
List.iter (fun (s,t) -> Hashtbl.add h s t) keyword_table;
fun s ->
let s = String.lowercase_ascii s in (* not sensitive to casing *)
try List.assoc s keyword_table with _ -> IDENT s (* rend Ident qd il trouve pas dans la table d'assoc*)
let newline lexbuf =
let pos = lexbuf.lex_curr_p in
lexbuf.lex_curr_p <-
{ pos with pos_lnum = pos.pos_lnum + 1; pos_bol = pos.pos_cnum }
}
let letter = ['a'-'z' 'A'-'Z']
let digit = ['0'-'9']
let ident = letter (letter | digit | '_')*
let integer = ['0'-'9']+
let float = ['0'-'9']+'.'['0'-'9']+
let space = [' ' '\t']
rule get_token = parse
| "#" [^ '\n']* '\n'
| '\n' { newline lexbuf; get_token lexbuf }
| space+ { get_token lexbuf }
| ident as id { id_or_kwd id }
(* | '+' { PLUS }
| '-' { MINUS }
| '*' { TIMES }
| '/' { DIV }*)
| '(' { LPAREN }
| ')' { RPAREN }
| '{' { BEGIN }
| '}' { END }
| ',' { COMMA }
| ';' { SEMICOLON }
| "(*" { comment lexbuf }
| integer as s { INT (int_of_string s) }
| float as f { FLOAT (float_of_string f) }
| "#" [^ '\n']* eof
| eof { EOF }
| _ as c { raise (Lexing_error ("illegal character: " ^ String.make 1 c)) }
(* Note : comments cannot be interlocked in Turtle *)
and comment = parse
| "*)" { get_token lexbuf }
| _ { comment lexbuf }
| eof { raise (Lexing_error ("unterminated comment")) }
\ No newline at end of file
(* Fichier principal de l'interprète mini-Turtle *)
open Format
open Lexing
(* Option de compilation, pour s'arrêter à l'issue du parser *)
let parse_only = ref false
(* Noms des fichiers source et cible *)
let ifile = ref ""
let ofile = ref ""
let set_file f s = f := s
(* Les options du compilateur que l'on affiche avec --help *)
let options =
["--parse-only", Arg.Set parse_only,
" Pour ne faire uniquement que la phase d'analyse syntaxique"]
let usage = "usage: turtle-js [option] file.tjs"
(* localise une erreur en indiquant la ligne et la colonne *)
let localisation pos =
let l = pos.pos_lnum in
let c = pos.pos_cnum - pos.pos_bol + 1 in
eprintf "File \"%s\", line %d, characters %d-%d:\n" !ifile l (c-1) c
let () =
(* Parsing de la ligne de commande *)
Arg.parse options (set_file ifile) usage;
(* On vérifie que le nom du fichier source a bien été indiqué *)
if !ifile="" then begin eprintf "Aucun fichier a compiler\n@?"; exit 1 end;
(* Ce fichier doit avoir l'extension .logo *)
if not (Filename.check_suffix !ifile ".tjs") then begin
eprintf "Le fichier d'entree doit avoir l'extension .tjs\n@?";
Arg.usage options usage;
exit 1
end;
(* Ouverture du fichier source en lecture *)
let f = open_in !ifile in
(* Création d'un tampon d'analyse lexicale *)
let buf = Lexing.from_channel f in
try
(* Parsing: la fonction Parser.prog transforme le tampon lexical en un
arbre de syntaxe abstraite si aucune erreur (lexicale ou syntaxique)
n'est détectée.
La fonction Lexer.token est utilisée par Parser.prog pour obtenir
le prochain token. *)
(*let p = Parser.prog Lexer.token buf in*)
Print_tokens.print stdout buf;
close_in f;
exit 0;
(* On s'arrête ici si on ne veut faire que le parsing *)
if !parse_only then exit 0;
(*Interp.prog p*)
() (* = void *)
with
| Lexer.Lexing_error c ->
(* Erreur lexicale. On récupère sa position absolue et
on la convertit en numéro de ligne *)
localisation (Lexing.lexeme_start_p buf);
eprintf "Erreur lexicale: %s@." c;
exit 1
| Parser.Error ->
(* Erreur syntaxique. On récupère sa position absolue et on la
convertit en numéro de ligne *)
localisation (Lexing.lexeme_start_p buf);
eprintf "Erreur syntaxique@.";
exit 1
(*| Interp.Error s->
(* Erreur pendant l'interprétation *)
eprintf "Erreur : %s@." s;
exit 1 *)
\ No newline at end of file
%{ open Ast %}
/*
Tokens declarations
*/
%token <int> INT
%token <float> FLOAT
%token <string> IDENT
%token INIT ITER
%token TRANSLATION ROTATION
%token COMMA SEMICOLON
%token BEGIN END
%token OR
%token LPAREN RPAREN
%token EOF
(*
%token DEF IF ELSE
%token PLUS MINUS TIMES DIV
%token REPEAT PENUP PENDOWN FORWARD TURNLEFT TURNRIGHT
%token COLOR BLACK WHITE RED GREEN BLUE
*)
/*
Tokens priorities and associativities
*/
(*
%left MINUS PLUS
%left TIMES DIV
%nonassoc uminus // used to negate a number
%nonassoc IF
%nonassoc ELSE
*)
/*
Grammar entry point
*/
%start program
/*
Value types returned by the parser
*/
%type <Ast.program> program
%%
program:
| INIT LPAREN xmin = FLOAT COMMA xmax = FLOAT COMMA ymin = FLOAT COMMA ymax = FLOAT RPAREN s = stmt EOF
{
((xmin, xmax, ymin, ymax), s)
}
stmt:
| TRANSLATION LPAREN x = FLOAT COMMA y = FLOAT RPAREN SEMICOLON
{ Translation (x, y) }
| ROTATION LPAREN x = FLOAT COMMA y = FLOAT COMMA theta = FLOAT RPAREN SEMICOLON
{ Rotation (x, y, theta) }
| s1 = stmt OR s2 = stmt weight = FLOAT
{ Or (s1, s2, weight) }
| ITER LPAREN it1 = INT COMMA it2 = INT RPAREN s = stmt
{ Iter (s, it1, it2) }
| BEGIN stmtList = stmt* END
{ StmtList stmtList }
;
\ No newline at end of file
open Parser
open Printf
(** UTF8 sequences for different symbols. *)
let lquote = "\xe2\x80\x98"
let rquote = "\xe2\x80\x98"
let rtriangle = "\xe2\x96\xb8"
let ltriangle = "\xe2\x97\x82"
(** [print_token out token] prints [token] on the out channel [out]. *)
let print_token out = function
| INIT ->
fprintf out "INIT"
| ITER ->
fprintf out "ITER"
| TRANSLATION ->
fprintf out "TRANSLATION"
| ROTATION ->
fprintf out "ROTATION"
| OR ->
fprintf out "OR"
| INT i ->
fprintf out "INTEGER %d" i
| FLOAT f ->
fprintf out "FLOAT %f" f
| IDENT id ->
fprintf out "IDENT %s%s%s" lquote id rquote
| COMMA ->
fprintf out "COMMA"
| SEMICOLON ->
fprintf out "SEMICOLON"
| LPAREN ->
fprintf out "LPAREN"
| RPAREN ->
fprintf out "RPAREN"
| BEGIN ->
fprintf out "BEGIN"
| END ->
fprintf out "END"
| EOF ->
fprintf out "EOF"
let print out lexbuf =
let token = ref (Lexer.get_token lexbuf) in
fprintf out "%a\n" (print_token) !token;
while !token <> EOF do
token := Lexer.get_token lexbuf;
fprintf out "%a\n" (print_token) !token
done
\ No newline at end of file
(*
Sample code provided by Pascalou the Mr. Cooder
Thank you Pascalou <3
*)
init(0,1,0,1) # Starting position (x,y) in [0,1]*[0,1]
iter(10,100) {
{
translation(1, 0);
}
or
{
rotation(0.5, 0.5);
}
}
\ No newline at end of file
type color =
| Black
| White
| Red
| Green
| Blue
type binop =
| Add
| Sub
| Mul
| Div
(*
Float range for XY coordinates
X between float1 and float2
Y between float3 and float4
*)
type init = float * float * float * float
type program = init * stmt
type stmt =
| Translation of float * float
| Rotation of float * float * float
| StmtList of stmt list
| Or of stmt * stmt * float (* Float is the left-member's random weightening *)
| Iter of stmt * int * int (* Min and max number of iteration *)
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment