init
This commit is contained in:
commit
7f6e51dfea
55
BE/ascendant/Lexer.mll
Executable file
55
BE/ascendant/Lexer.mll
Executable file
|
@ -0,0 +1,55 @@
|
||||||
|
{
|
||||||
|
|
||||||
|
(* Partie recopiée dans le fichier CaML généré. *)
|
||||||
|
(* Ouverture de modules exploités dans les actions *)
|
||||||
|
(* Déclarations de types, de constantes, de fonctions, d'exceptions exploités dans les actions *)
|
||||||
|
|
||||||
|
open Parser
|
||||||
|
exception LexicalError
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
(* Déclaration d'expressions régulières exploitées par la suite *)
|
||||||
|
let chiffre = ['0' - '9']
|
||||||
|
let entier = ['1' - '9']
|
||||||
|
let minuscule = ['a' - 'z']
|
||||||
|
let majuscule = ['A' - 'Z']
|
||||||
|
let alphabet = minuscule | majuscule
|
||||||
|
let alphanum = alphabet | chiffre | '_'
|
||||||
|
let commentaire =
|
||||||
|
(* Commentaire fin de ligne *)
|
||||||
|
"#" [^'\n']*
|
||||||
|
|
||||||
|
rule lexer = parse
|
||||||
|
| ['\n' '\t' ' ']+ { (lexer lexbuf) }
|
||||||
|
| commentaire { (lexer lexbuf) }
|
||||||
|
| "model" { UL_MODEL }
|
||||||
|
| "system" { UL_SYSTEM }
|
||||||
|
| "block" { UL_BLOCK }
|
||||||
|
| "flow" { UL_FLOW }
|
||||||
|
| "from" { UL_FROM }
|
||||||
|
| "to" { UL_TO }
|
||||||
|
| "in" { UL_IN }
|
||||||
|
| "out" { UL_OUT }
|
||||||
|
| "int" { UL_INT }
|
||||||
|
| "float" { UL_FLOAT }
|
||||||
|
| "boolean" { UL_BOOLEAN }
|
||||||
|
| "{" { UL_ACCOUV }
|
||||||
|
| "}" { UL_ACCFER }
|
||||||
|
| "(" { UL_PAROUV }
|
||||||
|
| ")" { UL_PARFER }
|
||||||
|
| "[" { UL_CROOUV }
|
||||||
|
| "]" { UL_CROFER }
|
||||||
|
| ";" { UL_PTV }
|
||||||
|
| "," { UL_VIRG }
|
||||||
|
| ":" { UL_PT2 }
|
||||||
|
| "." { UL_PT }
|
||||||
|
| eof { UL_FIN }
|
||||||
|
| majuscule alphabet* as texte { (UL_IDENT texte) }
|
||||||
|
| minuscule alphabet* as texte { (UL_PORT texte) }
|
||||||
|
| entier chiffre* as texte { (UL_ENTIER (int_of_string texte)) }
|
||||||
|
| _ as texte { (print_string "Erreur lexicale : ");(print_char texte);(print_newline ()); raise LexicalError }
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
52
BE/ascendant/MainSystem.ml
Executable file
52
BE/ascendant/MainSystem.ml
Executable file
|
@ -0,0 +1,52 @@
|
||||||
|
open Parser
|
||||||
|
|
||||||
|
(* Fonction d'affichage des unités lexicales et des données qu'elles contiennent *)
|
||||||
|
let printToken t =
|
||||||
|
(print_endline
|
||||||
|
(match t with
|
||||||
|
| UL_MODEL -> "model"
|
||||||
|
| UL_SYSTEM -> "system"
|
||||||
|
| UL_BLOCK -> "block"
|
||||||
|
| UL_FLOW -> "flow"
|
||||||
|
| UL_FROM -> "from"
|
||||||
|
| UL_TO -> "to"
|
||||||
|
| UL_IN -> "in"
|
||||||
|
| UL_OUT -> "out"
|
||||||
|
| UL_INT -> "int"
|
||||||
|
| UL_FLOAT -> "float"
|
||||||
|
| UL_BOOLEAN -> "boolean"
|
||||||
|
| UL_ACCOUV -> "{"
|
||||||
|
| UL_ACCFER -> "}"
|
||||||
|
| UL_PAROUV -> "("
|
||||||
|
| UL_PARFER -> ")"
|
||||||
|
| UL_CROOUV -> "["
|
||||||
|
| UL_CROFER -> "]"
|
||||||
|
| UL_PTV -> ";"
|
||||||
|
| UL_VIRG -> ","
|
||||||
|
| UL_PT2 -> ":"
|
||||||
|
| UL_PT -> "."
|
||||||
|
| UL_IDENT texte -> texte
|
||||||
|
| UL_PORT texte -> texte
|
||||||
|
| UL_ENTIER texte -> (string_of_int texte)
|
||||||
|
| UL_FIN -> "EOF"
|
||||||
|
));;
|
||||||
|
|
||||||
|
(* Analyse lexicale du fichier passé en paramètre de la ligne de commande *)
|
||||||
|
if (Array.length Sys.argv > 1)
|
||||||
|
then
|
||||||
|
let lexbuf = (Lexing.from_channel (open_in Sys.argv.(1))) in
|
||||||
|
let token = ref (Lexer.lexer lexbuf) in
|
||||||
|
while ((!token) != UL_FIN) do
|
||||||
|
(printToken (!token));
|
||||||
|
(token := (Lexer.lexer lexbuf))
|
||||||
|
done
|
||||||
|
else
|
||||||
|
(print_endline "MainJSON fichier");;
|
||||||
|
|
||||||
|
(* Analyse lexicale, syntaxique et sémantique du fichier passé en paramètre de la ligne de commande *)
|
||||||
|
if (Array.length Sys.argv > 1)
|
||||||
|
then
|
||||||
|
let lexbuf = (Lexing.from_channel (open_in Sys.argv.(1))) in
|
||||||
|
(Parser.modele Lexer.lexer lexbuf)
|
||||||
|
else
|
||||||
|
(print_endline "MainJSON fichier");;
|
88
BE/ascendant/Parser.mly
Executable file
88
BE/ascendant/Parser.mly
Executable file
|
@ -0,0 +1,88 @@
|
||||||
|
%{
|
||||||
|
|
||||||
|
(* Partie recopiee dans le fichier CaML genere. *)
|
||||||
|
(* Ouverture de modules exploites dans les actions *)
|
||||||
|
(* Declarations de types, de constantes, de fonctions, d'exceptions exploites dans les actions *)
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
/* Declaration des unites lexicales et de leur type si une valeur particuliere leur est associee */
|
||||||
|
|
||||||
|
%token UL_MODEL
|
||||||
|
%token UL_ACCOUV UL_ACCFER
|
||||||
|
%token UL_SYSTEM
|
||||||
|
%token UL_BLOCK
|
||||||
|
%token UL_FLOW UL_FROM UL_TO
|
||||||
|
%token UL_IN UL_OUT
|
||||||
|
%token UL_INT UL_FLOAT UL_BOOLEAN
|
||||||
|
%token UL_PAROUV UL_PARFER
|
||||||
|
%token UL_CROOUV UL_CROFER
|
||||||
|
%token UL_PTV UL_VIRG UL_PT2 UL_PT
|
||||||
|
|
||||||
|
/* Defini le type des donnees associees a l'unite lexicale */
|
||||||
|
|
||||||
|
%token <string> UL_IDENT
|
||||||
|
%token <string> UL_PORT
|
||||||
|
%token <int> UL_ENTIER
|
||||||
|
|
||||||
|
/* Unite lexicale particuliere qui represente la fin du fichier */
|
||||||
|
|
||||||
|
%token UL_FIN
|
||||||
|
|
||||||
|
/* Type renvoye pour le nom terminal document */
|
||||||
|
%type <unit> modele
|
||||||
|
|
||||||
|
/* Le non terminal document est l'axiome */
|
||||||
|
%start modele
|
||||||
|
|
||||||
|
%% /* Regles de productions */
|
||||||
|
|
||||||
|
modele : UL_MODEL UL_IDENT UL_ACCOUV loop_element UL_ACCFER UL_FIN { (print_endline "modele : UL_MODEL IDENT { loop_element } UL_FIN ") }
|
||||||
|
|
||||||
|
element : bloc { (print_endline "element : bloc") }
|
||||||
|
| systeme { (print_endline "element : systeme") }
|
||||||
|
| flot { (print_endline "element : flot") }
|
||||||
|
|
||||||
|
loop_element : /* Lambda */ { (print_endline "loop_element : /* Lambda */") }
|
||||||
|
| element loop_element { (print_endline "loop_element : element loop_element") }
|
||||||
|
|
||||||
|
bloc : UL_BLOCK UL_IDENT parametres UL_PTV { (print_endline "bloc : UL_BLOCK UL_IDENT parametres UL_PTV") }
|
||||||
|
|
||||||
|
systeme : UL_SYSTEM UL_IDENT parametres UL_ACCOUV loop_element UL_ACCFER { (print_endline "systeme : UL_SYSTEM UL_IDENT parametres UL_ACCOUV loop_element UL_ACCFER") }
|
||||||
|
|
||||||
|
parametres : UL_PAROUV port loop_port UL_PARFER { (print_endline "parametres : UL_PAROUV port loop_port UL_PARFER") }
|
||||||
|
|
||||||
|
loop_port : /* Lambda */ { (print_endline "loop_port : /* Lambda */") }
|
||||||
|
| UL_VIRG port loop_port { (print_endline "loop_port : UL_VIRG port loop_port") }
|
||||||
|
|
||||||
|
port : UL_PORT UL_PT2 in_or_out type_ { (print_endline "port : UL_PORT UL_PT2 in_or_out type_") }
|
||||||
|
|
||||||
|
in_or_out : UL_IN { (print_endline "in_or_out : UL_IN") }
|
||||||
|
| UL_OUT { (print_endline "in_or_out : UL_OUT") }
|
||||||
|
|
||||||
|
type_ : select_type option_entiers { (print_endline "type_ : select_type option_entiers") }
|
||||||
|
|
||||||
|
select_type : UL_INT { (print_endline "select_type : UL_INT") }
|
||||||
|
| UL_FLOAT { (print_endline "select_type : UL_FLOAT") }
|
||||||
|
| UL_BOOLEAN { (print_endline "select_type : UL_BOOLEAN") }
|
||||||
|
|
||||||
|
option_entiers : /* Lambda */ { (print_endline "option_entiers : /* Lambda */") }
|
||||||
|
| UL_CROOUV UL_ENTIER loop_entier UL_CROFER { (print_endline "option_entiers : UL_CROOUV UL_ENTIER loop_entier UL_CROFER") }
|
||||||
|
|
||||||
|
loop_entier : /* Lambda */ { (print_endline "loop_entier : /* Lambda */") }
|
||||||
|
| UL_VIRG UL_ENTIER loop_entier { (print_endline "loop_entier : UL_VIRG UL_ENTIER loop_entier") }
|
||||||
|
|
||||||
|
flot : UL_FLOW UL_PORT UL_FROM option_ident UL_PORT UL_TO option_loop_ident_port UL_PTV { (print_endline "flot : UL_FLOW UL_PORT UL_FROM option_ident UL_PORT UL_TO option_loop_ident_port UL_PTV") }
|
||||||
|
|
||||||
|
option_ident : /* Lambda */ { (print_endline "option_ident : /* Lambda */") }
|
||||||
|
| UL_IDENT UL_PT { (print_endline "option_ident : UL_IDENT UL_PT") }
|
||||||
|
|
||||||
|
ident_port : option_ident UL_PORT { (print_endline "ident_port : option_ident UL_PORT") }
|
||||||
|
|
||||||
|
loop_ident_port : /* Lambda */ { (print_endline "loop_ident_port : /* Lambda */") }
|
||||||
|
| UL_VIRG ident_port loop_ident_port { (print_endline "loop_ident_port : UL_IDENT UL_PT") }
|
||||||
|
|
||||||
|
option_loop_ident_port : /* Lambda */ { (print_endline "option_loop_ident_port : /* Lambda */") }
|
||||||
|
| ident_port loop_ident_port { (print_endline "option_loop_ident_port : ident_port loop_ident_port") }
|
||||||
|
|
||||||
|
%%
|
7
BE/ascendant/dune
Executable file
7
BE/ascendant/dune
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
(ocamllex Lexer)
|
||||||
|
|
||||||
|
(menhir
|
||||||
|
(modules Parser))
|
||||||
|
|
||||||
|
(executable
|
||||||
|
(name MainSystem))
|
2
BE/ascendant/dune-project
Executable file
2
BE/ascendant/dune-project
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
(lang dune 2.9)
|
||||||
|
(using menhir 2.1)
|
25
BE/descendant/MainSystem.ml
Executable file
25
BE/descendant/MainSystem.ml
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
open Tokens
|
||||||
|
open Scanner
|
||||||
|
open Parser
|
||||||
|
|
||||||
|
(* main : unit -> unit *)
|
||||||
|
(* Analyse le contenu d'un fichier passé en paramètre ou l'entrée standard si aucun fichier n'est donné *)
|
||||||
|
(* Affiche OK si l'analyse syntaxique c'est bien passée et KO sinon *)
|
||||||
|
let main () =
|
||||||
|
let cin =
|
||||||
|
if Array.length Sys.argv > 1 then
|
||||||
|
open_in Sys.argv.(1)
|
||||||
|
else
|
||||||
|
stdin
|
||||||
|
in
|
||||||
|
let lexbuf = Lexing.from_channel cin in
|
||||||
|
let tokens = (scanner lexbuf) in
|
||||||
|
(print_endline ("Résultat de l'analyse lexicale :" ^ (string_of_stream tokens)));
|
||||||
|
(print_endline "Analyse syntaxique par descente récursive, règles appliquées :");
|
||||||
|
(match (parseR tokens)
|
||||||
|
with
|
||||||
|
| Success [UL_FIN] -> print_endline "Succés"
|
||||||
|
| _ -> print_endline "Echec")
|
||||||
|
;;
|
||||||
|
|
||||||
|
main();;
|
303
BE/descendant/Parser.ml
Executable file
303
BE/descendant/Parser.ml
Executable file
|
@ -0,0 +1,303 @@
|
||||||
|
open Tokens
|
||||||
|
|
||||||
|
(* Type du résultat d'une analyse syntaxique *)
|
||||||
|
type parseResult =
|
||||||
|
| Success of inputStream
|
||||||
|
| Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* accept : token -> inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien le token attendu *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let accept expected stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| token when (token = expected) ->
|
||||||
|
(Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* acceptIdent : inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien un identifiant *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let acceptIdent stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| (UL_IDENT _) -> (Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* acceptPort : inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien un port *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let acceptPort stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| (UL_PORT _) -> (Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* acceptEntier : inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien un entier *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let acceptEntier stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| (UL_ENTIER _) -> (Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* Définition de la monade qui est composée de : *)
|
||||||
|
(* - le type de donnée monadique : parseResult *)
|
||||||
|
(* - la fonction : inject qui construit ce type à partir d'une liste de terminaux *)
|
||||||
|
(* - la fonction : bind (opérateur >>=) qui combine les fonctions d'analyse. *)
|
||||||
|
|
||||||
|
(* inject inputStream -> parseResult *)
|
||||||
|
(* Construit le type de la monade à partir d'une liste de terminaux *)
|
||||||
|
let inject s = Success s;;
|
||||||
|
|
||||||
|
(* bind : 'a m -> ('a -> 'b m) -> 'b m *)
|
||||||
|
(* bind (opérateur >>=) qui combine les fonctions d'analyse. *)
|
||||||
|
(* ici on utilise une version spécialisée de bind :
|
||||||
|
'b -> inputStream
|
||||||
|
'a -> inputStream
|
||||||
|
m -> parseResult
|
||||||
|
*)
|
||||||
|
(* >>= : parseResult -> (inputStream -> parseResult) -> parseResult *)
|
||||||
|
let (>>=) result f =
|
||||||
|
match result with
|
||||||
|
| Success next -> f next
|
||||||
|
| Failure -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
|
||||||
|
(* parseR : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal Programme *)
|
||||||
|
let rec parseR stream =
|
||||||
|
(print_string "R");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 1. R -> model Ident { SE } *)
|
||||||
|
| UL_MODEL ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_MODEL >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
accept UL_ACCOUV >>=
|
||||||
|
parseSE >>=
|
||||||
|
accept UL_ACCFER
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseSE : inputStream -> parseResult *)
|
||||||
|
and parseSE stream =
|
||||||
|
(print_endline "SE");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 2. SE -> Λ *)
|
||||||
|
| UL_ACCFER ->
|
||||||
|
inject stream
|
||||||
|
(* 3. SE -> E SE *)
|
||||||
|
| ( UL_BLOCK | UL_SYSTEM | UL_FLOW ) ->
|
||||||
|
inject stream >>=
|
||||||
|
parseE >>=
|
||||||
|
parseSE
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseE : inputStream -> parseResult *)
|
||||||
|
and parseE stream =
|
||||||
|
(print_endline "E");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 4. E -> block Ident P ; *)
|
||||||
|
| UL_BLOCK ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_BLOCK >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
parseP >>=
|
||||||
|
accept UL_PTV
|
||||||
|
(* 5. E -> system Ident P { SE } *)
|
||||||
|
| UL_SYSTEM ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_SYSTEM >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
parseP >>=
|
||||||
|
accept UL_ACCOUV >>=
|
||||||
|
parseSE >>=
|
||||||
|
accept UL_ACCFER
|
||||||
|
(* 6. E -> flow ident from NQ to LN ; *)
|
||||||
|
| UL_FLOW ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_FLOW >>=
|
||||||
|
acceptPort >>=
|
||||||
|
accept UL_FROM >>=
|
||||||
|
parseNQ >>=
|
||||||
|
accept UL_TO >>=
|
||||||
|
parseLN >>=
|
||||||
|
accept UL_PTV
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseNQ : inputStream -> parseResult *)
|
||||||
|
and parseNQ stream =
|
||||||
|
(print_endline "NQ");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 7. NQ -> ident *)
|
||||||
|
| (UL_PORT _) ->
|
||||||
|
inject stream >>=
|
||||||
|
acceptPort
|
||||||
|
(* 8. NQ -> Ident . ident *)
|
||||||
|
| (UL_IDENT _) ->
|
||||||
|
inject stream >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
accept UL_PT >>=
|
||||||
|
acceptPort
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseLN : inputStream -> parseResult *)
|
||||||
|
and parseLN stream =
|
||||||
|
(print_endline "LN");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 9. LN -> Λ *)
|
||||||
|
| UL_PTV ->
|
||||||
|
inject stream
|
||||||
|
(* 10. LN -> NQ SN *)
|
||||||
|
| ( (UL_IDENT _) | (UL_PORT _) ) ->
|
||||||
|
inject stream >>=
|
||||||
|
parseNQ >>=
|
||||||
|
parseSN
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseSN : inputStream -> parseResult *)
|
||||||
|
and parseSN stream =
|
||||||
|
(print_endline "SN");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 11. SN -> Λ *)
|
||||||
|
| UL_PTV ->
|
||||||
|
inject stream
|
||||||
|
(* 12. LN -> , NQ SN *)
|
||||||
|
| UL_VIRG ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_VIRG >>=
|
||||||
|
parseNQ >>=
|
||||||
|
parseSN
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseP : inputStream -> parseResult *)
|
||||||
|
and parseP stream =
|
||||||
|
(print_endline "P");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 13. P -> ( LP ) *)
|
||||||
|
| UL_PAROUV ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_PAROUV >>=
|
||||||
|
parseLP >>=
|
||||||
|
accept UL_PARFER
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseLP : inputStream -> parseResult *)
|
||||||
|
and parseLP stream =
|
||||||
|
(print_endline "LP");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 14. LP -> DP SP *)
|
||||||
|
| (UL_PORT _) ->
|
||||||
|
inject stream >>=
|
||||||
|
parseDP >>=
|
||||||
|
parseSP
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseSP : inputStream -> parseResult *)
|
||||||
|
and parseSP stream =
|
||||||
|
(print_endline "SP");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 15. SP -> Λ *)
|
||||||
|
| UL_PARFER ->
|
||||||
|
inject stream
|
||||||
|
(* 16. LN -> , DP SP *)
|
||||||
|
| UL_VIRG ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_VIRG >>=
|
||||||
|
parseDP >>=
|
||||||
|
parseSP
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseDP : inputStream -> parseResult *)
|
||||||
|
and parseDP stream =
|
||||||
|
(print_endline "DP");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 17. LP -> ident : M T OT *)
|
||||||
|
| (UL_PORT _) ->
|
||||||
|
inject stream >>=
|
||||||
|
acceptPort >>=
|
||||||
|
accept UL_PT2 >>=
|
||||||
|
parseM >>=
|
||||||
|
parseT >>=
|
||||||
|
parseOT
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseM : inputStream -> parseResult *)
|
||||||
|
and parseM stream =
|
||||||
|
(print_endline "M");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 18. M -> in *)
|
||||||
|
| UL_IN ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_IN
|
||||||
|
(* 19. M -> out *)
|
||||||
|
| UL_OUT ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_OUT
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseT : inputStream -> parseResult *)
|
||||||
|
and parseT stream =
|
||||||
|
(print_endline "T");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 20. T -> int *)
|
||||||
|
| UL_INT ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_INT
|
||||||
|
(* 21. M -> float *)
|
||||||
|
| UL_FLOAT ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_FLOAT
|
||||||
|
(* 22. M -> boolean *)
|
||||||
|
| UL_BOOLEAN ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_BOOLEAN
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseOT : inputStream -> parseResult *)
|
||||||
|
and parseOT stream =
|
||||||
|
(print_endline "OT");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 23. OT -> Λ *)
|
||||||
|
| ( UL_VIRG | UL_PARFER ) ->
|
||||||
|
inject stream
|
||||||
|
(* 24. OT -> [ entier SV ] *)
|
||||||
|
| UL_CROOUV ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_CROOUV >>=
|
||||||
|
acceptEntier >>=
|
||||||
|
parseSV >>=
|
||||||
|
accept UL_CROFER
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseSV : inputStream -> parseResult *)
|
||||||
|
and parseSV stream =
|
||||||
|
(print_endline "SV");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 25. OT -> Λ *)
|
||||||
|
| UL_CROFER ->
|
||||||
|
inject stream
|
||||||
|
(* 26. OT -> , entier SV *)
|
||||||
|
| UL_VIRG ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_VIRG >>=
|
||||||
|
acceptEntier >>=
|
||||||
|
parseSV
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
55
BE/descendant/Scanner.mll
Executable file
55
BE/descendant/Scanner.mll
Executable file
|
@ -0,0 +1,55 @@
|
||||||
|
{
|
||||||
|
|
||||||
|
(* Partie recopiée dans le fichier CaML généré. *)
|
||||||
|
(* Ouverture de modules exploités dans les actions *)
|
||||||
|
(* Déclarations de types, de constantes, de fonctions, d'exceptions exploités dans les actions *)
|
||||||
|
|
||||||
|
open Tokens
|
||||||
|
exception Printf
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
(* Déclaration d'expressions régulières exploitées par la suite *)
|
||||||
|
let chiffre = ['0' - '9']
|
||||||
|
let entier = ['1' - '9']
|
||||||
|
let minuscule = ['a' - 'z']
|
||||||
|
let majuscule = ['A' - 'Z']
|
||||||
|
let alphabet = minuscule | majuscule
|
||||||
|
let alphanum = alphabet | chiffre | '_'
|
||||||
|
let commentaire =
|
||||||
|
(* Commentaire fin de ligne *)
|
||||||
|
"#" [^'\n']*
|
||||||
|
|
||||||
|
rule scanner = parse
|
||||||
|
| ['\n' '\t' ' ']+ { (scanner lexbuf) }
|
||||||
|
| commentaire { (scanner lexbuf) }
|
||||||
|
| "model" { UL_MODEL::(scanner lexbuf) }
|
||||||
|
| "system" { UL_SYSTEM::(scanner lexbuf) }
|
||||||
|
| "block" { UL_BLOCK::(scanner lexbuf) }
|
||||||
|
| "flow" { UL_FLOW::(scanner lexbuf) }
|
||||||
|
| "from" { UL_FROM::(scanner lexbuf) }
|
||||||
|
| "to" { UL_TO::(scanner lexbuf) }
|
||||||
|
| "in" { UL_IN::(scanner lexbuf) }
|
||||||
|
| "out" { UL_OUT::(scanner lexbuf) }
|
||||||
|
| "int" { UL_INT::(scanner lexbuf) }
|
||||||
|
| "float" { UL_FLOAT::(scanner lexbuf) }
|
||||||
|
| "boolean" { UL_BOOLEAN::(scanner lexbuf) }
|
||||||
|
| "{" { UL_ACCOUV::(scanner lexbuf) }
|
||||||
|
| "}" { UL_ACCFER::(scanner lexbuf) }
|
||||||
|
| "(" { UL_PAROUV::(scanner lexbuf) }
|
||||||
|
| ")" { UL_PARFER::(scanner lexbuf) }
|
||||||
|
| "[" { UL_CROOUV::(scanner lexbuf) }
|
||||||
|
| "]" { UL_CROFER::(scanner lexbuf) }
|
||||||
|
| ";" { UL_PTV::(scanner lexbuf) }
|
||||||
|
| "," { UL_VIRG::(scanner lexbuf) }
|
||||||
|
| ":" { UL_PT2::(scanner lexbuf) }
|
||||||
|
| "." { UL_PT::(scanner lexbuf) }
|
||||||
|
| majuscule alphabet* as texte { (UL_IDENT texte)::(scanner lexbuf) }
|
||||||
|
| minuscule alphabet* as texte { (UL_PORT texte)::(scanner lexbuf) }
|
||||||
|
| entier chiffre* as texte { (UL_ENTIER (int_of_string texte))::(scanner lexbuf) }
|
||||||
|
| eof { [UL_FIN] }
|
||||||
|
| _ as texte { (print_string "Erreur lexicale : ");(print_char texte);(print_newline ()); (UL_ERREUR::(scanner lexbuf)) }
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
88
BE/descendant/Tokens.ml
Executable file
88
BE/descendant/Tokens.ml
Executable file
|
@ -0,0 +1,88 @@
|
||||||
|
open List
|
||||||
|
|
||||||
|
type token =
|
||||||
|
| UL_MODEL
|
||||||
|
| UL_SYSTEM
|
||||||
|
| UL_BLOCK
|
||||||
|
| UL_FLOW
|
||||||
|
| UL_FROM
|
||||||
|
| UL_TO
|
||||||
|
| UL_IN
|
||||||
|
| UL_OUT
|
||||||
|
| UL_INT
|
||||||
|
| UL_FLOAT
|
||||||
|
| UL_BOOLEAN
|
||||||
|
| UL_ACCOUV
|
||||||
|
| UL_ACCFER
|
||||||
|
| UL_PAROUV
|
||||||
|
| UL_PARFER
|
||||||
|
| UL_CROOUV
|
||||||
|
| UL_CROFER
|
||||||
|
| UL_PTV
|
||||||
|
| UL_VIRG
|
||||||
|
| UL_PT2
|
||||||
|
| UL_PT
|
||||||
|
| UL_IDENT of string
|
||||||
|
| UL_PORT of string
|
||||||
|
| UL_ENTIER of int
|
||||||
|
| UL_FIN
|
||||||
|
| UL_ERREUR;;
|
||||||
|
|
||||||
|
type inputStream = token list;;
|
||||||
|
|
||||||
|
(* string_of_token : token -> string *)
|
||||||
|
(* Converti un token en une chaîne de caractère*)
|
||||||
|
let string_of_token token =
|
||||||
|
match token with
|
||||||
|
| UL_MODEL -> "model"
|
||||||
|
| UL_SYSTEM -> "system"
|
||||||
|
| UL_BLOCK -> "block"
|
||||||
|
| UL_FLOW -> "flow"
|
||||||
|
| UL_FROM -> "from"
|
||||||
|
| UL_TO -> "to"
|
||||||
|
| UL_IN -> "in"
|
||||||
|
| UL_OUT -> "out"
|
||||||
|
| UL_INT -> "int"
|
||||||
|
| UL_FLOAT -> "float"
|
||||||
|
| UL_BOOLEAN -> "boolean"
|
||||||
|
| UL_ACCOUV -> "{"
|
||||||
|
| UL_ACCFER -> "}"
|
||||||
|
| UL_PAROUV -> "("
|
||||||
|
| UL_PARFER -> ")"
|
||||||
|
| UL_CROOUV -> "["
|
||||||
|
| UL_CROFER -> "]"
|
||||||
|
| UL_PTV -> ";"
|
||||||
|
| UL_VIRG -> ","
|
||||||
|
| UL_PT2 -> ":"
|
||||||
|
| UL_PT -> "."
|
||||||
|
| UL_IDENT texte -> texte
|
||||||
|
| UL_PORT texte -> texte
|
||||||
|
| UL_ENTIER texte -> (string_of_int texte)
|
||||||
|
| UL_FIN -> "EOF"
|
||||||
|
| UL_ERREUR -> "Erreur Lexicale";;
|
||||||
|
|
||||||
|
(* string_of_stream : inputStream -> string *)
|
||||||
|
(* Converti un inputStream (liste de token) en une chaîne de caractère *)
|
||||||
|
let string_of_stream stream =
|
||||||
|
List.fold_right (fun t tq -> (string_of_token t) ^ " " ^ tq ) stream "";;
|
||||||
|
|
||||||
|
|
||||||
|
(* peekAtFirstToken : inputStream -> token *)
|
||||||
|
(* Renvoie le premier élément d'un inputStream *)
|
||||||
|
(* Erreur : si l'inputStream est vide *)
|
||||||
|
let peekAtFirstToken stream =
|
||||||
|
match stream with
|
||||||
|
(* Normalement, ne doit jamais se produire sauf si la grammaire essaie de lire *)
|
||||||
|
(* après la fin de l'inputStream. *)
|
||||||
|
| [] -> failwith "Impossible d'acceder au premier element d'un inputStream vide"
|
||||||
|
|t::_ -> t;;
|
||||||
|
|
||||||
|
(* advanceInStream : inputStream -> inputStream *)
|
||||||
|
(* Consomme le premier élément d'un inputStream *)
|
||||||
|
(* Erreur : si l'inputStream est vide *)
|
||||||
|
let advanceInStream stream =
|
||||||
|
match stream with
|
||||||
|
(* Normalement, ne doit jamais se produire sauf si la grammaire essaie de lire *)
|
||||||
|
(* après la fin de l'inputStream. *)
|
||||||
|
| [] -> failwith "Impossible de consommer le premier element d'un inputStream vide"
|
||||||
|
| _::q -> q;;
|
4
BE/descendant/dune
Executable file
4
BE/descendant/dune
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
(ocamllex Scanner)
|
||||||
|
|
||||||
|
(executables
|
||||||
|
(names MainSystem))
|
1
BE/descendant/dune-project
Executable file
1
BE/descendant/dune-project
Executable file
|
@ -0,0 +1 @@
|
||||||
|
(lang dune 2.9)
|
11
BE/tests/sujet.sdl
Executable file
11
BE/tests/sujet.sdl
Executable file
|
@ -0,0 +1,11 @@
|
||||||
|
model S {
|
||||||
|
flow f from Ba.ra to HS.pa, HS.pb;
|
||||||
|
block Ba(pa : in float, pb : in float, ra : out float [ 2 ] );
|
||||||
|
system HS(pa : in float [ 2 ], ra : out float, pb : in float [ 2 ] , rb : out float [ 2 ] ) {
|
||||||
|
block Bb(ra : out float, pa : in float);
|
||||||
|
flow fa from pa to Bb.pa;
|
||||||
|
flow fb from pb to rb;
|
||||||
|
}
|
||||||
|
flow fb from HS.ra to Ba.pa, Ba.pb;
|
||||||
|
flow fc from HS.rb to;
|
||||||
|
}
|
43
BE_2020_2021/ascendant/Lexer.mll
Executable file
43
BE_2020_2021/ascendant/Lexer.mll
Executable file
|
@ -0,0 +1,43 @@
|
||||||
|
{
|
||||||
|
|
||||||
|
(* Partie recopiée dans le fichier CaML généré. *)
|
||||||
|
(* Ouverture de modules exploités dans les actions *)
|
||||||
|
(* Déclarations de types, de constantes, de fonctions, d'exceptions exploités dans les actions *)
|
||||||
|
|
||||||
|
open Parser
|
||||||
|
exception LexicalError
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
(* Déclaration d'expressions régulières exploitées par la suite *)
|
||||||
|
let chiffre = ['0' - '9']
|
||||||
|
let minuscule = ['a' - 'z']
|
||||||
|
let majuscule = ['A' - 'Z']
|
||||||
|
let alphabet = minuscule | majuscule
|
||||||
|
let alphanum = alphabet | chiffre | '_'
|
||||||
|
let commentaire =
|
||||||
|
(* Commentaire fin de ligne *)
|
||||||
|
"#" [^'\n']*
|
||||||
|
|
||||||
|
rule lexer = parse
|
||||||
|
| ['\n' '\t' ' ']+ { (lexer lexbuf) }
|
||||||
|
| commentaire { (lexer lexbuf) }
|
||||||
|
| "{" { UL_ACCOUV }
|
||||||
|
| "}" { UL_ACCFER }
|
||||||
|
| "." { UL_PT }
|
||||||
|
| "machine" { UL_MACHINE }
|
||||||
|
| "to" { UL_TO }
|
||||||
|
| "on" { UL_ON }
|
||||||
|
| "event" { UL_EVENT }
|
||||||
|
| "from" { UL_FROM }
|
||||||
|
| "region" { UL_REGION }
|
||||||
|
| "ends" { UL_ENDS }
|
||||||
|
| "starts" { UL_STARTS }
|
||||||
|
| "state" { UL_STATE }
|
||||||
|
| eof { UL_FIN }
|
||||||
|
| alphabet+ as texte { (UL_IDENT texte) }
|
||||||
|
| _ as texte { (print_string "Erreur lexicale : ");(print_char texte);(print_newline ()); raise LexicalError }
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
41
BE_2020_2021/ascendant/MainMachine.ml
Executable file
41
BE_2020_2021/ascendant/MainMachine.ml
Executable file
|
@ -0,0 +1,41 @@
|
||||||
|
open Parser
|
||||||
|
|
||||||
|
(* Fonction d'affichage des unités lexicales et des données qu'elles contiennent *)
|
||||||
|
let printToken t =
|
||||||
|
(print_endline
|
||||||
|
(match t with
|
||||||
|
| UL_IDENT (texte) -> texte
|
||||||
|
| UL_ACCOUV -> "{"
|
||||||
|
| UL_ACCFER -> "}"
|
||||||
|
| UL_PT -> "."
|
||||||
|
| UL_MACHINE -> "machine"
|
||||||
|
| UL_TO -> "to"
|
||||||
|
| UL_ON -> "on"
|
||||||
|
| UL_EVENT -> "event"
|
||||||
|
| UL_FROM -> "from"
|
||||||
|
| UL_REGION -> "region"
|
||||||
|
| UL_ENDS -> "ends"
|
||||||
|
| UL_STARTS -> "starts"
|
||||||
|
| UL_STATE -> "state"
|
||||||
|
| UL_FIN -> "EOF"
|
||||||
|
));;
|
||||||
|
|
||||||
|
(* Analyse lexicale du fichier passé en paramètre de la ligne de commande *)
|
||||||
|
if (Array.length Sys.argv > 1)
|
||||||
|
then
|
||||||
|
let lexbuf = (Lexing.from_channel (open_in Sys.argv.(1))) in
|
||||||
|
let token = ref (Lexer.lexer lexbuf) in
|
||||||
|
while ((!token) != UL_FIN) do
|
||||||
|
(printToken (!token));
|
||||||
|
(token := (Lexer.lexer lexbuf))
|
||||||
|
done
|
||||||
|
else
|
||||||
|
(print_endline "MainJSON fichier");;
|
||||||
|
|
||||||
|
(* Analyse lexicale, syntaxique et sémantique du fichier passé en paramètre de la ligne de commande *)
|
||||||
|
if (Array.length Sys.argv > 1)
|
||||||
|
then
|
||||||
|
let lexbuf = (Lexing.from_channel (open_in Sys.argv.(1))) in
|
||||||
|
(Parser.machine Lexer.lexer lexbuf)
|
||||||
|
else
|
||||||
|
(print_endline "MainJSON fichier");;
|
71
BE_2020_2021/ascendant/Parser.mly
Executable file
71
BE_2020_2021/ascendant/Parser.mly
Executable file
|
@ -0,0 +1,71 @@
|
||||||
|
%{
|
||||||
|
|
||||||
|
(* Partie recopiee dans le fichier CaML genere. *)
|
||||||
|
(* Ouverture de modules exploites dans les actions *)
|
||||||
|
(* Declarations de types, de constantes, de fonctions, d'exceptions exploites dans les actions *)
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
/* Declaration des unites lexicales et de leur type si une valeur particuliere leur est associee */
|
||||||
|
|
||||||
|
%token UL_MACHINE
|
||||||
|
%token UL_ACCOUV UL_ACCFER
|
||||||
|
%token UL_FROM UL_TO UL_ON
|
||||||
|
%token UL_STARTS UL_ENDS
|
||||||
|
%token UL_REGION
|
||||||
|
%token UL_STATE
|
||||||
|
%token UL_EVENT
|
||||||
|
%token UL_PT
|
||||||
|
|
||||||
|
/* Defini le type des donnees associees a l'unite lexicale */
|
||||||
|
|
||||||
|
%token <string> UL_IDENT
|
||||||
|
|
||||||
|
/* Unite lexicale particuliere qui represente la fin du fichier */
|
||||||
|
|
||||||
|
%token UL_FIN
|
||||||
|
|
||||||
|
/* Type renvoye pour le nom terminal document */
|
||||||
|
%type <unit> machine
|
||||||
|
|
||||||
|
/* Le non terminal document est l'axiome */
|
||||||
|
%start machine
|
||||||
|
|
||||||
|
%% /* Regles de productions */
|
||||||
|
|
||||||
|
machine : UL_MACHINE UL_IDENT UL_ACCOUV loop_composant UL_ACCFER UL_FIN { (print_endline "machine : MACHINE IDENT ACCOUV loop_composant ACCFER FIN") }
|
||||||
|
|
||||||
|
composant : UL_EVENT UL_IDENT { (print_endline "composant : EVENT IDENT") }
|
||||||
|
| transition { (print_endline "composant : transition") }
|
||||||
|
| region { (print_endline "composant : region") }
|
||||||
|
|
||||||
|
transition : UL_FROM nom_qualifie UL_TO nom_qualifie UL_ON UL_IDENT { (print_endline "transition : FROM nom_qualifie TO nom_qualifie ON IDENT") }
|
||||||
|
|
||||||
|
nom_qualifie : UL_IDENT loop_nom_qualfie { (print_endline "nom_qualifie : IDENT loop_nom_qualifie") }
|
||||||
|
|
||||||
|
etat : UL_STATE UL_IDENT option_starts option_ends option_regions { (print_endline "etat : STATE IDENT option_starts option_ends option_regions") }
|
||||||
|
|
||||||
|
region : UL_REGION UL_IDENT UL_ACCOUV etat loop_etat UL_ACCFER { (print_endline "region : REGION IDENT ACCOUV etat loop_etat ACCFER") }
|
||||||
|
|
||||||
|
loop_composant : /* Lambda, mot vide */ { (print_endline "loop_composant : /* Lambda, mot vide */") }
|
||||||
|
| composant loop_composant { (print_endline "loop_composant : composant loop_composant") }
|
||||||
|
|
||||||
|
loop_nom_qualfie : /* Lambda, mot vide */ { (print_endline "loop_nom_qualifie : /* Lambda, mot vide */") }
|
||||||
|
| UL_PT UL_IDENT loop_nom_qualfie { (print_endline "loop_nom_qualifie : PT IDENT loop_nom_qualifie") }
|
||||||
|
|
||||||
|
loop_etat : /* Lambda, mot vide */ { (print_endline "loop_etat : /* Lambda, mot vide */") }
|
||||||
|
| etat loop_etat { (print_endline "loop_etat : etat loop_etat") }
|
||||||
|
|
||||||
|
loop_region : /* Lambda, mot vide */ { (print_endline "loop_region : /* Lambda, mot vide */") }
|
||||||
|
| region loop_region { (print_endline "loop_region : region loop_region") }
|
||||||
|
|
||||||
|
option_starts : /* Lambda, mot vide */ { (print_endline "option_starts : /* Lambda, mot vide */") }
|
||||||
|
| UL_STARTS { (print_endline "option_starts : STARTS") }
|
||||||
|
|
||||||
|
option_ends : /* Lambda, mot vide */ { (print_endline "option_ends : /* Lambda, mot vide */") }
|
||||||
|
| UL_ENDS { (print_endline "option_ends : ENDS") }
|
||||||
|
|
||||||
|
option_regions : /* Lambda, mot vide */ { (print_endline "option_regions : /* Lambda, mot vide */") }
|
||||||
|
| UL_ACCOUV region loop_region UL_ACCFER { (print_endline "option_regions : ACCOUV region loop_region ACCFER") }
|
||||||
|
|
||||||
|
%%
|
7
BE_2020_2021/ascendant/dune
Executable file
7
BE_2020_2021/ascendant/dune
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
(ocamllex Lexer)
|
||||||
|
|
||||||
|
(menhir
|
||||||
|
(modules Parser))
|
||||||
|
|
||||||
|
(executable
|
||||||
|
(name MainMachine))
|
2
BE_2020_2021/ascendant/dune-project
Executable file
2
BE_2020_2021/ascendant/dune-project
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
(lang dune 2.9)
|
||||||
|
(using menhir 2.1)
|
25
BE_2020_2021/descendant/MainMachine.ml
Executable file
25
BE_2020_2021/descendant/MainMachine.ml
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
open Tokens
|
||||||
|
open Scanner
|
||||||
|
open Parser
|
||||||
|
|
||||||
|
(* main : unit -> unit *)
|
||||||
|
(* Analyse le contenu d'un fichier passé en paramètre ou l'entrée standard si aucun fichier n'est donné *)
|
||||||
|
(* Affiche OK si l'analyse syntaxique c'est bien passée et KO sinon *)
|
||||||
|
let main () =
|
||||||
|
let cin =
|
||||||
|
if Array.length Sys.argv > 1 then
|
||||||
|
open_in Sys.argv.(1)
|
||||||
|
else
|
||||||
|
stdin
|
||||||
|
in
|
||||||
|
let lexbuf = Lexing.from_channel cin in
|
||||||
|
let tokens = (scanner lexbuf) in
|
||||||
|
(print_endline ("Résultat de l'analyse lexicale : " ^ (string_of_stream tokens)));
|
||||||
|
(print_endline "Analyse syntaxique par descente récursive, règles appliquées :");
|
||||||
|
(match (parseM tokens)
|
||||||
|
with
|
||||||
|
| Success [UL_FIN] -> print_endline "Succés"
|
||||||
|
| _ -> print_endline "Echec")
|
||||||
|
;;
|
||||||
|
|
||||||
|
main();;
|
239
BE_2020_2021/descendant/Parser.ml
Executable file
239
BE_2020_2021/descendant/Parser.ml
Executable file
|
@ -0,0 +1,239 @@
|
||||||
|
open Tokens
|
||||||
|
|
||||||
|
(* Type du résultat d'une analyse syntaxique *)
|
||||||
|
type parseResult =
|
||||||
|
| Success of inputStream
|
||||||
|
| Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* accept : token -> inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien le token attendu *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let accept expected stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| token when (token = expected) -> (Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* acceptIdent : inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien un identifiant *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let acceptIdent stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| (UL_IDENT _) -> (Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* Définition de la monade qui est composée de : *)
|
||||||
|
(* - le type de donnée monadique : parseResult *)
|
||||||
|
(* - la fonction : inject qui construit ce type à partir d'une liste de terminaux *)
|
||||||
|
(* - la fonction : bind (opérateur >>=) qui combine les fonctions d'analyse. *)
|
||||||
|
|
||||||
|
(* inject inputStream -> parseResult *)
|
||||||
|
(* Construit le type de la monade à partir d'une liste de terminaux *)
|
||||||
|
let inject s = Success s;;
|
||||||
|
|
||||||
|
(* bind : 'a m -> ('a -> 'b m) -> 'b m *)
|
||||||
|
(* bind (opérateur >>=) qui combine les fonctions d'analyse. *)
|
||||||
|
(* ici on utilise une version spécialisée de bind :
|
||||||
|
'b -> inputStream
|
||||||
|
'a -> inputStream
|
||||||
|
m -> parseResult
|
||||||
|
*)
|
||||||
|
(* >>= : parseResult -> (inputStream -> parseResult) -> parseResult *)
|
||||||
|
let (>>=) result f =
|
||||||
|
match result with
|
||||||
|
| Success next -> f next
|
||||||
|
| Failure -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(****** Règles LL1 ******)
|
||||||
|
|
||||||
|
(* parseM : inputStream -> parseResult *)
|
||||||
|
let rec parseM stream =
|
||||||
|
(print_endline "M");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 1. M -> machine ident { SC } *)
|
||||||
|
| UL_MACHINE ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_MACHINE >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
accept UL_ACCOUV >>=
|
||||||
|
parseSC >>=
|
||||||
|
accept UL_ACCFER
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseSC : inputStream -> parseResult *)
|
||||||
|
and parseSC stream =
|
||||||
|
(print_endline "SC");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 2. SC -> Λ *)
|
||||||
|
| UL_ACCFER ->
|
||||||
|
inject stream
|
||||||
|
(* 3. SC -> C SC *)
|
||||||
|
| ( UL_EVENT | UL_FROM | UL_REGION ) ->
|
||||||
|
inject stream >>=
|
||||||
|
parseC >>=
|
||||||
|
parseSC
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseC : inputStream -> parseResult *)
|
||||||
|
and parseC stream =
|
||||||
|
(print_endline "C");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 4. C -> event ident *)
|
||||||
|
| UL_EVENT ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_EVENT >>=
|
||||||
|
acceptIdent
|
||||||
|
(* 5. C -> from NQ to NQ on ident *)
|
||||||
|
| UL_FROM ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_FROM >>=
|
||||||
|
parseNQ >>=
|
||||||
|
accept UL_TO >>=
|
||||||
|
parseNQ >>=
|
||||||
|
accept UL_ON >>=
|
||||||
|
acceptIdent
|
||||||
|
(* 9. C -> R *)
|
||||||
|
| UL_REGION ->
|
||||||
|
inject stream >>=
|
||||||
|
parseR
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseNQ : inputStream -> parseResult *)
|
||||||
|
and parseNQ stream =
|
||||||
|
(print_endline "NQ");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 6. NQ -> ident SQ *)
|
||||||
|
| (UL_IDENT _) ->
|
||||||
|
inject stream >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
parseSQ
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseSQ : inputStream -> parseResult *)
|
||||||
|
and parseSQ stream =
|
||||||
|
(print_endline "SQ");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 7. SQ -> Λ *)
|
||||||
|
| ( UL_TO | UL_ON ) ->
|
||||||
|
inject stream
|
||||||
|
(* 8. SQ -> . ident SQ *)
|
||||||
|
| UL_PT ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_PT >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
parseSQ
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseR : inputStream -> parseResult *)
|
||||||
|
and parseR stream =
|
||||||
|
(print_endline "R");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 10. R -> region ident { E SE } *)
|
||||||
|
| UL_REGION ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_REGION >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
accept UL_ACCOUV >>=
|
||||||
|
parseE >>=
|
||||||
|
parseSE >>=
|
||||||
|
accept UL_ACCFER
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseSE : inputStream -> parseResult *)
|
||||||
|
and parseSE stream =
|
||||||
|
(print_endline "SE");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 11. SE -> Λ *)
|
||||||
|
| UL_ACCFER ->
|
||||||
|
inject stream
|
||||||
|
(* 12. SE -> E SE *)
|
||||||
|
| UL_STATE ->
|
||||||
|
inject stream >>=
|
||||||
|
parseE >>=
|
||||||
|
parseSE
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseE : inputStream -> parseResult *)
|
||||||
|
and parseE stream =
|
||||||
|
(print_endline "E");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 13. E -> state ident ES EE EC *)
|
||||||
|
| UL_STATE ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_STATE >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
parseES >>=
|
||||||
|
parseEE >>=
|
||||||
|
parseEC
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseES : inputStream -> parseResult *)
|
||||||
|
and parseES stream =
|
||||||
|
(print_endline "ES");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 14. ES -> Λ *)
|
||||||
|
| ( UL_ENDS | UL_ACCOUV | UL_ACCFER | UL_STATE ) ->
|
||||||
|
inject stream
|
||||||
|
(* 15. ES -> starts *)
|
||||||
|
| UL_STARTS ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_STARTS
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseEE : inputStream -> parseResult *)
|
||||||
|
and parseEE stream =
|
||||||
|
(print_endline "EE");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 16. EE -> Λ *)
|
||||||
|
| ( UL_ACCOUV | UL_ACCFER | UL_STATE ) ->
|
||||||
|
inject stream
|
||||||
|
(* 17. EE -> ends *)
|
||||||
|
| UL_ENDS ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_ENDS
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseEC : inputStream -> parseResult *)
|
||||||
|
and parseEC stream =
|
||||||
|
(print_endline "EC");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 18. EC -> Λ *)
|
||||||
|
| ( UL_ACCFER | UL_STATE ) ->
|
||||||
|
inject stream
|
||||||
|
(* 19. EC -> { R SR } *)
|
||||||
|
| UL_ACCOUV ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_ACCOUV >>=
|
||||||
|
parseR >>=
|
||||||
|
parseSR >>=
|
||||||
|
accept UL_ACCFER
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseSR : inputStream -> parseResult *)
|
||||||
|
and parseSR stream =
|
||||||
|
(print_endline "SR");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 20. SR -> Λ *)
|
||||||
|
| UL_ACCFER ->
|
||||||
|
inject stream
|
||||||
|
(* 21. SR -> R SR *)
|
||||||
|
| UL_REGION ->
|
||||||
|
inject stream >>=
|
||||||
|
parseR >>=
|
||||||
|
parseSR
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
43
BE_2020_2021/descendant/Scanner.mll
Executable file
43
BE_2020_2021/descendant/Scanner.mll
Executable file
|
@ -0,0 +1,43 @@
|
||||||
|
{
|
||||||
|
|
||||||
|
(* Partie recopiée dans le fichier CaML généré. *)
|
||||||
|
(* Ouverture de modules exploités dans les actions *)
|
||||||
|
(* Déclarations de types, de constantes, de fonctions, d'exceptions exploités dans les actions *)
|
||||||
|
|
||||||
|
open Tokens
|
||||||
|
exception Printf
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
(* Déclaration d'expressions régulières exploitées par la suite *)
|
||||||
|
let chiffre = ['0' - '9']
|
||||||
|
let minuscule = ['a' - 'z']
|
||||||
|
let majuscule = ['A' - 'Z']
|
||||||
|
let alphabet = minuscule | majuscule
|
||||||
|
let alphanum = alphabet | chiffre | '_'
|
||||||
|
let commentaire =
|
||||||
|
(* Commentaire fin de ligne *)
|
||||||
|
"#" [^'\n']*
|
||||||
|
|
||||||
|
rule scanner = parse
|
||||||
|
| ['\n' '\t' ' ']+ { (scanner lexbuf) }
|
||||||
|
| commentaire { (scanner lexbuf) }
|
||||||
|
| "machine" { UL_MACHINE::(scanner lexbuf) }
|
||||||
|
| "." { UL_PT::(scanner lexbuf) }
|
||||||
|
| "{" { UL_ACCOUV::(scanner lexbuf) }
|
||||||
|
| "}" { UL_ACCFER::(scanner lexbuf) }
|
||||||
|
| "to" { UL_TO::(scanner lexbuf) }
|
||||||
|
| "on" { UL_ON::(scanner lexbuf) }
|
||||||
|
| "event" { UL_EVENT::(scanner lexbuf) }
|
||||||
|
| "from" { UL_FROM::(scanner lexbuf) }
|
||||||
|
| "region" { UL_REGION::(scanner lexbuf) }
|
||||||
|
| "ends" { UL_ENDS::(scanner lexbuf) }
|
||||||
|
| "starts" { UL_STARTS::(scanner lexbuf) }
|
||||||
|
| "state" { UL_STATE::(scanner lexbuf) }
|
||||||
|
| eof { [UL_FIN] }
|
||||||
|
| alphabet+ as texte { (UL_IDENT texte)::(scanner lexbuf) }
|
||||||
|
| _ as texte { (print_string "Erreur lexicale : ");(print_char texte);(print_newline ()); (UL_ERREUR::(scanner lexbuf)) }
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
68
BE_2020_2021/descendant/Tokens.ml
Executable file
68
BE_2020_2021/descendant/Tokens.ml
Executable file
|
@ -0,0 +1,68 @@
|
||||||
|
open List
|
||||||
|
|
||||||
|
type token =
|
||||||
|
| UL_ACCOUV
|
||||||
|
| UL_ACCFER
|
||||||
|
| UL_PT
|
||||||
|
| UL_MACHINE
|
||||||
|
| UL_TO
|
||||||
|
| UL_ON
|
||||||
|
| UL_EVENT
|
||||||
|
| UL_FROM
|
||||||
|
| UL_REGION
|
||||||
|
| UL_ENDS
|
||||||
|
| UL_STARTS
|
||||||
|
| UL_STATE
|
||||||
|
| UL_FIN
|
||||||
|
| UL_IDENT of string
|
||||||
|
| UL_ERREUR
|
||||||
|
;;
|
||||||
|
|
||||||
|
type inputStream = token list;;
|
||||||
|
|
||||||
|
(* string_of_token : token -> string *)
|
||||||
|
(* Converti un token en une chaîne de caractère*)
|
||||||
|
let string_of_token token =
|
||||||
|
match token with
|
||||||
|
| UL_MACHINE -> "machine"
|
||||||
|
| UL_ACCOUV -> "{"
|
||||||
|
| UL_ACCFER -> "}"
|
||||||
|
| UL_PT -> "."
|
||||||
|
| UL_TO -> "to"
|
||||||
|
| UL_ON -> "on"
|
||||||
|
| UL_EVENT -> "event"
|
||||||
|
| UL_FROM -> "from"
|
||||||
|
| UL_REGION -> "region"
|
||||||
|
| UL_ENDS -> "ends"
|
||||||
|
| UL_STARTS -> "starts"
|
||||||
|
| UL_STATE -> "state"
|
||||||
|
| UL_FIN -> "EOF"
|
||||||
|
| UL_ERREUR -> "Erreur Lexicale"
|
||||||
|
| UL_IDENT (texte) -> texte
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* string_of_stream : inputStream -> string *)
|
||||||
|
(* Converti un inputStream (liste de token) en une chaîne de caractère *)
|
||||||
|
let string_of_stream stream =
|
||||||
|
List.fold_right (fun t tq -> (string_of_token t) ^ " " ^ tq ) stream "";;
|
||||||
|
|
||||||
|
|
||||||
|
(* peekAtFirstToken : inputStream -> token *)
|
||||||
|
(* Renvoie le premier élément d'un inputStream *)
|
||||||
|
(* Erreur : si l'inputStream est vide *)
|
||||||
|
let peekAtFirstToken stream =
|
||||||
|
match stream with
|
||||||
|
(* Normalement, ne doit jamais se produire sauf si la grammaire essaie de lire *)
|
||||||
|
(* après la fin de l'inputStream. *)
|
||||||
|
| [] -> failwith "Impossible d'acceder au premier element d'un inputStream vide"
|
||||||
|
|t::_ -> t;;
|
||||||
|
|
||||||
|
(* advanceInStream : inputStream -> inputStream *)
|
||||||
|
(* Consomme le premier élément d'un inputStream *)
|
||||||
|
(* Erreur : si l'inputStream est vide *)
|
||||||
|
let advanceInStream stream =
|
||||||
|
match stream with
|
||||||
|
(* Normalement, ne doit jamais se produire sauf si la grammaire essaie de lire *)
|
||||||
|
(* après la fin de l'inputStream. *)
|
||||||
|
| [] -> failwith "Impossible de consommer le premier element d'un inputStream vide"
|
||||||
|
| _::q -> q;;
|
4
BE_2020_2021/descendant/dune
Executable file
4
BE_2020_2021/descendant/dune
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
(ocamllex Scanner)
|
||||||
|
|
||||||
|
(executables
|
||||||
|
(names MainMachine))
|
1
BE_2020_2021/descendant/dune-project
Executable file
1
BE_2020_2021/descendant/dune-project
Executable file
|
@ -0,0 +1 @@
|
||||||
|
(lang dune 2.9)
|
10
BE_2020_2021/tests/sujet.sml
Executable file
10
BE_2020_2021/tests/sujet.sml
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
machine lamp {
|
||||||
|
event switchOn
|
||||||
|
event switchOff
|
||||||
|
region bulb {
|
||||||
|
state Off starts ends
|
||||||
|
state On
|
||||||
|
}
|
||||||
|
from bulb.Off to buld.On on switchOn
|
||||||
|
from buld.On to buld.Off on SwitchOff
|
||||||
|
}
|
1
BE_2020_2021/tests/test-KO-00.sml
Executable file
1
BE_2020_2021/tests/test-KO-00.sml
Executable file
|
@ -0,0 +1 @@
|
||||||
|
machine Test {
|
2
BE_2020_2021/tests/test-OK-00.sml
Executable file
2
BE_2020_2021/tests/test-OK-00.sml
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
machine Test {
|
||||||
|
}
|
55
BE_2021_2022/ascendant/Lexer.mll
Normal file
55
BE_2021_2022/ascendant/Lexer.mll
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
{
|
||||||
|
|
||||||
|
(* Partie recopiée dans le fichier CaML généré. *)
|
||||||
|
(* Ouverture de modules exploités dans les actions *)
|
||||||
|
(* Déclarations de types, de constantes, de fonctions, d'exceptions exploités dans les actions *)
|
||||||
|
|
||||||
|
open Parser
|
||||||
|
exception LexicalError
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
(* Déclaration d'expressions régulières exploitées par la suite *)
|
||||||
|
let chiffre = ['0' - '9']
|
||||||
|
let entier = ['1' - '9']
|
||||||
|
let minuscule = ['a' - 'z']
|
||||||
|
let majuscule = ['A' - 'Z']
|
||||||
|
let alphabet = minuscule | majuscule
|
||||||
|
let alphanum = alphabet | chiffre | '_'
|
||||||
|
let commentaire =
|
||||||
|
(* Commentaire fin de ligne *)
|
||||||
|
"#" [^'\n']*
|
||||||
|
|
||||||
|
rule lexer = parse
|
||||||
|
| ['\n' '\t' ' ']+ { (lexer lexbuf) }
|
||||||
|
| commentaire { (lexer lexbuf) }
|
||||||
|
| "model" { UL_MODEL }
|
||||||
|
| "system" { UL_SYSTEM }
|
||||||
|
| "block" { UL_BLOCK }
|
||||||
|
| "flow" { UL_FLOW }
|
||||||
|
| "from" { UL_FROM }
|
||||||
|
| "to" { UL_TO }
|
||||||
|
| "in" { UL_IN }
|
||||||
|
| "out" { UL_OUT }
|
||||||
|
| "int" { UL_INT }
|
||||||
|
| "float" { UL_FLOAT }
|
||||||
|
| "boolean" { UL_BOOLEAN }
|
||||||
|
| "{" { UL_ACCOUV }
|
||||||
|
| "}" { UL_ACCFER }
|
||||||
|
| "(" { UL_PAROUV }
|
||||||
|
| ")" { UL_PARFER }
|
||||||
|
| "[" { UL_CROOUV }
|
||||||
|
| "]" { UL_CROFER }
|
||||||
|
| ";" { UL_PTV }
|
||||||
|
| "," { UL_VIRG }
|
||||||
|
| ":" { UL_PT2 }
|
||||||
|
| "." { UL_PT }
|
||||||
|
| eof { UL_FIN }
|
||||||
|
| majuscule alphabet* as texte { (UL_IDENT texte) }
|
||||||
|
| minuscule alphabet* as texte { (UL_PORT texte) }
|
||||||
|
| entier chiffre* as texte { (UL_ENTIER (int_of_string texte)) }
|
||||||
|
| _ as texte { (print_string "Erreur lexicale : ");(print_char texte);(print_newline ()); raise LexicalError }
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
52
BE_2021_2022/ascendant/MainSystem.ml
Normal file
52
BE_2021_2022/ascendant/MainSystem.ml
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
open Parser
|
||||||
|
|
||||||
|
(* Fonction d'affichage des unités lexicales et des données qu'elles contiennent *)
|
||||||
|
let printToken t =
|
||||||
|
(print_endline
|
||||||
|
(match t with
|
||||||
|
| UL_MODEL -> "model"
|
||||||
|
| UL_SYSTEM -> "system"
|
||||||
|
| UL_BLOCK -> "block"
|
||||||
|
| UL_FLOW -> "flow"
|
||||||
|
| UL_FROM -> "from"
|
||||||
|
| UL_TO -> "to"
|
||||||
|
| UL_IN -> "in"
|
||||||
|
| UL_OUT -> "out"
|
||||||
|
| UL_INT -> "int"
|
||||||
|
| UL_FLOAT -> "float"
|
||||||
|
| UL_BOOLEAN -> "boolean"
|
||||||
|
| UL_ACCOUV -> "{"
|
||||||
|
| UL_ACCFER -> "}"
|
||||||
|
| UL_PAROUV -> "("
|
||||||
|
| UL_PARFER -> ")"
|
||||||
|
| UL_CROOUV -> "["
|
||||||
|
| UL_CROFER -> "]"
|
||||||
|
| UL_PTV -> ";"
|
||||||
|
| UL_VIRG -> ","
|
||||||
|
| UL_PT2 -> ":"
|
||||||
|
| UL_PT -> "."
|
||||||
|
| UL_IDENT texte -> texte
|
||||||
|
| UL_PORT texte -> texte
|
||||||
|
| UL_ENTIER texte -> (string_of_int texte)
|
||||||
|
| UL_FIN -> "EOF"
|
||||||
|
));;
|
||||||
|
|
||||||
|
(* Analyse lexicale du fichier passé en paramètre de la ligne de commande *)
|
||||||
|
if (Array.length Sys.argv > 1)
|
||||||
|
then
|
||||||
|
let lexbuf = (Lexing.from_channel (open_in Sys.argv.(1))) in
|
||||||
|
let token = ref (Lexer.lexer lexbuf) in
|
||||||
|
while ((!token) != UL_FIN) do
|
||||||
|
(printToken (!token));
|
||||||
|
(token := (Lexer.lexer lexbuf))
|
||||||
|
done
|
||||||
|
else
|
||||||
|
(print_endline "MainJSON fichier");;
|
||||||
|
|
||||||
|
(* Analyse lexicale, syntaxique et sémantique du fichier passé en paramètre de la ligne de commande *)
|
||||||
|
if (Array.length Sys.argv > 1)
|
||||||
|
then
|
||||||
|
let lexbuf = (Lexing.from_channel (open_in Sys.argv.(1))) in
|
||||||
|
(Parser.modele Lexer.lexer lexbuf)
|
||||||
|
else
|
||||||
|
(print_endline "MainJSON fichier");;
|
88
BE_2021_2022/ascendant/Parser.mly
Normal file
88
BE_2021_2022/ascendant/Parser.mly
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
%{
|
||||||
|
|
||||||
|
(* Partie recopiee dans le fichier CaML genere. *)
|
||||||
|
(* Ouverture de modules exploites dans les actions *)
|
||||||
|
(* Declarations de types, de constantes, de fonctions, d'exceptions exploites dans les actions *)
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
/* Declaration des unites lexicales et de leur type si une valeur particuliere leur est associee */
|
||||||
|
|
||||||
|
%token UL_MODEL
|
||||||
|
%token UL_ACCOUV UL_ACCFER
|
||||||
|
%token UL_SYSTEM
|
||||||
|
%token UL_BLOCK
|
||||||
|
%token UL_FLOW UL_FROM UL_TO
|
||||||
|
%token UL_IN UL_OUT
|
||||||
|
%token UL_INT UL_FLOAT UL_BOOLEAN
|
||||||
|
%token UL_PAROUV UL_PARFER
|
||||||
|
%token UL_CROOUV UL_CROFER
|
||||||
|
%token UL_PTV UL_VIRG UL_PT2 UL_PT
|
||||||
|
|
||||||
|
/* Defini le type des donnees associees a l'unite lexicale */
|
||||||
|
|
||||||
|
%token <string> UL_IDENT
|
||||||
|
%token <string> UL_PORT
|
||||||
|
%token <int> UL_ENTIER
|
||||||
|
|
||||||
|
/* Unite lexicale particuliere qui represente la fin du fichier */
|
||||||
|
|
||||||
|
%token UL_FIN
|
||||||
|
|
||||||
|
/* Type renvoye pour le nom terminal document */
|
||||||
|
%type <unit> modele
|
||||||
|
|
||||||
|
/* Le non terminal document est l'axiome */
|
||||||
|
%start modele
|
||||||
|
|
||||||
|
%% /* Regles de productions */
|
||||||
|
|
||||||
|
modele : UL_MODEL UL_IDENT UL_ACCOUV loop_element UL_ACCFER UL_FIN { (print_endline "modele : UL_MODEL IDENT { loop_element } UL_FIN ") }
|
||||||
|
|
||||||
|
element : bloc { (print_endline "element : bloc") }
|
||||||
|
| systeme { (print_endline "element : systeme") }
|
||||||
|
| flot { (print_endline "element : flot") }
|
||||||
|
|
||||||
|
loop_element : /* Lambda */ { (print_endline "loop_element : /* Lambda */") }
|
||||||
|
| element loop_element { (print_endline "loop_element : element loop_element") }
|
||||||
|
|
||||||
|
bloc : UL_BLOCK UL_IDENT parametres UL_PTV { (print_endline "bloc : UL_BLOCK UL_IDENT parametres UL_PTV") }
|
||||||
|
|
||||||
|
systeme : UL_SYSTEM UL_IDENT parametres UL_ACCOUV loop_element UL_ACCFER { (print_endline "systeme : UL_SYSTEM UL_IDENT parametres UL_ACCOUV loop_element UL_ACCFER") }
|
||||||
|
|
||||||
|
parametres : UL_PAROUV port loop_port UL_PARFER { (print_endline "parametres : UL_PAROUV port loop_port UL_PARFER") }
|
||||||
|
|
||||||
|
loop_port : /* Lambda */ { (print_endline "loop_port : /* Lambda */") }
|
||||||
|
| UL_VIRG port loop_port { (print_endline "loop_port : UL_VIRG port loop_port") }
|
||||||
|
|
||||||
|
port : UL_PORT UL_PT2 in_or_out type_ { (print_endline "port : UL_PORT UL_PT2 in_or_out type_") }
|
||||||
|
|
||||||
|
in_or_out : UL_IN { (print_endline "in_or_out : UL_IN") }
|
||||||
|
| UL_OUT { (print_endline "in_or_out : UL_OUT") }
|
||||||
|
|
||||||
|
type_ : select_type option_entiers { (print_endline "type_ : select_type option_entiers") }
|
||||||
|
|
||||||
|
select_type : UL_INT { (print_endline "select_type : UL_INT") }
|
||||||
|
| UL_FLOAT { (print_endline "select_type : UL_FLOAT") }
|
||||||
|
| UL_BOOLEAN { (print_endline "select_type : UL_BOOLEAN") }
|
||||||
|
|
||||||
|
option_entiers : /* Lambda */ { (print_endline "option_entiers : /* Lambda */") }
|
||||||
|
| UL_CROOUV UL_ENTIER loop_entier UL_CROFER { (print_endline "option_entiers : UL_CROOUV UL_ENTIER loop_entier UL_CROFER") }
|
||||||
|
|
||||||
|
loop_entier : /* Lambda */ { (print_endline "loop_entier : /* Lambda */") }
|
||||||
|
| UL_VIRG UL_ENTIER loop_entier { (print_endline "loop_entier : UL_VIRG UL_ENTIER loop_entier") }
|
||||||
|
|
||||||
|
flot : UL_FLOW UL_PORT UL_FROM option_ident UL_PORT UL_TO option_loop_ident_port UL_PTV { (print_endline "flot : UL_FLOW UL_PORT UL_FROM option_ident UL_PORT UL_TO option_loop_ident_port UL_PTV") }
|
||||||
|
|
||||||
|
option_ident : /* Lambda */ { (print_endline "option_ident : /* Lambda */") }
|
||||||
|
| UL_IDENT UL_PT { (print_endline "option_ident : UL_IDENT UL_PT") }
|
||||||
|
|
||||||
|
ident_port : option_ident UL_PORT { (print_endline "ident_port : option_ident UL_PORT") }
|
||||||
|
|
||||||
|
loop_ident_port : /* Lambda */ { (print_endline "loop_ident_port : /* Lambda */") }
|
||||||
|
| UL_VIRG ident_port loop_ident_port { (print_endline "loop_ident_port : UL_IDENT UL_PT") }
|
||||||
|
|
||||||
|
option_loop_ident_port : /* Lambda */ { (print_endline "option_loop_ident_port : /* Lambda */") }
|
||||||
|
| ident_port loop_ident_port { (print_endline "option_loop_ident_port : ident_port loop_ident_port") }
|
||||||
|
|
||||||
|
%%
|
7
BE_2021_2022/ascendant/dune
Normal file
7
BE_2021_2022/ascendant/dune
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
(ocamllex Lexer)
|
||||||
|
|
||||||
|
(menhir
|
||||||
|
(modules Parser))
|
||||||
|
|
||||||
|
(executable
|
||||||
|
(name MainSystem))
|
2
BE_2021_2022/ascendant/dune-project
Normal file
2
BE_2021_2022/ascendant/dune-project
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
(lang dune 2.9)
|
||||||
|
(using menhir 2.1)
|
25
BE_2021_2022/descendant/MainSystem.ml
Normal file
25
BE_2021_2022/descendant/MainSystem.ml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
open Tokens
|
||||||
|
open Scanner
|
||||||
|
open Parser
|
||||||
|
|
||||||
|
(* main : unit -> unit *)
|
||||||
|
(* Analyse le contenu d'un fichier passé en paramètre ou l'entrée standard si aucun fichier n'est donné *)
|
||||||
|
(* Affiche OK si l'analyse syntaxique c'est bien passée et KO sinon *)
|
||||||
|
let main () =
|
||||||
|
let cin =
|
||||||
|
if Array.length Sys.argv > 1 then
|
||||||
|
open_in Sys.argv.(1)
|
||||||
|
else
|
||||||
|
stdin
|
||||||
|
in
|
||||||
|
let lexbuf = Lexing.from_channel cin in
|
||||||
|
let tokens = (scanner lexbuf) in
|
||||||
|
(print_endline ("Résultat de l'analyse lexicale :" ^ (string_of_stream tokens)));
|
||||||
|
(print_endline "Analyse syntaxique par descente récursive, règles appliquées :");
|
||||||
|
(match (parseR tokens)
|
||||||
|
with
|
||||||
|
| Success [UL_FIN] -> print_endline "Succés"
|
||||||
|
| _ -> print_endline "Echec")
|
||||||
|
;;
|
||||||
|
|
||||||
|
main();;
|
303
BE_2021_2022/descendant/Parser.ml
Normal file
303
BE_2021_2022/descendant/Parser.ml
Normal file
|
@ -0,0 +1,303 @@
|
||||||
|
open Tokens
|
||||||
|
|
||||||
|
(* Type du résultat d'une analyse syntaxique *)
|
||||||
|
type parseResult =
|
||||||
|
| Success of inputStream
|
||||||
|
| Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* accept : token -> inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien le token attendu *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let accept expected stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| token when (token = expected) ->
|
||||||
|
(Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* acceptIdent : inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien un identifiant *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let acceptIdent stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| (UL_IDENT _) -> (Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* acceptPort : inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien un port *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let acceptPort stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| (UL_PORT _) -> (Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* acceptEntier : inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien un entier *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let acceptEntier stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| (UL_ENTIER _) -> (Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* Définition de la monade qui est composée de : *)
|
||||||
|
(* - le type de donnée monadique : parseResult *)
|
||||||
|
(* - la fonction : inject qui construit ce type à partir d'une liste de terminaux *)
|
||||||
|
(* - la fonction : bind (opérateur >>=) qui combine les fonctions d'analyse. *)
|
||||||
|
|
||||||
|
(* inject inputStream -> parseResult *)
|
||||||
|
(* Construit le type de la monade à partir d'une liste de terminaux *)
|
||||||
|
let inject s = Success s;;
|
||||||
|
|
||||||
|
(* bind : 'a m -> ('a -> 'b m) -> 'b m *)
|
||||||
|
(* bind (opérateur >>=) qui combine les fonctions d'analyse. *)
|
||||||
|
(* ici on utilise une version spécialisée de bind :
|
||||||
|
'b -> inputStream
|
||||||
|
'a -> inputStream
|
||||||
|
m -> parseResult
|
||||||
|
*)
|
||||||
|
(* >>= : parseResult -> (inputStream -> parseResult) -> parseResult *)
|
||||||
|
let (>>=) result f =
|
||||||
|
match result with
|
||||||
|
| Success next -> f next
|
||||||
|
| Failure -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
|
||||||
|
(* parseR : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal Programme *)
|
||||||
|
let rec parseR stream =
|
||||||
|
(print_string "R");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 1. R -> model Ident { SE } *)
|
||||||
|
| UL_MODEL ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_MODEL >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
accept UL_ACCOUV >>=
|
||||||
|
parseSE >>=
|
||||||
|
accept UL_ACCFER
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseSE : inputStream -> parseResult *)
|
||||||
|
and parseSE stream =
|
||||||
|
(print_endline "SE");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 2. SE -> Λ *)
|
||||||
|
| UL_ACCFER ->
|
||||||
|
inject stream
|
||||||
|
(* 3. SE -> E SE *)
|
||||||
|
| ( UL_BLOCK | UL_SYSTEM | UL_FLOW ) ->
|
||||||
|
inject stream >>=
|
||||||
|
parseE >>=
|
||||||
|
parseSE
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseE : inputStream -> parseResult *)
|
||||||
|
and parseE stream =
|
||||||
|
(print_endline "E");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 4. E -> block Ident P ; *)
|
||||||
|
| UL_BLOCK ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_BLOCK >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
parseP >>=
|
||||||
|
accept UL_PTV
|
||||||
|
(* 5. E -> system Ident P { SE } *)
|
||||||
|
| UL_SYSTEM ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_SYSTEM >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
parseP >>=
|
||||||
|
accept UL_ACCOUV >>=
|
||||||
|
parseSE >>=
|
||||||
|
accept UL_ACCFER
|
||||||
|
(* 6. E -> flow ident from NQ to LN ; *)
|
||||||
|
| UL_FLOW ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_FLOW >>=
|
||||||
|
acceptPort >>=
|
||||||
|
accept UL_FROM >>=
|
||||||
|
parseNQ >>=
|
||||||
|
accept UL_TO >>=
|
||||||
|
parseLN >>=
|
||||||
|
accept UL_PTV
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseNQ : inputStream -> parseResult *)
|
||||||
|
and parseNQ stream =
|
||||||
|
(print_endline "NQ");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 7. NQ -> ident *)
|
||||||
|
| (UL_PORT _) ->
|
||||||
|
inject stream >>=
|
||||||
|
acceptPort
|
||||||
|
(* 8. NQ -> Ident . ident *)
|
||||||
|
| (UL_IDENT _) ->
|
||||||
|
inject stream >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
accept UL_PT >>=
|
||||||
|
acceptPort
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseLN : inputStream -> parseResult *)
|
||||||
|
and parseLN stream =
|
||||||
|
(print_endline "LN");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 9. LN -> Λ *)
|
||||||
|
| UL_PTV ->
|
||||||
|
inject stream
|
||||||
|
(* 10. LN -> NQ SN *)
|
||||||
|
| ( (UL_IDENT _) | (UL_PORT _) ) ->
|
||||||
|
inject stream >>=
|
||||||
|
parseNQ >>=
|
||||||
|
parseSN
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseSN : inputStream -> parseResult *)
|
||||||
|
and parseSN stream =
|
||||||
|
(print_endline "SN");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 11. SN -> Λ *)
|
||||||
|
| UL_PTV ->
|
||||||
|
inject stream
|
||||||
|
(* 12. LN -> , NQ SN *)
|
||||||
|
| UL_VIRG ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_VIRG >>=
|
||||||
|
parseNQ >>=
|
||||||
|
parseSN
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseP : inputStream -> parseResult *)
|
||||||
|
and parseP stream =
|
||||||
|
(print_endline "P");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 13. P -> ( LP ) *)
|
||||||
|
| UL_PAROUV ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_PAROUV >>=
|
||||||
|
parseLP >>=
|
||||||
|
accept UL_PARFER
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseLP : inputStream -> parseResult *)
|
||||||
|
and parseLP stream =
|
||||||
|
(print_endline "LP");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 14. LP -> DP SP *)
|
||||||
|
| (UL_PORT _) ->
|
||||||
|
inject stream >>=
|
||||||
|
parseDP >>=
|
||||||
|
parseSP
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseSP : inputStream -> parseResult *)
|
||||||
|
and parseSP stream =
|
||||||
|
(print_endline "SP");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 15. SP -> Λ *)
|
||||||
|
| UL_PARFER ->
|
||||||
|
inject stream
|
||||||
|
(* 16. LN -> , DP SP *)
|
||||||
|
| UL_VIRG ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_VIRG >>=
|
||||||
|
parseDP >>=
|
||||||
|
parseSP
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseDP : inputStream -> parseResult *)
|
||||||
|
and parseDP stream =
|
||||||
|
(print_endline "DP");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 17. LP -> ident : M T OT *)
|
||||||
|
| (UL_PORT _) ->
|
||||||
|
inject stream >>=
|
||||||
|
acceptPort >>=
|
||||||
|
accept UL_PT2 >>=
|
||||||
|
parseM >>=
|
||||||
|
parseT >>=
|
||||||
|
parseOT
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseM : inputStream -> parseResult *)
|
||||||
|
and parseM stream =
|
||||||
|
(print_endline "M");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 18. M -> in *)
|
||||||
|
| UL_IN ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_IN
|
||||||
|
(* 19. M -> out *)
|
||||||
|
| UL_OUT ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_OUT
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseT : inputStream -> parseResult *)
|
||||||
|
and parseT stream =
|
||||||
|
(print_endline "T");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 20. T -> int *)
|
||||||
|
| UL_INT ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_INT
|
||||||
|
(* 21. M -> float *)
|
||||||
|
| UL_FLOAT ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_FLOAT
|
||||||
|
(* 22. M -> boolean *)
|
||||||
|
| UL_BOOLEAN ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_BOOLEAN
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseOT : inputStream -> parseResult *)
|
||||||
|
and parseOT stream =
|
||||||
|
(print_endline "OT");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 23. OT -> Λ *)
|
||||||
|
| ( UL_VIRG | UL_PARFER ) ->
|
||||||
|
inject stream
|
||||||
|
(* 24. OT -> [ entier SV ] *)
|
||||||
|
| UL_CROOUV ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_CROOUV >>=
|
||||||
|
acceptEntier >>=
|
||||||
|
parseSV >>=
|
||||||
|
accept UL_CROFER
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseSV : inputStream -> parseResult *)
|
||||||
|
and parseSV stream =
|
||||||
|
(print_endline "SV");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* 25. OT -> Λ *)
|
||||||
|
| UL_CROFER ->
|
||||||
|
inject stream
|
||||||
|
(* 26. OT -> , entier SV *)
|
||||||
|
| UL_VIRG ->
|
||||||
|
inject stream >>=
|
||||||
|
accept UL_VIRG >>=
|
||||||
|
acceptEntier >>=
|
||||||
|
parseSV
|
||||||
|
(* Failure *)
|
||||||
|
| _ -> Failure)
|
55
BE_2021_2022/descendant/Scanner.mll
Normal file
55
BE_2021_2022/descendant/Scanner.mll
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
{
|
||||||
|
|
||||||
|
(* Partie recopiée dans le fichier CaML généré. *)
|
||||||
|
(* Ouverture de modules exploités dans les actions *)
|
||||||
|
(* Déclarations de types, de constantes, de fonctions, d'exceptions exploités dans les actions *)
|
||||||
|
|
||||||
|
open Tokens
|
||||||
|
exception Printf
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
(* Déclaration d'expressions régulières exploitées par la suite *)
|
||||||
|
let chiffre = ['0' - '9']
|
||||||
|
let entier = ['1' - '9']
|
||||||
|
let minuscule = ['a' - 'z']
|
||||||
|
let majuscule = ['A' - 'Z']
|
||||||
|
let alphabet = minuscule | majuscule
|
||||||
|
let alphanum = alphabet | chiffre | '_'
|
||||||
|
let commentaire =
|
||||||
|
(* Commentaire fin de ligne *)
|
||||||
|
"#" [^'\n']*
|
||||||
|
|
||||||
|
rule scanner = parse
|
||||||
|
| ['\n' '\t' ' ']+ { (scanner lexbuf) }
|
||||||
|
| commentaire { (scanner lexbuf) }
|
||||||
|
| "model" { UL_MODEL::(scanner lexbuf) }
|
||||||
|
| "system" { UL_SYSTEM::(scanner lexbuf) }
|
||||||
|
| "block" { UL_BLOCK::(scanner lexbuf) }
|
||||||
|
| "flow" { UL_FLOW::(scanner lexbuf) }
|
||||||
|
| "from" { UL_FROM::(scanner lexbuf) }
|
||||||
|
| "to" { UL_TO::(scanner lexbuf) }
|
||||||
|
| "in" { UL_IN::(scanner lexbuf) }
|
||||||
|
| "out" { UL_OUT::(scanner lexbuf) }
|
||||||
|
| "int" { UL_INT::(scanner lexbuf) }
|
||||||
|
| "float" { UL_FLOAT::(scanner lexbuf) }
|
||||||
|
| "boolean" { UL_BOOLEAN::(scanner lexbuf) }
|
||||||
|
| "{" { UL_ACCOUV::(scanner lexbuf) }
|
||||||
|
| "}" { UL_ACCFER::(scanner lexbuf) }
|
||||||
|
| "(" { UL_PAROUV::(scanner lexbuf) }
|
||||||
|
| ")" { UL_PARFER::(scanner lexbuf) }
|
||||||
|
| "[" { UL_CROOUV::(scanner lexbuf) }
|
||||||
|
| "]" { UL_CROFER::(scanner lexbuf) }
|
||||||
|
| ";" { UL_PTV::(scanner lexbuf) }
|
||||||
|
| "," { UL_VIRG::(scanner lexbuf) }
|
||||||
|
| ":" { UL_PT2::(scanner lexbuf) }
|
||||||
|
| "." { UL_PT::(scanner lexbuf) }
|
||||||
|
| majuscule alphabet* as texte { (UL_IDENT texte)::(scanner lexbuf) }
|
||||||
|
| minuscule alphabet* as texte { (UL_PORT texte)::(scanner lexbuf) }
|
||||||
|
| entier chiffre* as texte { (UL_ENTIER (int_of_string texte))::(scanner lexbuf) }
|
||||||
|
| eof { [UL_FIN] }
|
||||||
|
| _ as texte { (print_string "Erreur lexicale : ");(print_char texte);(print_newline ()); (UL_ERREUR::(scanner lexbuf)) }
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
88
BE_2021_2022/descendant/Tokens.ml
Normal file
88
BE_2021_2022/descendant/Tokens.ml
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
open List
|
||||||
|
|
||||||
|
type token =
|
||||||
|
| UL_MODEL
|
||||||
|
| UL_SYSTEM
|
||||||
|
| UL_BLOCK
|
||||||
|
| UL_FLOW
|
||||||
|
| UL_FROM
|
||||||
|
| UL_TO
|
||||||
|
| UL_IN
|
||||||
|
| UL_OUT
|
||||||
|
| UL_INT
|
||||||
|
| UL_FLOAT
|
||||||
|
| UL_BOOLEAN
|
||||||
|
| UL_ACCOUV
|
||||||
|
| UL_ACCFER
|
||||||
|
| UL_PAROUV
|
||||||
|
| UL_PARFER
|
||||||
|
| UL_CROOUV
|
||||||
|
| UL_CROFER
|
||||||
|
| UL_PTV
|
||||||
|
| UL_VIRG
|
||||||
|
| UL_PT2
|
||||||
|
| UL_PT
|
||||||
|
| UL_IDENT of string
|
||||||
|
| UL_PORT of string
|
||||||
|
| UL_ENTIER of int
|
||||||
|
| UL_FIN
|
||||||
|
| UL_ERREUR;;
|
||||||
|
|
||||||
|
type inputStream = token list;;
|
||||||
|
|
||||||
|
(* string_of_token : token -> string *)
|
||||||
|
(* Converti un token en une chaîne de caractère*)
|
||||||
|
let string_of_token token =
|
||||||
|
match token with
|
||||||
|
| UL_MODEL -> "model"
|
||||||
|
| UL_SYSTEM -> "system"
|
||||||
|
| UL_BLOCK -> "block"
|
||||||
|
| UL_FLOW -> "flow"
|
||||||
|
| UL_FROM -> "from"
|
||||||
|
| UL_TO -> "to"
|
||||||
|
| UL_IN -> "in"
|
||||||
|
| UL_OUT -> "out"
|
||||||
|
| UL_INT -> "int"
|
||||||
|
| UL_FLOAT -> "float"
|
||||||
|
| UL_BOOLEAN -> "boolean"
|
||||||
|
| UL_ACCOUV -> "{"
|
||||||
|
| UL_ACCFER -> "}"
|
||||||
|
| UL_PAROUV -> "("
|
||||||
|
| UL_PARFER -> ")"
|
||||||
|
| UL_CROOUV -> "["
|
||||||
|
| UL_CROFER -> "]"
|
||||||
|
| UL_PTV -> ";"
|
||||||
|
| UL_VIRG -> ","
|
||||||
|
| UL_PT2 -> ":"
|
||||||
|
| UL_PT -> "."
|
||||||
|
| UL_IDENT texte -> texte
|
||||||
|
| UL_PORT texte -> texte
|
||||||
|
| UL_ENTIER texte -> (string_of_int texte)
|
||||||
|
| UL_FIN -> "EOF"
|
||||||
|
| UL_ERREUR -> "Erreur Lexicale";;
|
||||||
|
|
||||||
|
(* string_of_stream : inputStream -> string *)
|
||||||
|
(* Converti un inputStream (liste de token) en une chaîne de caractère *)
|
||||||
|
let string_of_stream stream =
|
||||||
|
List.fold_right (fun t tq -> (string_of_token t) ^ " " ^ tq ) stream "";;
|
||||||
|
|
||||||
|
|
||||||
|
(* peekAtFirstToken : inputStream -> token *)
|
||||||
|
(* Renvoie le premier élément d'un inputStream *)
|
||||||
|
(* Erreur : si l'inputStream est vide *)
|
||||||
|
let peekAtFirstToken stream =
|
||||||
|
match stream with
|
||||||
|
(* Normalement, ne doit jamais se produire sauf si la grammaire essaie de lire *)
|
||||||
|
(* après la fin de l'inputStream. *)
|
||||||
|
| [] -> failwith "Impossible d'acceder au premier element d'un inputStream vide"
|
||||||
|
|t::_ -> t;;
|
||||||
|
|
||||||
|
(* advanceInStream : inputStream -> inputStream *)
|
||||||
|
(* Consomme le premier élément d'un inputStream *)
|
||||||
|
(* Erreur : si l'inputStream est vide *)
|
||||||
|
let advanceInStream stream =
|
||||||
|
match stream with
|
||||||
|
(* Normalement, ne doit jamais se produire sauf si la grammaire essaie de lire *)
|
||||||
|
(* après la fin de l'inputStream. *)
|
||||||
|
| [] -> failwith "Impossible de consommer le premier element d'un inputStream vide"
|
||||||
|
| _::q -> q;;
|
4
BE_2021_2022/descendant/dune
Normal file
4
BE_2021_2022/descendant/dune
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
(ocamllex Scanner)
|
||||||
|
|
||||||
|
(executables
|
||||||
|
(names MainSystem))
|
1
BE_2021_2022/descendant/dune-project
Normal file
1
BE_2021_2022/descendant/dune-project
Normal file
|
@ -0,0 +1 @@
|
||||||
|
(lang dune 2.9)
|
11
BE_2021_2022/tests/sujet.sdl
Normal file
11
BE_2021_2022/tests/sujet.sdl
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
model S {
|
||||||
|
flow f from Ba.ra to HS.pa, HS.pb;
|
||||||
|
block Ba(pa : in float, pb : in float, ra : out float [ 2 ] );
|
||||||
|
system HS(pa : in float [ 2 ], ra : out float, pb : in float [ 2 ] , rb : out float [ 2 ] ) {
|
||||||
|
block Bb(ra : out float, pa : in float);
|
||||||
|
flow fa from pa to Bb.pa;
|
||||||
|
flow fb from pb to rb;
|
||||||
|
}
|
||||||
|
flow fb from HS.ra to Ba.pa, Ba.pb;
|
||||||
|
flow fc from HS.rb to;
|
||||||
|
}
|
5
TP1/dune
Executable file
5
TP1/dune
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
(ocamllex lexerJava)
|
||||||
|
|
||||||
|
(executable
|
||||||
|
(modes byte exe)
|
||||||
|
(name mainJava))
|
3
TP1/dune-project
Executable file
3
TP1/dune-project
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
(lang dune 2.0)
|
||||||
|
|
||||||
|
(formatting disabled)
|
95
TP1/lexerJava.mll
Executable file
95
TP1/lexerJava.mll
Executable file
|
@ -0,0 +1,95 @@
|
||||||
|
{
|
||||||
|
|
||||||
|
open TokenJava
|
||||||
|
(* open String *)
|
||||||
|
(* open Str *)
|
||||||
|
exception LexicalError
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
(* Macro-definitions *)
|
||||||
|
let minuscule = ['a'-'z']
|
||||||
|
let javaLetter = minuscule | '_'
|
||||||
|
let majuscule = ['A'-'Z']
|
||||||
|
let chiffre = ['0'-'9']
|
||||||
|
let hexa = chiffre | ['a'-'f'] | ['A'-'F']
|
||||||
|
let octa = ['0'-'7']
|
||||||
|
let alphabet = minuscule | majuscule
|
||||||
|
let alphanum = alphabet | chiffre | '_'
|
||||||
|
let commentaireBloc = "/*" [^'*']* ('*' [^'/'] [^'*']*)* "*/"
|
||||||
|
let commentaireLigne = "//" [^'\n']* '\n'
|
||||||
|
|
||||||
|
(* Analyseur lexical : expression reguliere { action CaML } *)
|
||||||
|
rule lexer = parse
|
||||||
|
(* Espace, tabulation, passage a ligne, etc : consommes par l'analyse lexicale *)
|
||||||
|
| ['\n' '\t' ' ']+ { lexer lexbuf }
|
||||||
|
(* Commentaires consommés par l'analyse lexicale *)
|
||||||
|
| commentaireBloc { lexer lexbuf }
|
||||||
|
| commentaireLigne { lexer lexbuf }
|
||||||
|
(* Structures de blocs *)
|
||||||
|
| "(" { PAROUV }
|
||||||
|
| ")" { PARFER }
|
||||||
|
| "[" { CROOUV }
|
||||||
|
| "]" { CROFER }
|
||||||
|
| "{" { ACCOUV }
|
||||||
|
| "}" { ACCFER }
|
||||||
|
(* Separateurs *)
|
||||||
|
| "," { VIRG }
|
||||||
|
| ";" { PTVIRG }
|
||||||
|
(* Operateurs booleens *)
|
||||||
|
| "||" { OPOU }
|
||||||
|
| "&&" { OPET }
|
||||||
|
| "!" { OPNON }
|
||||||
|
(* Operateurs comparaisons *)
|
||||||
|
| "==" { OPEG }
|
||||||
|
| "!=" { OPNONEG }
|
||||||
|
| "<=" { OPSUPEG }
|
||||||
|
| "<" { OPSUP }
|
||||||
|
| ">=" { OPINFEG }
|
||||||
|
| ">" { OPINF }
|
||||||
|
(* Operateurs arithmetiques *)
|
||||||
|
| "+" { OPPLUS }
|
||||||
|
| "-" { OPMOINS }
|
||||||
|
| "*" { OPMULT }
|
||||||
|
| "/" { OPDIV }
|
||||||
|
| "%" { OPMOD }
|
||||||
|
| "." { OPPT }
|
||||||
|
| "=" { ASSIGN }
|
||||||
|
| "new" { NOUVEAU }
|
||||||
|
(* Mots cles : types *)
|
||||||
|
| "bool" { BOOL }
|
||||||
|
| "char" { CHAR }
|
||||||
|
| "float" { FLOAT }
|
||||||
|
| "int" { INT }
|
||||||
|
| "String" { STRING }
|
||||||
|
| "void" { VOID }
|
||||||
|
(* Mots cles : instructions *)
|
||||||
|
| "while" { TANTQUE }
|
||||||
|
| "if" { SI }
|
||||||
|
| "else" { SINON }
|
||||||
|
| "return" { RETOUR }
|
||||||
|
(* Mots cles : constantes *)
|
||||||
|
| "true" { (BOOLEEN true) }
|
||||||
|
| "false" { (BOOLEEN false) }
|
||||||
|
| "null" { VIDE }
|
||||||
|
(* Nombres entiers : *)
|
||||||
|
| ( '0' | (['1' - '9'](chiffre | '_')*) ) as texte { (ENTIER (int_of_string texte)) }
|
||||||
|
| ( '0'('b'|'B') (chiffre | '_')* ) as texte { (BINAIRE (int_of_string texte)) }
|
||||||
|
| ( '0'('x'|'X') (hexa | '_')* ) as texte { (HEXA (int_of_string texte)) }
|
||||||
|
| ( '0'* (octa | '_')* ) as texte { (OCTA (int_of_string ("0o" ^ texte))) }
|
||||||
|
(* Nombres flottants : *)
|
||||||
|
| ['+''-']? ( chiffre+ | chiffre+ '.' chiffre+ | '.' chiffre+ | chiffre+ '.' ) (['e''E'] ['+''-']? chiffre+ )? as texte { (FLOTTANT (float_of_string texte)) }
|
||||||
|
(* Caracteres : *)
|
||||||
|
| "'" _ "'" as texte { CARACTERE texte.[1] }
|
||||||
|
| "'" '\\' _* "'" as texte { print_endline texte; CARACTERE (char_of_int (int_of_string (String.sub texte 2 ((String.length texte) - 3)))) }
|
||||||
|
(* Chaines de caracteres : A COMPLETER *)
|
||||||
|
| '"' _* '"' as texte { CHAINE texte }
|
||||||
|
(* Identificateurs *)
|
||||||
|
| majuscule alphanum* as texte { TYPEIDENT texte }
|
||||||
|
| javaLetter alphanum* as texte { IDENT texte }
|
||||||
|
| eof { FIN }
|
||||||
|
| _ { raise LexicalError }
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
12
TP1/mainJava.ml
Executable file
12
TP1/mainJava.ml
Executable file
|
@ -0,0 +1,12 @@
|
||||||
|
open TokenJava;;
|
||||||
|
|
||||||
|
if (Array.length Sys.argv > 1)
|
||||||
|
then
|
||||||
|
let lexbuf = (Lexing.from_channel (open_in Sys.argv.(1))) in
|
||||||
|
let token = ref (LexerJava.lexer lexbuf) in
|
||||||
|
while ((!token) != FIN) do
|
||||||
|
(printToken (!token));
|
||||||
|
(token := (LexerJava.lexer lexbuf))
|
||||||
|
done
|
||||||
|
else
|
||||||
|
(print_endline "mainJava.exe fichier")
|
49
TP1/tests/exemple-complique.java
Executable file
49
TP1/tests/exemple-complique.java
Executable file
|
@ -0,0 +1,49 @@
|
||||||
|
|
||||||
|
/* Cet exemple respecte la syntaxe (grammaire) de microjava, avec des
|
||||||
|
* commentaires, des cha<EFBFBD>nes complexes, des r<EFBFBD>els bizarres...
|
||||||
|
* Les constructions qui ne sont pas trait
|
||||||
|
* Ce programme est s<EFBFBD>mantiquement faux (typage en particulier)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* class Point {
|
||||||
|
private int x;
|
||||||
|
private int y;
|
||||||
|
|
||||||
|
private String toto;
|
||||||
|
|
||||||
|
// rien {
|
||||||
|
public int get_x () */
|
||||||
|
{ return x; }
|
||||||
|
// public void set_x (int _x)
|
||||||
|
{ x = _x; }
|
||||||
|
|
||||||
|
// private void essai_string ()
|
||||||
|
{
|
||||||
|
toto = "machin avec des espaces et des \" quotes
|
||||||
|
et multiligne avec echappement \n meme a la fin \\"; foo(); "et une autre chaine";
|
||||||
|
x = 3.14 + .14 + 3. + 14e-1 + .3e1;
|
||||||
|
y = 'a' + '\33' + 0x2A;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ghjd /* ****/
|
||||||
|
/* class PointColore extends Point {
|
||||||
|
public int c;
|
||||||
|
public int get_c () */
|
||||||
|
{ return c*2; }
|
||||||
|
/* } */
|
||||||
|
/*****
|
||||||
|
class PointColore extends Point **g
|
||||||
|
// dfgkhdk *f ** */
|
||||||
|
|
||||||
|
/* public class Exemple {
|
||||||
|
public static void main (String[] argv) */
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
bool b;
|
||||||
|
b = true;
|
||||||
|
if (b) {
|
||||||
|
x = 2*x + 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }
|
32
TP1/tests/exemple-simple.java
Executable file
32
TP1/tests/exemple-simple.java
Executable file
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
// Note: ce fichier ne respecte pas la *grammaire* de micro-java
|
||||||
|
// Il ne fait qu'enumerer les tokens de la grammaire.
|
||||||
|
|
||||||
|
// mot clefs
|
||||||
|
// class extends private public static main
|
||||||
|
|
||||||
|
// types
|
||||||
|
int void float bool char String
|
||||||
|
|
||||||
|
// structures de controle
|
||||||
|
if else while return
|
||||||
|
|
||||||
|
// instructions
|
||||||
|
new null
|
||||||
|
|
||||||
|
// operateurs
|
||||||
|
< > >= <= == !=
|
||||||
|
+ - / * % && || ! = .
|
||||||
|
|
||||||
|
// parentheses
|
||||||
|
( [ { } ] )
|
||||||
|
|
||||||
|
// separateurs
|
||||||
|
, ;
|
||||||
|
|
||||||
|
// constantes
|
||||||
|
true false 0 245 1_234_567 0b1101 0B1_0100_1100 077 01_345 0xFF 0X1_FF00_1234 'a' '(' '?' '\'' '\\' 567.34 +1e-5 -.12 1.5e-4 2.
|
||||||
|
"bonjour"
|
||||||
|
|
||||||
|
// noms
|
||||||
|
x toto Point
|
3
TP1/tests/exemple-tres-simple.java
Executable file
3
TP1/tests/exemple-tres-simple.java
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
, /* test */ int while // ceci est un autre test
|
||||||
|
" te \" st "
|
||||||
|
123
|
2
TP1/tests/exemple.java
Executable file
2
TP1/tests/exemple.java
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
453 while 45, 4, 8
|
||||||
|
int 4 int while , 8
|
11
TP1/tests/test.java
Executable file
11
TP1/tests/test.java
Executable file
|
@ -0,0 +1,11 @@
|
||||||
|
// commentaire ligne
|
||||||
|
/*
|
||||||
|
commentaire
|
||||||
|
bloc
|
||||||
|
*/
|
||||||
|
a = 4
|
||||||
|
/*aaa*/
|
||||||
|
index + 000123
|
||||||
|
{
|
||||||
|
bonjour = 3
|
||||||
|
}
|
121
TP1/tokenJava.ml
Executable file
121
TP1/tokenJava.ml
Executable file
|
@ -0,0 +1,121 @@
|
||||||
|
open Char
|
||||||
|
|
||||||
|
(* Type déclarent les différentes unités lexicales possibles *)
|
||||||
|
|
||||||
|
type token =
|
||||||
|
(* Identificateurs *)
|
||||||
|
| IDENT of string
|
||||||
|
| TYPEIDENT of string
|
||||||
|
(* Mots cles : types *)
|
||||||
|
| INT
|
||||||
|
| FLOAT
|
||||||
|
| BOOL
|
||||||
|
| CHAR
|
||||||
|
| VOID
|
||||||
|
| STRING
|
||||||
|
(* Structure de blocs *)
|
||||||
|
| ACCOUV
|
||||||
|
| ACCFER
|
||||||
|
| PAROUV
|
||||||
|
| PARFER
|
||||||
|
| CROOUV
|
||||||
|
| CROFER
|
||||||
|
(* Separateurs *)
|
||||||
|
| PTVIRG
|
||||||
|
| VIRG
|
||||||
|
(* Mots cles : Instructions *)
|
||||||
|
| SI
|
||||||
|
| SINON
|
||||||
|
| TANTQUE
|
||||||
|
| RETOUR
|
||||||
|
(* Valeurs *)
|
||||||
|
| ENTIER of int
|
||||||
|
| BINAIRE of int
|
||||||
|
| HEXA of int
|
||||||
|
| OCTA of int
|
||||||
|
| FLOTTANT of float
|
||||||
|
| BOOLEEN of bool
|
||||||
|
| CARACTERE of char
|
||||||
|
| CHAINE of string
|
||||||
|
| VIDE
|
||||||
|
(* Operateurs *)
|
||||||
|
| NOUVEAU
|
||||||
|
| ASSIGN
|
||||||
|
| OPPT
|
||||||
|
(* Comparaison *)
|
||||||
|
| OPNONEG
|
||||||
|
| OPEG
|
||||||
|
| OPSUPEG
|
||||||
|
| OPINFEG
|
||||||
|
| OPSUP
|
||||||
|
| OPINF
|
||||||
|
(* Booleen *)
|
||||||
|
| OPOU
|
||||||
|
| OPET
|
||||||
|
| OPNON
|
||||||
|
(* Arithmetique *)
|
||||||
|
| OPPLUS
|
||||||
|
| OPMOINS
|
||||||
|
| OPMULT
|
||||||
|
| OPDIV
|
||||||
|
| OPMOD
|
||||||
|
(* Fin de texte *)
|
||||||
|
| FIN ;;
|
||||||
|
|
||||||
|
let printToken t =
|
||||||
|
(print_endline
|
||||||
|
(match t with
|
||||||
|
(* Structure de blocs *)
|
||||||
|
| PAROUV -> "bloc : ("
|
||||||
|
| PARFER -> "bloc : )"
|
||||||
|
| CROOUV -> "bloc : ["
|
||||||
|
| CROFER -> "bloc : ]"
|
||||||
|
| ACCOUV -> "bloc : {"
|
||||||
|
| ACCFER -> "bloc : }"
|
||||||
|
(* Separateurs *)
|
||||||
|
| VIRG -> "separateur : ,"
|
||||||
|
| PTVIRG -> "separateur : ;"
|
||||||
|
(* Operateurs *)
|
||||||
|
| OPEG -> "operateur : =="
|
||||||
|
| OPNONEG -> "operateur : !="
|
||||||
|
| OPINFEG -> "operateur : >="
|
||||||
|
| OPINF -> "operateur : >"
|
||||||
|
| OPSUPEG -> "operateur : <="
|
||||||
|
| OPSUP -> "operateur : <"
|
||||||
|
| OPET -> "operateur : &&"
|
||||||
|
| OPOU -> "operateur : ||"
|
||||||
|
| OPNON -> "operateur : !"
|
||||||
|
| OPPLUS -> "operateur : +"
|
||||||
|
| OPMOINS -> "operateur : -"
|
||||||
|
| OPMULT -> "operateur : *"
|
||||||
|
| OPDIV -> "operateur : /"
|
||||||
|
| OPMOD -> "operateur : %"
|
||||||
|
| ASSIGN -> "operateur : ="
|
||||||
|
| OPPT -> "operateur : ."
|
||||||
|
| NOUVEAU -> "operateur : new"
|
||||||
|
(* Mots cles : Instructions *)
|
||||||
|
| TANTQUE -> "mot-cle : while"
|
||||||
|
| SI -> "mot-cle : if"
|
||||||
|
| SINON -> "mot-cle : else"
|
||||||
|
| RETOUR -> "mot-cle : return"
|
||||||
|
(* Mots cles : Types *)
|
||||||
|
| BOOL -> "type : boolean"
|
||||||
|
| CHAR -> "type : char"
|
||||||
|
| FLOAT -> "type : float"
|
||||||
|
| INT -> "type : int"
|
||||||
|
| STRING -> "type : String"
|
||||||
|
| VOID -> "type : void"
|
||||||
|
(* Valeurs *)
|
||||||
|
| BOOLEEN b -> "booleen : " ^ (if b then "true" else "false")
|
||||||
|
| CARACTERE c -> "caractere : '" ^ (escaped c) ^ "'"
|
||||||
|
| CHAINE s -> "chaine : " ^ s
|
||||||
|
| ENTIER n -> "entier : " ^ string_of_int n
|
||||||
|
| HEXA n -> "hexa : " ^ string_of_int n
|
||||||
|
| OCTA n -> "octa : " ^ string_of_int n
|
||||||
|
| BINAIRE n -> "binaire : " ^ string_of_int n
|
||||||
|
| FLOTTANT f -> "flottant : " ^ string_of_float f
|
||||||
|
| VIDE -> "null"
|
||||||
|
(* Identificateurs *)
|
||||||
|
| IDENT n -> "identificateur : " ^ n
|
||||||
|
| TYPEIDENT t -> "identificateur de type : " ^ t
|
||||||
|
| _ -> "TBC"));;
|
65
TP1/tokenJava.mli
Executable file
65
TP1/tokenJava.mli
Executable file
|
@ -0,0 +1,65 @@
|
||||||
|
(* Type déclarent les différentes unités lexicales possibles *)
|
||||||
|
|
||||||
|
type token =
|
||||||
|
(* Identificateurs *)
|
||||||
|
| IDENT of string
|
||||||
|
| TYPEIDENT of string
|
||||||
|
(* Mots cles : types *)
|
||||||
|
| INT
|
||||||
|
| FLOAT
|
||||||
|
| BOOL
|
||||||
|
| CHAR
|
||||||
|
| VOID
|
||||||
|
| STRING
|
||||||
|
(* Structure de blocs *)
|
||||||
|
| ACCOUV
|
||||||
|
| ACCFER
|
||||||
|
| PAROUV
|
||||||
|
| PARFER
|
||||||
|
| CROOUV
|
||||||
|
| CROFER
|
||||||
|
(* Separateurs *)
|
||||||
|
| PTVIRG
|
||||||
|
| VIRG
|
||||||
|
(* Mots cles : Instructions *)
|
||||||
|
| SI
|
||||||
|
| SINON
|
||||||
|
| TANTQUE
|
||||||
|
| RETOUR
|
||||||
|
(* Valeurs *)
|
||||||
|
| ENTIER of int
|
||||||
|
| BINAIRE of int
|
||||||
|
| HEXA of int
|
||||||
|
| OCTA of int
|
||||||
|
| FLOTTANT of float
|
||||||
|
| BOOLEEN of bool
|
||||||
|
| CARACTERE of char
|
||||||
|
| CHAINE of string
|
||||||
|
| VIDE
|
||||||
|
(* Operateurs *)
|
||||||
|
| NOUVEAU
|
||||||
|
| ASSIGN
|
||||||
|
| OPPT
|
||||||
|
(* Comparaison *)
|
||||||
|
| OPNONEG
|
||||||
|
| OPEG
|
||||||
|
| OPSUPEG
|
||||||
|
| OPINFEG
|
||||||
|
| OPSUP
|
||||||
|
| OPINF
|
||||||
|
(* Booleen *)
|
||||||
|
| OPOU
|
||||||
|
| OPET
|
||||||
|
| OPNON
|
||||||
|
(* Arithmetique *)
|
||||||
|
| OPPLUS
|
||||||
|
| OPMOINS
|
||||||
|
| OPMULT
|
||||||
|
| OPDIV
|
||||||
|
| OPMOD
|
||||||
|
(* Fin de texte *)
|
||||||
|
| FIN ;;
|
||||||
|
|
||||||
|
|
||||||
|
(* Fonction d'affichage d'une unité lexicale *)
|
||||||
|
val printToken : token -> unit;;
|
7
TP2/dune
Executable file
7
TP2/dune
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
(ocamllex lexerJava)
|
||||||
|
|
||||||
|
(menhir
|
||||||
|
(modules parserJava))
|
||||||
|
|
||||||
|
(executable
|
||||||
|
(name mainJava))
|
5
TP2/dune-project
Executable file
5
TP2/dune-project
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
(lang dune 2.0)
|
||||||
|
|
||||||
|
(using menhir 2.0)
|
||||||
|
|
||||||
|
(formatting disabled)
|
82
TP2/lexerJava.mll
Executable file
82
TP2/lexerJava.mll
Executable file
|
@ -0,0 +1,82 @@
|
||||||
|
{
|
||||||
|
|
||||||
|
(* Partie recopiée dans le fichier CaML généré. *)
|
||||||
|
(* Ouverture de modules exploités dans les actions *)
|
||||||
|
(* Déclarations de types, de constantes, de fonctions, d'exceptions exploités dans les actions *)
|
||||||
|
|
||||||
|
open ParserJava
|
||||||
|
exception LexicalError
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
(* Déclaration d'expressions régulières exploitées par la suite *)
|
||||||
|
let chiffre = ['0' - '9']
|
||||||
|
let binaire = ('0' | '1')
|
||||||
|
let octal = ['0' - '7']
|
||||||
|
let hexadecimal = chiffre | ['A' - 'F']
|
||||||
|
let minuscule = ['a' - 'z']
|
||||||
|
let majuscule = ['A' - 'Z']
|
||||||
|
let alpha = minuscule | majuscule
|
||||||
|
let alphanum = alpha | chiffre | '_'
|
||||||
|
let commentaire =
|
||||||
|
(* Commentaire bloc *)
|
||||||
|
("/*" [^ '*']* '*'* ([^ '*' '/'] [^ '*']* '*'*)* '/')
|
||||||
|
(* Commentaire fin de ligne *)
|
||||||
|
| "//" [^'\n']*
|
||||||
|
|
||||||
|
rule main = parse
|
||||||
|
| ['\n' '\t' ' ']+ { main lexbuf }
|
||||||
|
| commentaire { (main lexbuf) }
|
||||||
|
| "import" { IMPORT }
|
||||||
|
| "int" { INT }
|
||||||
|
| "float" { FLOAT }
|
||||||
|
| "boolean" { BOOL }
|
||||||
|
| "char" { CHAR }
|
||||||
|
| "void" { VOID }
|
||||||
|
| "String" { STRING }
|
||||||
|
| "{" { ACCOUV }
|
||||||
|
| "}" { ACCFER }
|
||||||
|
| "," { VIRG }
|
||||||
|
| ";" { PTVIRG }
|
||||||
|
| "(" { PAROUV }
|
||||||
|
| ")" { PARFER }
|
||||||
|
| "[" { CROOUV }
|
||||||
|
| "]" { CROFER }
|
||||||
|
| "if" { SI }
|
||||||
|
| "else" { SINON }
|
||||||
|
| "while" { TANTQUE }
|
||||||
|
| "return" { RETOUR }
|
||||||
|
| "=" { ASSIGN }
|
||||||
|
| "<" { OPINF }
|
||||||
|
| ">" { OPSUP }
|
||||||
|
| "<=" { OPINFEG }
|
||||||
|
| ">=" { OPSUPEG }
|
||||||
|
| "==" { OPEG }
|
||||||
|
| "!=" { OPNONEG }
|
||||||
|
| "+" { OPPLUS }
|
||||||
|
| "-" { OPMOINS }
|
||||||
|
| "||" { OPOU }
|
||||||
|
| "*" { OPMULT }
|
||||||
|
| "%" { OPMOD }
|
||||||
|
| "/" { OPDIV }
|
||||||
|
| "&&" { OPET }
|
||||||
|
| "!" { OPNON }
|
||||||
|
| "." { OPPT }
|
||||||
|
| chiffre+ as texte { (ENTIER (int_of_string texte)) }
|
||||||
|
| "0x" hexadecimal+ as texte { (ENTIER (int_of_string texte)) }
|
||||||
|
| "0o" octal+ as texte { (ENTIER (int_of_string texte)) }
|
||||||
|
| "0b" binaire+ as texte { (ENTIER (int_of_string texte)) }
|
||||||
|
| chiffre+"."chiffre+ as texte { (FLOTTANT (float_of_string texte))}
|
||||||
|
| ("true" | "false") as texte { (BOOLEEN (bool_of_string texte)) }
|
||||||
|
| '\'' _ '\'' as texte { (CARACTERE texte.[1]) }
|
||||||
|
| '\"' ([^ '\"' '\\'] | ('\\' _))* '\"' as texte { (CHAINE texte) }
|
||||||
|
| "null" { VIDE }
|
||||||
|
| "new" { NOUVEAU }
|
||||||
|
| ('_' | minuscule) alphanum* as texte { (IDENT texte) }
|
||||||
|
| majuscule alphanum* as texte { (TYPEIDENT texte) }
|
||||||
|
| eof { FIN }
|
||||||
|
| _ as texte { (print_string "Erreur lexicale : ");(print_char texte);(print_newline ()); VIDE }
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
71
TP2/mainJava.ml
Executable file
71
TP2/mainJava.ml
Executable file
|
@ -0,0 +1,71 @@
|
||||||
|
open ParserJava
|
||||||
|
|
||||||
|
(* Fonction d'affichage des unités lexicales et des données qu'elles contiennent *)
|
||||||
|
let printToken t =
|
||||||
|
(print_endline
|
||||||
|
(match t with
|
||||||
|
| IMPORT -> "import"
|
||||||
|
| IDENT (texte) -> texte
|
||||||
|
| TYPEIDENT (texte) -> texte
|
||||||
|
| INT -> "int"
|
||||||
|
| FLOAT -> "float"
|
||||||
|
| BOOL -> "bool"
|
||||||
|
| CHAR -> "char"
|
||||||
|
| VOID -> "void"
|
||||||
|
| STRING -> "String"
|
||||||
|
| ACCOUV -> "{"
|
||||||
|
| ACCFER -> "}"
|
||||||
|
| PTVIRG -> ";"
|
||||||
|
| VIRG -> ","
|
||||||
|
| PAROUV -> "("
|
||||||
|
| PARFER -> ")"
|
||||||
|
| CROOUV -> "["
|
||||||
|
| CROFER -> "]"
|
||||||
|
| SI -> "if"
|
||||||
|
| SINON -> "else"
|
||||||
|
| TANTQUE -> "while"
|
||||||
|
| RETOUR -> "return"
|
||||||
|
| ENTIER (texte) -> (string_of_int texte)
|
||||||
|
| FLOTTANT (texte) -> (string_of_float texte)
|
||||||
|
| BOOLEEN (texte) -> (string_of_bool texte)
|
||||||
|
| CARACTERE (texte) -> (String.make 1 texte)
|
||||||
|
| CHAINE (texte) -> texte
|
||||||
|
| VIDE -> "null"
|
||||||
|
| NOUVEAU -> "new"
|
||||||
|
| FIN -> "EOF"
|
||||||
|
| ASSIGN -> "="
|
||||||
|
| OPINF -> "<"
|
||||||
|
| OPSUP -> ">"
|
||||||
|
| OPINFEG -> "<="
|
||||||
|
| OPSUPEG -> ">="
|
||||||
|
| OPEG -> "=="
|
||||||
|
| OPNONEG -> "!="
|
||||||
|
| OPPLUS -> "+"
|
||||||
|
| OPMOINS -> "-"
|
||||||
|
| OPOU -> "||"
|
||||||
|
| OPMULT -> "*"
|
||||||
|
| OPMOD -> "%"
|
||||||
|
| OPDIV -> "/"
|
||||||
|
| OPET -> "&&"
|
||||||
|
| OPNON -> "!"
|
||||||
|
| OPPT -> "."));;
|
||||||
|
|
||||||
|
(* Analyse lexicale du fichier passé en paramètre de la ligne de commande *)
|
||||||
|
if (Array.length Sys.argv > 1)
|
||||||
|
then
|
||||||
|
let lexbuf = (Lexing.from_channel (open_in Sys.argv.(1))) in
|
||||||
|
let token = ref (LexerJava.main lexbuf) in
|
||||||
|
while ((!token) != FIN) do
|
||||||
|
(printToken (!token));
|
||||||
|
(token := (LexerJava.main lexbuf))
|
||||||
|
done
|
||||||
|
else
|
||||||
|
(print_endline "MainMuJava fichier");;
|
||||||
|
|
||||||
|
(* Analyse lexicale, syntaxique et sémantique du fichier passé en paramètre de la ligne de commande *)
|
||||||
|
if (Array.length Sys.argv > 1)
|
||||||
|
then
|
||||||
|
let lexbuf = (Lexing.from_channel (open_in Sys.argv.(1))) in
|
||||||
|
(ParserJava.fichier LexerJava.main lexbuf)
|
||||||
|
else
|
||||||
|
(print_endline "MainJava fichier");;
|
165
TP2/parserJava.mly
Executable file
165
TP2/parserJava.mly
Executable file
|
@ -0,0 +1,165 @@
|
||||||
|
%{
|
||||||
|
|
||||||
|
(* Partie recopiee dans le fichier CaML genere. *)
|
||||||
|
(* Ouverture de modules exploites dans les actions *)
|
||||||
|
(* Declarations de types, de constantes, de fonctions, d'exceptions exploites dans les actions *)
|
||||||
|
|
||||||
|
(* let nbrVariables = ref 0;; *)
|
||||||
|
|
||||||
|
let nbrFonctions = ref 0;;
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
/* Declaration des unites lexicales et de leur type si une valeur particuliere leur est associee */
|
||||||
|
|
||||||
|
%token IMPORT
|
||||||
|
%token <string> IDENT TYPEIDENT
|
||||||
|
%token INT FLOAT BOOL CHAR VOID STRING
|
||||||
|
%token ACCOUV ACCFER PAROUV PARFER CROOUV CROFER
|
||||||
|
%token PTVIRG VIRG
|
||||||
|
%token SI SINON TANTQUE RETOUR
|
||||||
|
/* Defini le type des donnees associees a l'unite lexicale */
|
||||||
|
%token <int> ENTIER
|
||||||
|
%token <float> FLOTTANT
|
||||||
|
%token <bool> BOOLEEN
|
||||||
|
%token <char> CARACTERE
|
||||||
|
%token <string> CHAINE
|
||||||
|
%token VIDE
|
||||||
|
%token NOUVEAU
|
||||||
|
%token ASSIGN
|
||||||
|
%token OPINF OPSUP OPINFEG OPSUPEG OPEG OPNONEG
|
||||||
|
%token OPPLUS OPMOINS OPOU
|
||||||
|
%token OPMULT OPMOD OPDIV OPET
|
||||||
|
%token OPNON
|
||||||
|
%token OPPT
|
||||||
|
/* Unite lexicale particuliere qui represente la fin du fichier */
|
||||||
|
%token FIN
|
||||||
|
|
||||||
|
/* Declarations des regles d'associative et de priorite pour les operateurs */
|
||||||
|
/* La priorite est croissante de haut en bas */
|
||||||
|
/* Associatif a droite */
|
||||||
|
%right ASSIGN /* Priorite la plus faible */
|
||||||
|
/* Non associatif */
|
||||||
|
%nonassoc OPINF OPSUP OPINFEG OPSUPEG OPEG OPNONEG
|
||||||
|
/* Associatif a gauche */
|
||||||
|
%left OPPLUS OPMOINS OPOU
|
||||||
|
%left OPMULT OPMOD OPDIV OPET
|
||||||
|
%right OPNON
|
||||||
|
%left OPPT PAROUV CROOUV /* Priorite la plus forte */
|
||||||
|
|
||||||
|
/* Type renvoye pour le nom terminal fichier */
|
||||||
|
%type <unit> fichier
|
||||||
|
%type <int> variables
|
||||||
|
|
||||||
|
/* Le non terminal fichier est l'axiome */
|
||||||
|
%start fichier
|
||||||
|
|
||||||
|
%% /* Regles de productions */
|
||||||
|
|
||||||
|
fichier : programme FIN { (print_endline "fichier : programme FIN");(print_string "Nombre de fonctions : ");(print_int !nbrFonctions);(print_newline()) }
|
||||||
|
|
||||||
|
programme : /* Lambda, mot vide */ { (nbrFonctions := 0); (print_endline "programme : /* Lambda, mot vide */") }
|
||||||
|
| fonction programme { (nbrFonctions := !nbrFonctions + 1);(print_endline "programme : fonction programme") }
|
||||||
|
|
||||||
|
typeStruct : typeBase declTab { (print_endline "typeStruct : typeBase declTab") }
|
||||||
|
|
||||||
|
typeBase : INT { (print_endline "typeBase : INT") }
|
||||||
|
| FLOAT { (print_endline "typeBase : FLOAT") }
|
||||||
|
| BOOL { (print_endline "typeBase : BOOL") }
|
||||||
|
| CHAR { (print_endline "typeBase : CHAR") }
|
||||||
|
| STRING { (print_endline "typeBase : STRING") }
|
||||||
|
| TYPEIDENT { (print_endline "typeBase : TYPEIDENT") }
|
||||||
|
|
||||||
|
declTab : /* Lambda, mot vide */ { (print_endline "declTab : /* Lambda, mot vide */") }
|
||||||
|
| CROOUV CROFER { (print_endline "declTab : CROOUV CROFER") }
|
||||||
|
|
||||||
|
fonction : entete bloc { (print_endline "fonction : entete bloc") }
|
||||||
|
|
||||||
|
entete : typeStruct IDENT PAROUV parsFormels PARFER { (print_endline "entete : typeStruct IDENT PAROUV parsFormels PARFER") }
|
||||||
|
| VOID IDENT PAROUV parsFormels PARFER { (print_endline "entete : VOID IDENT PAROUV parsFormels PARFER") }
|
||||||
|
|
||||||
|
parsFormels : /* Lambda, mot vide */ { (print_endline "parsFormels : /* Lambda, mot vide */") }
|
||||||
|
| typeStruct IDENT suiteParsFormels { (print_endline "parsFormels : typeStruct IDENT suiteParsFormels") }
|
||||||
|
|
||||||
|
suiteParsFormels : /* Lambda, mot vide */ { (print_endline "suiteParsFormels : /* Lambda, mot vide */") }
|
||||||
|
| VIRG typeStruct IDENT suiteParsFormels { (print_endline "suiteParsFormels : VIRG typeStruct IDENT suiteParsFormels") }
|
||||||
|
|
||||||
|
bloc : ACCOUV /* $1 */ variables /* $2 */ instructions /* $3 */ ACCFER /* $4 */
|
||||||
|
{
|
||||||
|
(print_endline "bloc : ACCOUV variables instructions ACCFER");
|
||||||
|
(print_string "Nombre de variables = ");
|
||||||
|
(print_int $2);
|
||||||
|
(print_newline ());
|
||||||
|
(print_string "Nombre d'instructions = ");
|
||||||
|
(print_int $3);
|
||||||
|
(print_newline ())
|
||||||
|
}
|
||||||
|
|
||||||
|
variables : /* Lambda, mot vide */ {(print_endline "variables : /* Lambda, mot vide */");0}
|
||||||
|
| variable /* $1 */ variables /* $2 */ {(print_endline "variables : variable variables");($2 + 1)}
|
||||||
|
|
||||||
|
variable : typeStruct IDENT PTVIRG { (print_endline "variable : typeStruct IDENT PTVIRG") }
|
||||||
|
|
||||||
|
instructions : /* Lambda, mot vide */ { (print_endline "instructions : /* Lambda, mot vide */");0}
|
||||||
|
| instruction /* $1 */ instructions /* $2 */ { (print_endline "instructions : instruction instructions");($2 + 1) }
|
||||||
|
|
||||||
|
/* A FAIRE : Completer pour ajouter les autres formes d'instructions */
|
||||||
|
instruction : expression PTVIRG { (print_endline "instruction : expression PTVIRG") }
|
||||||
|
| TANTQUE PAROUV expression PARFER bloc { (print_endline "instruction : TANTQUE PAROUV expression PARFER bloc") }
|
||||||
|
| RETOUR expression PTVIRG { (print_endline "instruction : RETURN expression PTVIRG") }
|
||||||
|
| SI PAROUV expression PARFER bloc else_option {(print_endline "instruction : SI PAROUV expression PARFER bloc else_option")}
|
||||||
|
|
||||||
|
expression : unaires sub_expression_1 {(print_endline "expression : unaires sub_expressions_1")}
|
||||||
|
| expression binaire expression {(print_endline "expression : expression binaire expression")}
|
||||||
|
|
||||||
|
else_option : /* Lambda, mot vide */ {(print_endline "else_option : /* Lambda, mot vide */")}
|
||||||
|
| SINON bloc {(print_endline "else_option : SINON bloc")}
|
||||||
|
|
||||||
|
sub_expression_1 : ENTIER {(print_endline "expression : ENTIER")}
|
||||||
|
| FLOTTANT {(print_endline "expression : FLOTTANT")}
|
||||||
|
| BOOLEEN {(print_endline "expression : BOOLEEN")}
|
||||||
|
| CARACTERE {(print_endline "expression : CARACTERE")}
|
||||||
|
| VIDE {(print_endline "expression : VIDE")}
|
||||||
|
| NOUVEAU IDENT sub_expression_2 {(print_endline "expression : NOUVEAU IDENT")}
|
||||||
|
| IDENT suffixes {(print_endline "expression : IDENT suffixes")}
|
||||||
|
| PAROUV expression PARFER suffixes {(print_endline "expression : PAROUV expression PARFER suffixes")}
|
||||||
|
| OPPLUS expression %prec OPNON {}
|
||||||
|
|
||||||
|
sub_expression_2 : PAROUV PARFER {(print_endline "sub_expression_2 : ( )" )}
|
||||||
|
| CROOUV expression CROFER {(print_endline "sub_expression_2 : [ expression ]" )}
|
||||||
|
|
||||||
|
binaire : ASSIGN {(print_endline "binaire : =")}
|
||||||
|
| OPINF {(print_endline "binaire : <")}
|
||||||
|
| OPSUP {(print_endline "binaire : >")}
|
||||||
|
| OPINFEG {(print_endline "binaire : <=")}
|
||||||
|
| OPSUPEG {(print_endline "binaire : >=")}
|
||||||
|
| OPEG {(print_endline "binaire : ==")}
|
||||||
|
| OPNONEG {(print_endline "binaire : !=")}
|
||||||
|
| OPPLUS {(print_endline "binaire : +")}
|
||||||
|
| OPMOINS {(print_endline "binaire : -")}
|
||||||
|
| OPOU {(print_endline "binaire : ||")}
|
||||||
|
| OPMULT {(print_endline "binaire : *")}
|
||||||
|
| OPMOD {(print_endline "binaire : %")}
|
||||||
|
| OPDIV {(print_endline "binaire : /")}
|
||||||
|
| OPET {(print_endline "binaire : &&")}
|
||||||
|
| OPPT {(print_endline "binaire : .")}
|
||||||
|
|
||||||
|
unaires : /* Lambda, mot vide */ {(print_endline "unaires : /* Lambda, mot vide */")}
|
||||||
|
| unaire unaires {(print_endline "unaires : unaire unaires")}
|
||||||
|
|
||||||
|
unaire : PAROUV typeStruct PARFER {(print_endline "unaire : ( typeStruct )")}
|
||||||
|
| OPPLUS {(print_endline "unaire : +")}
|
||||||
|
| OPMOINS {(print_endline "unaire : -")}
|
||||||
|
| OPNON {(print_endline "unaire : !")}
|
||||||
|
|
||||||
|
suffixes : /* Lambda, mot vide */ {(print_endline "suffixe : /* Lambda, mot vide */")}
|
||||||
|
| suffixe suffixes {(print_endline "suffixes : suffixe suffixes")}
|
||||||
|
|
||||||
|
suffixe : CROOUV expression CROFER {(print_endline "suffixe : CROOUV expression CROFER")}
|
||||||
|
| PAROUV sub_suffixe PARFER {(print_endline "suffixe : PAROUV sub_suffixe PARFER")}
|
||||||
|
|
||||||
|
sub_suffixe : /* Lambda, mot vide */ {(print_endline "sub_suffixe : /* Lambda, mot vide */")}
|
||||||
|
| expression {(print_endline "sub_suffixe : expression")}
|
||||||
|
| sub_suffixe VIRG sub_suffixe {(print_endline "expression : sub_suffixe binaire sub_suffixe")}
|
||||||
|
|
||||||
|
%%
|
49
TP2/tests/exemple-complique.java
Executable file
49
TP2/tests/exemple-complique.java
Executable file
|
@ -0,0 +1,49 @@
|
||||||
|
|
||||||
|
/* Cet exemple respecte la syntaxe (grammaire) de microjava, avec des
|
||||||
|
* commentaires, des chaînes complexes, des réels bizarres...
|
||||||
|
* Les constructions qui ne sont pas trait
|
||||||
|
* Ce programme est sémantiquement faux (typage en particulier)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* class Point {
|
||||||
|
private int x;
|
||||||
|
private int y;
|
||||||
|
|
||||||
|
private String toto;
|
||||||
|
|
||||||
|
// rien {
|
||||||
|
public int get_x () */
|
||||||
|
{ return x; }
|
||||||
|
// public void set_x (int _x)
|
||||||
|
{ x = _x; }
|
||||||
|
|
||||||
|
// private void essai_string ()
|
||||||
|
{
|
||||||
|
toto = "machin avec des espaces et des \" quotes
|
||||||
|
et multiligne avec echappement \n meme a la fin \\"; foo(); "et une autre chaine";
|
||||||
|
x = 3.14 + .14 + 3. + 14e-1 + .3e1;
|
||||||
|
y = 'a' + '\13' + 0x2A;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ghjd /* ****/
|
||||||
|
/* class PointColore extends Point {
|
||||||
|
public int c;
|
||||||
|
public int get_c () */
|
||||||
|
{ return c*2; }
|
||||||
|
/* } */
|
||||||
|
/*****
|
||||||
|
class PointColore extends Point **g
|
||||||
|
// dfgkhdk *f ** */
|
||||||
|
|
||||||
|
/* public class Exemple {
|
||||||
|
public static void main (String[] argv) */
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
bool b;
|
||||||
|
b = true;
|
||||||
|
if (b) {
|
||||||
|
x = 2*x + 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }
|
32
TP2/tests/exemple-simple.java
Executable file
32
TP2/tests/exemple-simple.java
Executable file
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
// Note: ce fichier ne respecte pas la *grammaire* de micro-java
|
||||||
|
// Il ne fait qu'enumerer les tokens de la grammaire.
|
||||||
|
|
||||||
|
// mot clefs
|
||||||
|
// class extends private public static main
|
||||||
|
|
||||||
|
// types
|
||||||
|
int void float bool char String
|
||||||
|
|
||||||
|
// structures de controle
|
||||||
|
if else while return
|
||||||
|
|
||||||
|
// instructions
|
||||||
|
new null
|
||||||
|
|
||||||
|
// operateurs
|
||||||
|
< > >= <= == !=
|
||||||
|
+ - / * % && || ! = .
|
||||||
|
|
||||||
|
// parentheses
|
||||||
|
( [ { } ] )
|
||||||
|
|
||||||
|
// separateurs
|
||||||
|
, ;
|
||||||
|
|
||||||
|
// constantes
|
||||||
|
true false 0 245 1_234_567 0b1101 0B1_0100_1100 077 01_345 0xFF 0X1_FF00_1234 'a' 567.34 1e-5 .12
|
||||||
|
"bonjour"
|
||||||
|
|
||||||
|
// noms
|
||||||
|
x toto Point
|
3
TP2/tests/exemple-tres-simple.java
Executable file
3
TP2/tests/exemple-tres-simple.java
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
, /* test */ int while // ceci est un autre test
|
||||||
|
" te \" st "
|
||||||
|
123
|
2
TP2/tests/exemple.java
Executable file
2
TP2/tests/exemple.java
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
453 while 45, 4, 8
|
||||||
|
int 4 int while , 8
|
3
TP2/tests/test.java
Executable file
3
TP2/tests/test.java
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
//
|
||||||
|
index + 000123
|
||||||
|
|
30
TP2/tests/test00.java
Executable file
30
TP2/tests/test00.java
Executable file
|
@ -0,0 +1,30 @@
|
||||||
|
void f() {
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
return 1.0 = 2 + 3 - 4 * 5 / 6 % 7 || 8 && 9 == 10 != 11 < 12 > 13 <= 14 >= 15;
|
||||||
|
|
||||||
|
-3.14;
|
||||||
|
null;
|
||||||
|
new bonjour();
|
||||||
|
new entiers[10];
|
||||||
|
|
||||||
|
test(a, b, c, d);
|
||||||
|
tableau[13];
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (10 == 3) {
|
||||||
|
int k;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (1) {
|
||||||
|
2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void deuxieme() {
|
||||||
|
int k;
|
||||||
|
}
|
145
TP3/A_FAIRE.txt
Executable file
145
TP3/A_FAIRE.txt
Executable file
|
@ -0,0 +1,145 @@
|
||||||
|
TP Outils Mathématiques Informatique : Analyse Syntaxique par Descente Récursive
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
Le but de ce TP est d'apprendre à écrire un analyseur syntaxique
|
||||||
|
descendant récursif et à le tester.
|
||||||
|
|
||||||
|
Nous allons dans une première étape traiter le cas de la grammaire manipulée
|
||||||
|
en TD, puis nous étendrons celle-ci :
|
||||||
|
|
||||||
|
A/ La syntaxe du langage est un sous ensemble des expressions en CaML :
|
||||||
|
|
||||||
|
E est l'axiome.
|
||||||
|
|
||||||
|
E -> ER = E
|
||||||
|
E -> ER
|
||||||
|
ER -> ER + T
|
||||||
|
ER -> ER - T
|
||||||
|
ER -> T
|
||||||
|
T -> T * F
|
||||||
|
T -> T / F
|
||||||
|
T -> F
|
||||||
|
F -> - F
|
||||||
|
F -> ( E )
|
||||||
|
F -> ident
|
||||||
|
F -> true
|
||||||
|
F -> false
|
||||||
|
F -> number
|
||||||
|
|
||||||
|
Voici une grammaire LL(1) possible (vous pouvez aussi partir de celle proposée
|
||||||
|
en TD pour les expressions de bloc) :
|
||||||
|
|
||||||
|
E -> ER EX - ( ident true false number
|
||||||
|
EX -> = ER EX =
|
||||||
|
EX -> ) $
|
||||||
|
ER -> T TX - ( ident true false number
|
||||||
|
TX -> + T TX +
|
||||||
|
TX -> - T TX -
|
||||||
|
TX -> = ) $
|
||||||
|
T -> F FX - ( ident true false number
|
||||||
|
FX -> * F FX *
|
||||||
|
FX -> / F FX /
|
||||||
|
FX -> + - = ) $
|
||||||
|
F -> - F -
|
||||||
|
F -> ( E ) (
|
||||||
|
F -> ident ident
|
||||||
|
F -> true true
|
||||||
|
F -> false false
|
||||||
|
F -> number number
|
||||||
|
|
||||||
|
1) Écrire quelques programmes de test respectant la syntaxe de miniml.
|
||||||
|
|
||||||
|
2) L'analyseur lexical étant fourni (généré par camllex à partir du
|
||||||
|
fichier Scanner.mll), écrire un analyseur descendant récursif pour
|
||||||
|
miniml dans le fichier Syntax.ml, suivant le principe étudié en TD.
|
||||||
|
|
||||||
|
La compilation est effectuée par la commande : dune build Main.exe
|
||||||
|
|
||||||
|
3) Tester cet analyseur syntaxique.
|
||||||
|
|
||||||
|
================================================================
|
||||||
|
B/ Simplification de l'analyseur par notation monadique
|
||||||
|
|
||||||
|
L'analyseur développé dans l'exercice précédent est relativement complexe à
|
||||||
|
cause de la gestion des succès/échec et de la transmission de la liste des
|
||||||
|
terminaux en cours d'analyse.
|
||||||
|
|
||||||
|
Il est possible de simplifier la programmation en utilisant une notation
|
||||||
|
monadique pour factoriser ce traitement répétitif.
|
||||||
|
|
||||||
|
Celle-ci est composée de trois parties :
|
||||||
|
- le type de donnée monadique : parseResult
|
||||||
|
- la fonction : inject qui construit ce type à partir d'une liste de terminaux
|
||||||
|
- la fonction : bind (opérateur >>=) qui combine les fonctions d'analyse.
|
||||||
|
|
||||||
|
1) Étudier le fichier SyntaxMonad.ml qui implante le même analyseur
|
||||||
|
que l'exercice A/ en utilisant cette notation.
|
||||||
|
|
||||||
|
La compilation est effectuée par la commande : dune build MainMonad.exe
|
||||||
|
|
||||||
|
================================================================
|
||||||
|
C/ La syntaxe du langage étendue sera celle d'un mini CaML.
|
||||||
|
|
||||||
|
E0 est l'axiome.
|
||||||
|
|
||||||
|
Nous avons mis en évidence les nouvelles règles et les règles modifiées.
|
||||||
|
|
||||||
|
* E0 -> function ident -> E0
|
||||||
|
* E0 -> let ident = E0 in E0
|
||||||
|
* E0 -> letrec ident = E0 in E0
|
||||||
|
* E0 -> if E0 then E0 else E0
|
||||||
|
* E0 -> E
|
||||||
|
E -> ER = E
|
||||||
|
E -> ER
|
||||||
|
ER -> ER + T
|
||||||
|
ER -> ER - T
|
||||||
|
ER -> T
|
||||||
|
T -> T * F
|
||||||
|
T -> T / F
|
||||||
|
T -> F
|
||||||
|
F -> - F
|
||||||
|
* F -> ( E0 )
|
||||||
|
* F -> ( E0 ) (E0)
|
||||||
|
F -> ident
|
||||||
|
* F -> ident (E0)
|
||||||
|
F -> true
|
||||||
|
F -> false
|
||||||
|
F -> number
|
||||||
|
|
||||||
|
1) Écrire quelques programmes de test respectant la syntaxe de miniml.
|
||||||
|
|
||||||
|
2) Cette grammaire n'est pas LL(1), factoriser celle-ci et éliminer la
|
||||||
|
récursivité à gauche.
|
||||||
|
|
||||||
|
LL(1)
|
||||||
|
E0 -> function ident -> E0
|
||||||
|
E0 -> let ident = E0 in E0
|
||||||
|
E0 -> letrec ident = E0 in E0
|
||||||
|
E0 -> if E0 then E0 else E0
|
||||||
|
E0 -> E
|
||||||
|
E -> ER = E
|
||||||
|
E -> ER
|
||||||
|
ER -> T EY
|
||||||
|
EY -> + T EY
|
||||||
|
EY -> - T EY
|
||||||
|
EY ->
|
||||||
|
T -> F TY
|
||||||
|
TY -> * F TY
|
||||||
|
TY -> / F TY
|
||||||
|
TY ->
|
||||||
|
F -> - F
|
||||||
|
F -> ( E0 )
|
||||||
|
F -> ( E0 ) (E0)
|
||||||
|
F -> ident
|
||||||
|
F -> ident (E0)
|
||||||
|
F -> true
|
||||||
|
F -> false
|
||||||
|
F -> number
|
||||||
|
|
||||||
|
3) L'analyseur lexical étant fourni (généré par camllex à partir du
|
||||||
|
fichier Scanner.mll), écrire un analyseur descendant récursif pour
|
||||||
|
miniML en exploitant la technique monadique présentée dans
|
||||||
|
l'exercice précédent, vous modifierez pour cela le fichier
|
||||||
|
SyntaxMonad.ml.
|
||||||
|
|
||||||
|
4) Tester cet analyseur syntaxique.
|
88
TP3/Lex.ml
Executable file
88
TP3/Lex.ml
Executable file
|
@ -0,0 +1,88 @@
|
||||||
|
(* open List *)
|
||||||
|
|
||||||
|
type token =
|
||||||
|
| EOSToken
|
||||||
|
| FunctionToken
|
||||||
|
| BodyToken
|
||||||
|
| IfToken
|
||||||
|
| ThenToken
|
||||||
|
| ElseToken
|
||||||
|
| LetToken
|
||||||
|
| InToken
|
||||||
|
| TrueToken
|
||||||
|
| FalseToken
|
||||||
|
| RecToken
|
||||||
|
| IdentToken of string
|
||||||
|
| NumberToken of int
|
||||||
|
| EqualToken
|
||||||
|
| DifferentToken
|
||||||
|
| LesserToken
|
||||||
|
| GreaterToken
|
||||||
|
| LesserEqualToken
|
||||||
|
| GreaterEqualToken
|
||||||
|
| PlusToken
|
||||||
|
| MinusToken
|
||||||
|
| TimesToken
|
||||||
|
| DivideToken
|
||||||
|
| LeftParenthesisToken
|
||||||
|
| RightParenthesisToken
|
||||||
|
;;
|
||||||
|
|
||||||
|
type inputStream = token list;;
|
||||||
|
|
||||||
|
(* string_of_token : token -> string *)
|
||||||
|
(* Converti un token en une chaîne de caractère*)
|
||||||
|
let string_of_token token =
|
||||||
|
match token with
|
||||||
|
| EOSToken -> "$"
|
||||||
|
| FunctionToken -> "function"
|
||||||
|
| BodyToken -> "->"
|
||||||
|
| IfToken -> "if"
|
||||||
|
| ThenToken -> "then"
|
||||||
|
| ElseToken -> "else"
|
||||||
|
| LetToken -> "let"
|
||||||
|
| InToken -> "in"
|
||||||
|
| TrueToken -> "true"
|
||||||
|
| FalseToken -> "false"
|
||||||
|
| RecToken -> "letrec"
|
||||||
|
| NumberToken xxx -> string_of_int xxx
|
||||||
|
| IdentToken name -> name
|
||||||
|
| EqualToken -> "="
|
||||||
|
| DifferentToken -> "!="
|
||||||
|
| LesserToken -> "<"
|
||||||
|
| GreaterToken -> ">"
|
||||||
|
| LesserEqualToken -> "<="
|
||||||
|
| GreaterEqualToken -> ">="
|
||||||
|
| PlusToken -> "+"
|
||||||
|
| MinusToken -> "-"
|
||||||
|
| TimesToken -> "*"
|
||||||
|
| DivideToken -> "/"
|
||||||
|
| LeftParenthesisToken -> "("
|
||||||
|
| RightParenthesisToken -> ")"
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* string_of_stream : inputStream -> string *)
|
||||||
|
(* Converti un inputStream (liste de token) en une chaîne de caractère *)
|
||||||
|
let string_of_stream stream =
|
||||||
|
List.fold_right (fun t tq -> (string_of_token t) ^ " " ^ tq ) stream "";;
|
||||||
|
|
||||||
|
|
||||||
|
(* peekAtFirstToken : inputStream -> token *)
|
||||||
|
(* Renvoie le premier élément d'un inputStream *)
|
||||||
|
(* Erreur : si l'inputStream est vide *)
|
||||||
|
let peekAtFirstToken stream =
|
||||||
|
match stream with
|
||||||
|
(* Normalement, ne doit jamais se produire sauf si la grammaire essaie de lire *)
|
||||||
|
(* après la fin de l'inputStream. *)
|
||||||
|
| [] -> failwith "Impossible d'acceder au premier element d'un inputStream vide"
|
||||||
|
|t::_ -> t;;
|
||||||
|
|
||||||
|
(* advanceInStream : inputStream -> inputStream *)
|
||||||
|
(* Consomme le premier élément d'un inputStream *)
|
||||||
|
(* Erreur : si l'inputStream est vide *)
|
||||||
|
let advanceInStream stream =
|
||||||
|
match stream with
|
||||||
|
(* Normalement, ne doit jamais se produire sauf si la grammaire essaie de lire *)
|
||||||
|
(* après la fin de l'inputStream. *)
|
||||||
|
| [] -> failwith "Impossible de consommer le premier element d'un inputStream vide"
|
||||||
|
| _::q -> q;;
|
22
TP3/Main.ml
Executable file
22
TP3/Main.ml
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
open Lex
|
||||||
|
open Scanner
|
||||||
|
open Syntax
|
||||||
|
|
||||||
|
(* main : unit -> unit *)
|
||||||
|
(* Analyse le contenu d'un fichier passé en paramètre ou l'entrée standard si aucun fichier n'est donné *)
|
||||||
|
(* Affiche OK si l'analyse syntaxique c'est bien passée et KO sinon *)
|
||||||
|
let main () =
|
||||||
|
let cin =
|
||||||
|
if Array.length Sys.argv > 1 then
|
||||||
|
open_in Sys.argv.(1)
|
||||||
|
else
|
||||||
|
stdin
|
||||||
|
in
|
||||||
|
let lexbuf = Lexing.from_channel cin in
|
||||||
|
match (parseE (scanner lexbuf))
|
||||||
|
with
|
||||||
|
| Success [EOSToken] -> print_endline "Ok"
|
||||||
|
| _ -> print_endline "Ko"
|
||||||
|
;;
|
||||||
|
|
||||||
|
main();;
|
22
TP3/MainMonad.ml
Executable file
22
TP3/MainMonad.ml
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
open Lex
|
||||||
|
open Scanner
|
||||||
|
open SyntaxMonad
|
||||||
|
|
||||||
|
(* main : unit -> unit *)
|
||||||
|
(* Analyse le contenu d'un fichier passé en paramètre ou l'entrée standard si aucun fichier n'est donné *)
|
||||||
|
(* Affiche OK si l'analyse syntaxique c'est bien passée et KO sinon *)
|
||||||
|
let main () =
|
||||||
|
let cin =
|
||||||
|
if Array.length Sys.argv > 1 then
|
||||||
|
open_in Sys.argv.(1)
|
||||||
|
else
|
||||||
|
stdin
|
||||||
|
in
|
||||||
|
let lexbuf = Lexing.from_channel cin in
|
||||||
|
match (parseE (scanner lexbuf))
|
||||||
|
with
|
||||||
|
| Success [EOSToken] -> print_endline "Ok"
|
||||||
|
| _ -> print_endline "Ko"
|
||||||
|
;;
|
||||||
|
|
||||||
|
main();;
|
118
TP3/Scanner.mll
Executable file
118
TP3/Scanner.mll
Executable file
|
@ -0,0 +1,118 @@
|
||||||
|
{
|
||||||
|
open Lex
|
||||||
|
open Printf
|
||||||
|
}
|
||||||
|
|
||||||
|
let digit = ['0'-'9']
|
||||||
|
let id = ['a'-'z'] ['a'-'z' '0'-'9']*
|
||||||
|
|
||||||
|
rule scanner = parse
|
||||||
|
| [' ' '\t' '\n' '\r'] { (scanner lexbuf) } (* eat up whitespace *)
|
||||||
|
| '('
|
||||||
|
{
|
||||||
|
LeftParenthesisToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| ')'
|
||||||
|
{
|
||||||
|
RightParenthesisToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| '='
|
||||||
|
{
|
||||||
|
EqualToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| "!="
|
||||||
|
{
|
||||||
|
DifferentToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| '='
|
||||||
|
{
|
||||||
|
EqualToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| '<'
|
||||||
|
{
|
||||||
|
LesserToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| '>'
|
||||||
|
{
|
||||||
|
GreaterToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| "<="
|
||||||
|
{
|
||||||
|
LesserEqualToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| ">="
|
||||||
|
{
|
||||||
|
GreaterEqualToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| '+'
|
||||||
|
{
|
||||||
|
PlusToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| '-'
|
||||||
|
{
|
||||||
|
MinusToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| '*'
|
||||||
|
{
|
||||||
|
TimesToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| '/'
|
||||||
|
{
|
||||||
|
DivideToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| "->"
|
||||||
|
{
|
||||||
|
BodyToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| "function"
|
||||||
|
{
|
||||||
|
FunctionToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| "if"
|
||||||
|
{
|
||||||
|
IfToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| "then"
|
||||||
|
{
|
||||||
|
ThenToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| "else"
|
||||||
|
{
|
||||||
|
ElseToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| "let"
|
||||||
|
{
|
||||||
|
LetToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| "in"
|
||||||
|
{
|
||||||
|
InToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| "letrec"
|
||||||
|
{
|
||||||
|
RecToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| "true"
|
||||||
|
{
|
||||||
|
TrueToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| "false"
|
||||||
|
{
|
||||||
|
FalseToken :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| digit+ as inum
|
||||||
|
{
|
||||||
|
(NumberToken (int_of_string inum)) :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| id as text
|
||||||
|
{
|
||||||
|
(IdentToken ("\"" ^ text ^"\"")) :: (scanner lexbuf)
|
||||||
|
}
|
||||||
|
| _ as c
|
||||||
|
{ printf "Unrecognized character: %c\n" c;
|
||||||
|
(scanner lexbuf)
|
||||||
|
}
|
||||||
|
| eof {[ EOSToken ] }
|
||||||
|
|
||||||
|
{
|
||||||
|
}
|
209
TP3/Syntax.ml
Executable file
209
TP3/Syntax.ml
Executable file
|
@ -0,0 +1,209 @@
|
||||||
|
open Lex
|
||||||
|
|
||||||
|
type parseResult =
|
||||||
|
| Success of inputStream
|
||||||
|
| Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(*
|
||||||
|
E -> ER = E
|
||||||
|
E -> ER
|
||||||
|
ER -> ER + T
|
||||||
|
ER -> ER - T
|
||||||
|
ER -> T
|
||||||
|
T -> T * F
|
||||||
|
T -> T / F
|
||||||
|
T -> F
|
||||||
|
F -> - F
|
||||||
|
F -> ( E )
|
||||||
|
F -> ident
|
||||||
|
F -> true
|
||||||
|
F -> false
|
||||||
|
F -> number
|
||||||
|
*)
|
||||||
|
|
||||||
|
(*
|
||||||
|
LL(1) Règle de production / Symboles directeurs
|
||||||
|
#1 - E -> function ident fleche E { function }
|
||||||
|
#2 - E -> if E then E else E { if }
|
||||||
|
#5 - E -> ER EX | { -, number, ident, true, false, ( }
|
||||||
|
#6 - EX -> = ER EX | { = }
|
||||||
|
#7 - EX -> | { $, ), then, else }
|
||||||
|
#8 - ER -> T TX | { -, number, ident, true, false, ( }
|
||||||
|
#9 - TX -> + T TX | { + }
|
||||||
|
#10 - TX -> - T TX | { - }
|
||||||
|
#11 - TX -> | { $, =, ), then, else }
|
||||||
|
#12 - T -> F FX | { -, number, ident, true, false, ( }
|
||||||
|
#13 - FX -> * F FX | { * }
|
||||||
|
#14 - FX -> / F FX | { / }
|
||||||
|
#15 - FX -> | { $, +, -, =, ), then, else }
|
||||||
|
#16 - F -> - F | { - }
|
||||||
|
#17 - F -> number | { number }
|
||||||
|
#20 - F -> ident | { ident }
|
||||||
|
#21 - F -> true | { true }
|
||||||
|
#22 - F -> false | { false }
|
||||||
|
#23 - F -> ( E ) | { ( }
|
||||||
|
*)
|
||||||
|
|
||||||
|
(* accept : token -> inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien le token attendu *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let accept expected stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| token when (token = expected) ->
|
||||||
|
(print_endline (string_of_token token));
|
||||||
|
(Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* acceptIdent : inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien un identifiant *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let acceptIdent stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| (IdentToken nom) ->
|
||||||
|
(print_endline nom);
|
||||||
|
(Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* acceptNumber : inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien un nombre *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let acceptNumber stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| (NumberToken _) -> (Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* parseE : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal E *)
|
||||||
|
let rec parseE stream =
|
||||||
|
(*
|
||||||
|
(print_endline (string_of_stream stream));
|
||||||
|
*)
|
||||||
|
(print_endline "E");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle #5 - E -> ER EX | { -, number, ident, true, false, ( } *)
|
||||||
|
(* Symboles directeurs *)
|
||||||
|
| (IdentToken _) | (NumberToken _) | TrueToken | FalseToken |
|
||||||
|
MinusToken | LeftParenthesisToken ->
|
||||||
|
(* Regle *)
|
||||||
|
(* Analyse ER *)
|
||||||
|
(match (parseER stream) with
|
||||||
|
| (Success next) ->
|
||||||
|
(* En cas de succes, analyse EX *)
|
||||||
|
parseEX next
|
||||||
|
| _ -> Failure)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseEX : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal EX *)
|
||||||
|
and parseEX stream =
|
||||||
|
(print_endline "EX");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle #6 - EX -> = ER EX | { = } *)
|
||||||
|
| EqualToken -> (match (accept EqualToken stream) with
|
||||||
|
| Success next -> (match (parseER next) with
|
||||||
|
| Success next2 -> (parseEX next2)
|
||||||
|
| _ -> Failure)
|
||||||
|
| _ -> Failure)
|
||||||
|
(* regle #7 - EX -> | { $, ) } *)
|
||||||
|
| EOSToken | RightParenthesisToken | ThenToken | ElseToken -> (Success stream)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseER : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal ER *)
|
||||||
|
and parseER stream =
|
||||||
|
(print_endline "ER");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle #8 - ER -> T TX | { -, number, ident, true, false, ( } *)
|
||||||
|
| (IdentToken _) | (NumberToken _) | TrueToken | FalseToken | MinusToken | LeftParenthesisToken ->
|
||||||
|
(match (parseT stream) with
|
||||||
|
| Success next -> (parseTX next)
|
||||||
|
| _ -> Failure)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseTX : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal TX *)
|
||||||
|
and parseTX stream =
|
||||||
|
(print_endline "TX");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle #9 - TX -> + T TX | { + } *)
|
||||||
|
| PlusToken -> (match (accept PlusToken stream) with
|
||||||
|
| Success next -> (
|
||||||
|
match (parseT next) with
|
||||||
|
| Success next -> (parseTX next)
|
||||||
|
| _ -> Failure)
|
||||||
|
| _ -> Failure)
|
||||||
|
(* regle #10 - TX -> - T TX | { - } *)
|
||||||
|
| MinusToken -> (match (accept MinusToken stream) with
|
||||||
|
| Success next -> (
|
||||||
|
match (parseT next) with
|
||||||
|
| Success next -> (parseTX next)
|
||||||
|
| _ -> Failure)
|
||||||
|
| _ -> Failure)
|
||||||
|
(* regle #11 - TX -> | { $, =, ) } *)
|
||||||
|
| EOSToken | EqualToken | RightParenthesisToken -> Success stream
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseT : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal T *)
|
||||||
|
and parseT stream =
|
||||||
|
(print_endline "T");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle #12 - T -> F FX | { -, number, ident, true, false, ( } *)
|
||||||
|
| (IdentToken _) | (NumberToken _) | TrueToken | FalseToken |
|
||||||
|
MinusToken | LeftParenthesisToken -> (match (parseF stream) with
|
||||||
|
| Success next -> (parseFX next)
|
||||||
|
| _ -> Failure)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseFX : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal FX *)
|
||||||
|
and parseFX stream =
|
||||||
|
(print_endline "FX");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle #13 - FX -> * F FX | { * } *)
|
||||||
|
| TimesToken -> (match (accept TimesToken stream) with
|
||||||
|
| Success next -> (
|
||||||
|
match (parseF next) with
|
||||||
|
| Success next -> (parseFX next)
|
||||||
|
| _ -> Failure)
|
||||||
|
| _ -> Failure)
|
||||||
|
(* regle #14 - FX -> / F FX | { / } *)
|
||||||
|
| DivideToken -> (match (accept DivideToken stream) with
|
||||||
|
| Success next -> (
|
||||||
|
match (parseF next) with
|
||||||
|
| Success next -> (parseFX next)
|
||||||
|
| _ -> Failure)
|
||||||
|
| _ -> Failure)
|
||||||
|
(* regle #15 - FX -> | { $, +, -, =, ) } *)
|
||||||
|
| EOSToken | PlusToken | MinusToken | EqualToken | RightParenthesisToken -> (Success stream)
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseF : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal F *)
|
||||||
|
and parseF stream =
|
||||||
|
(print_endline "F");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle #16 - F -> - F | { - } *)
|
||||||
|
| MinusToken -> (match (accept MinusToken stream) with
|
||||||
|
| Success next -> (parseF next)
|
||||||
|
| _ -> Failure)
|
||||||
|
(* regle #17 - F -> number | { number } *)
|
||||||
|
| NumberToken _ -> (acceptNumber stream)
|
||||||
|
(* regle #20 - F -> ident | { ident } *)
|
||||||
|
| IdentToken _ -> (acceptIdent stream)
|
||||||
|
(* regle #21 - F -> true | { true } *)
|
||||||
|
| TrueToken -> (accept TrueToken stream)
|
||||||
|
(* regle #22 - F -> false | { false } *)
|
||||||
|
| FalseToken -> (accept FalseToken stream)
|
||||||
|
(* regle #23 - F -> ( E ) | { ( } *)
|
||||||
|
| LeftParenthesisToken -> (match (accept LeftParenthesisToken stream) with
|
||||||
|
| Success next -> (match (parseE next) with
|
||||||
|
| Success next2 -> (accept RightParenthesisToken next2)
|
||||||
|
| _ -> Failure)
|
||||||
|
| _ -> Failure)
|
||||||
|
| _ -> Failure)
|
||||||
|
;;
|
288
TP3/SyntaxMonad.ml
Executable file
288
TP3/SyntaxMonad.ml
Executable file
|
@ -0,0 +1,288 @@
|
||||||
|
open Lex
|
||||||
|
|
||||||
|
type parseResult =
|
||||||
|
| Success of inputStream
|
||||||
|
| Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(*
|
||||||
|
LL(1)
|
||||||
|
#01 - E0 -> function ident -> E0
|
||||||
|
#02 - E0 -> let ident = E0 in E0
|
||||||
|
#03 - E0 -> letrec ident = E0 in E0
|
||||||
|
#04 - E0 -> if E0 then E0 else E0
|
||||||
|
#05 - E0 -> F TY EY EX
|
||||||
|
#06 - EX -> = F TY EY EX
|
||||||
|
#07 - EX ->
|
||||||
|
#08 - EY -> + F TY EY
|
||||||
|
#09 - EY -> - F TY EY
|
||||||
|
#10 - EY ->
|
||||||
|
#11 - TY -> * F TY
|
||||||
|
#12 - TY -> / F TY
|
||||||
|
#13 - TY ->
|
||||||
|
#14 - F -> - F
|
||||||
|
#15 - F -> ( E0 ) FX
|
||||||
|
#16 - F -> ident FX
|
||||||
|
#17 - F -> true
|
||||||
|
#18 - F -> false
|
||||||
|
#19 - F -> number
|
||||||
|
#20 - FX -> ( E0 )
|
||||||
|
#21 - FX ->
|
||||||
|
*)
|
||||||
|
|
||||||
|
(* accept : token -> inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien le token attendu *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let accept expected stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| token when (token = expected) ->
|
||||||
|
(print_endline (string_of_token token)); (Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* acceptIdent : inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien un identifiant *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let acceptIdent stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| (IdentToken _) -> (Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* acceptNumber : inputStream -> parseResult *)
|
||||||
|
(* Vérifie que le premier token du flux d'entrée est bien un nombre *)
|
||||||
|
(* et avance dans l'analyse si c'est le cas *)
|
||||||
|
let acceptNumber stream =
|
||||||
|
match (peekAtFirstToken stream) with
|
||||||
|
| (NumberToken _) -> (Success (advanceInStream stream))
|
||||||
|
| _ -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
(* Définition de la monade qui est composée de : *)
|
||||||
|
(* - le type de donnée monadique : parseResult *)
|
||||||
|
(* - la fonction : inject qui construit ce type à partir d'une liste de terminaux *)
|
||||||
|
(* - la fonction : bind (opérateur >>=) qui combine les fonctions d'analyse. *)
|
||||||
|
|
||||||
|
(* inject inputStream -> parseResult *)
|
||||||
|
(* Construit le type de la monade à partir d'une liste de terminaux *)
|
||||||
|
let inject s = Success s;;
|
||||||
|
|
||||||
|
(* bind : 'a m -> ('a -> 'b m) -> 'b m *)
|
||||||
|
(* bind (opérateur >>=) qui combine les fonctions d'analyse. *)
|
||||||
|
(* ici on utilise une version spécialisée de bind :
|
||||||
|
'b -> inputStream
|
||||||
|
'a -> inputStream
|
||||||
|
m -> parseResult
|
||||||
|
*)
|
||||||
|
(* >>= : parseResult -> (inputStream -> parseResult) -> parseResult *)
|
||||||
|
let (>>=) result f =
|
||||||
|
match result with
|
||||||
|
| Success next -> f next
|
||||||
|
| Failure -> Failure
|
||||||
|
;;
|
||||||
|
|
||||||
|
|
||||||
|
(* parseE0 : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal E0 *)
|
||||||
|
let rec parseE0 stream =
|
||||||
|
(*
|
||||||
|
(print_endline (string_of_stream stream));
|
||||||
|
*)
|
||||||
|
(print_endline "E0");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle #1 *)
|
||||||
|
| FunctionToken ->
|
||||||
|
inject stream >>=
|
||||||
|
accept FunctionToken >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
accept BodyToken >>=
|
||||||
|
parseE0
|
||||||
|
(* regle #2 *)
|
||||||
|
| LetToken ->
|
||||||
|
inject stream >>=
|
||||||
|
accept LetToken >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
accept EqualToken >>=
|
||||||
|
parseE0 >>=
|
||||||
|
accept InToken >>=
|
||||||
|
parseE0
|
||||||
|
(* regle #3 *)
|
||||||
|
| RecToken ->
|
||||||
|
inject stream >>=
|
||||||
|
accept RecToken >>=
|
||||||
|
acceptIdent >>=
|
||||||
|
accept EqualToken >>=
|
||||||
|
parseE0 >>=
|
||||||
|
accept InToken >>=
|
||||||
|
parseE0
|
||||||
|
(* regle #4 if E then E else E *)
|
||||||
|
| IfToken ->
|
||||||
|
inject stream >>=
|
||||||
|
accept IfToken >>=
|
||||||
|
parseE0 >>=
|
||||||
|
accept ThenToken >>=
|
||||||
|
parseE0 >>=
|
||||||
|
accept ElseToken >>=
|
||||||
|
parseE0
|
||||||
|
(* regle #5 *)
|
||||||
|
| ((IdentToken _) | (NumberToken _) | TrueToken | FalseToken | MinusToken | LeftParenthesisToken ) ->
|
||||||
|
inject stream >>=
|
||||||
|
parseF >>=
|
||||||
|
parseTY >>=
|
||||||
|
parseEY >>=
|
||||||
|
parseEX
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseEX : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal EX *)
|
||||||
|
and parseE stream =
|
||||||
|
(print_endline "EX");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle #6 *)
|
||||||
|
| EqualToken ->
|
||||||
|
inject stream >>=
|
||||||
|
accept EqualToken >>=
|
||||||
|
parseF >>=
|
||||||
|
parseTY >>=
|
||||||
|
parseEY >>=
|
||||||
|
parseEX
|
||||||
|
(* regle #7 *)
|
||||||
|
| (RightParenthesisToken | ElseToken | ThenToken | InToken) ->
|
||||||
|
inject stream
|
||||||
|
| EOSToken ->
|
||||||
|
inject stream
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseER : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal ER *)
|
||||||
|
and parseER stream =
|
||||||
|
(print_endline "ER");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle #8 *)
|
||||||
|
| ((IdentToken _) | (NumberToken _) | TrueToken | FalseToken | MinusToken | LeftParenthesisToken) ->
|
||||||
|
inject stream >>=
|
||||||
|
parseT >>=
|
||||||
|
parseTX
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseTX : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal TX *)
|
||||||
|
and parseTX stream =
|
||||||
|
(print_endline "TX");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle 9 *)
|
||||||
|
| PlusToken ->
|
||||||
|
inject stream >>=
|
||||||
|
accept PlusToken >>=
|
||||||
|
parseT >>=
|
||||||
|
parseTX
|
||||||
|
(* regle 10 *)
|
||||||
|
| MinusToken ->
|
||||||
|
inject stream >>=
|
||||||
|
accept MinusToken >>=
|
||||||
|
parseT >>=
|
||||||
|
parseTX
|
||||||
|
(* regle 11 *)
|
||||||
|
| (RightParenthesisToken | EqualToken | ElseToken | ThenToken | InToken) -> inject stream
|
||||||
|
| EOSToken -> inject stream
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseT : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal T *)
|
||||||
|
and parseT stream =
|
||||||
|
(print_endline "T");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle 12 *)
|
||||||
|
| ((IdentToken _) | (NumberToken _) | TrueToken | FalseToken | MinusToken | LeftParenthesisToken) ->
|
||||||
|
inject stream >>=
|
||||||
|
parseF >>=
|
||||||
|
parseFX
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseFX : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal FX *)
|
||||||
|
and parseFX stream =
|
||||||
|
(print_endline "FX");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle 13 *)
|
||||||
|
| TimesToken ->
|
||||||
|
inject stream >>=
|
||||||
|
accept TimesToken >>=
|
||||||
|
parseF >>=
|
||||||
|
parseFX
|
||||||
|
(* regle 14 *)
|
||||||
|
| DivideToken ->
|
||||||
|
inject stream >>=
|
||||||
|
accept DivideToken >>=
|
||||||
|
parseF >>=
|
||||||
|
parseFX
|
||||||
|
(* regle 15 *)
|
||||||
|
| (RightParenthesisToken | EqualToken | PlusToken | MinusToken | ElseToken | ThenToken | InToken) ->
|
||||||
|
inject stream
|
||||||
|
| EOSToken -> inject stream
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseF : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal F *)
|
||||||
|
and parseF stream =
|
||||||
|
(print_endline "F");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle 16 *)
|
||||||
|
| MinusToken ->
|
||||||
|
inject stream >>=
|
||||||
|
accept MinusToken >>=
|
||||||
|
parseF
|
||||||
|
(* regle 17 *)
|
||||||
|
| (NumberToken _) ->
|
||||||
|
inject stream >>=
|
||||||
|
acceptNumber
|
||||||
|
(* regle 20 *)
|
||||||
|
| ((IdentToken _) | LeftParenthesisToken) ->
|
||||||
|
inject stream >>=
|
||||||
|
parseFF >>=
|
||||||
|
parseARG
|
||||||
|
(* regle 21 *)
|
||||||
|
| TrueToken ->
|
||||||
|
inject stream >>=
|
||||||
|
accept TrueToken
|
||||||
|
(* regle 22 *)
|
||||||
|
| FalseToken ->
|
||||||
|
inject stream >>=
|
||||||
|
accept FalseToken
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseFF : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal FF *)
|
||||||
|
and parseFF stream =
|
||||||
|
(print_endline "FF");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle 23 ( E ) *)
|
||||||
|
| LeftParenthesisToken ->
|
||||||
|
inject stream >>=
|
||||||
|
accept LeftParenthesisToken >>=
|
||||||
|
parseE >>=
|
||||||
|
accept RightParenthesisToken
|
||||||
|
(* regle 24 *)
|
||||||
|
| IdentToken _ ->
|
||||||
|
inject stream >>=
|
||||||
|
acceptIdent
|
||||||
|
| _ -> Failure)
|
||||||
|
|
||||||
|
(* parseARG : inputStream -> parseResult *)
|
||||||
|
(* Analyse du non terminal ARG *)
|
||||||
|
and parseARG stream =
|
||||||
|
(print_endline "ARG");
|
||||||
|
(match (peekAtFirstToken stream) with
|
||||||
|
(* regle 25 - ARG -> ( E ) *)
|
||||||
|
| LeftParenthesisToken ->
|
||||||
|
inject stream >>=
|
||||||
|
accept LeftParenthesisToken >>=
|
||||||
|
parseE >>=
|
||||||
|
accept RightParenthesisToken
|
||||||
|
(* regle 26 - ARG -> *)
|
||||||
|
| (RightParenthesisToken | EqualToken | PlusToken | MinusToken | ElseToken | ThenToken | InToken | TimesToken | DivideToken ) ->
|
||||||
|
inject stream
|
||||||
|
| EOSToken ->
|
||||||
|
inject stream
|
||||||
|
| _ -> Failure)
|
||||||
|
;;
|
4
TP3/dune
Executable file
4
TP3/dune
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
(ocamllex Scanner)
|
||||||
|
|
||||||
|
(executables
|
||||||
|
(names Main MainMonad))
|
1
TP3/dune-project
Executable file
1
TP3/dune-project
Executable file
|
@ -0,0 +1 @@
|
||||||
|
(lang dune 1.11)
|
27
TP3/tests/test.ml
Executable file
27
TP3/tests/test.ml
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
(*
|
||||||
|
LL(1)
|
||||||
|
#01 - E0 -> function ident -> E0
|
||||||
|
#02 - E0 -> let ident = E0 in E0
|
||||||
|
#03 - E0 -> letrec ident = E0 in E0
|
||||||
|
#04 - E0 -> if E0 then E0 else E0
|
||||||
|
#05 - E0 -> F TY EY EX
|
||||||
|
#06 - EX -> = F TY EY EX
|
||||||
|
#07 - EX ->
|
||||||
|
#08 - EY -> + F TY EY
|
||||||
|
#09 - EY -> - F TY EY
|
||||||
|
#10 - EY ->
|
||||||
|
#11 - TY -> * F TY
|
||||||
|
#12 - TY -> / F TY
|
||||||
|
#13 - TY ->
|
||||||
|
#14 - F -> - F
|
||||||
|
#15 - F -> ( E0 ) FX
|
||||||
|
#16 - F -> ident FI
|
||||||
|
#17 - F -> true
|
||||||
|
#18 - F -> false
|
||||||
|
#19 - F -> number
|
||||||
|
#20 - FX -> ( E0 )
|
||||||
|
#21 - FX ->
|
||||||
|
#22 - FI -> ( EO )
|
||||||
|
#23 - FI ->
|
||||||
|
*)
|
Loading…
Reference in a new issue