From a27cc602422cc9076ddc1d0e7db3f3cbf2bf193f Mon Sep 17 00:00:00 2001 From: pacien Date: Mon, 30 Apr 2018 20:50:28 +0200 Subject: Adjust parser --- README.md | 2 +- src/eurm_test.ml | 2 ++ src/main.ml | 12 +++++++++--- src/parser.ml | 47 +++++++++++++++++++++++++++++++++++++---------- src/parser.mli | 9 ++++++--- 5 files changed, 55 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 2cce7bf..6606650 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Unlimited Register Machine in OCaml. ## Usage ``` -./urm +./urm ``` Examples programs are provided in the `examples` folder. diff --git a/src/eurm_test.ml b/src/eurm_test.ml index afecf9e..a3ef5a8 100644 --- a/src/eurm_test.ml +++ b/src/eurm_test.ml @@ -8,6 +8,7 @@ open Urm open Eurm open Kaputt.Abbreviations +(* let () = Test.add_simple_test ~title:"example_eurm_factorial_conversion" @@ -72,3 +73,4 @@ let () = Assert.is_true (output_urm = expected_urm)) let () = if Array.mem "run-tests" Sys.argv then Test.launch_tests () + *) diff --git a/src/main.ml b/src/main.ml index 3e66645..c6a059e 100644 --- a/src/main.ml +++ b/src/main.ml @@ -8,13 +8,14 @@ open Parser open Instptr open Reg open Urm +open Eurm let exec_with_resource func filename = let file = open_in filename in let res = func file in close_in file; res -let read_prgm = exec_with_resource (fun f -> string_of_file f |> program_of_string) +let read_prgm lexer = exec_with_resource (fun f -> string_of_file f |> program_of_string lexer) let read_regs = exec_with_resource (fun f -> string_of_file f |> regs_of_string) let run run_func prgm regs = urm_mk prgm regs |> run_func |> regs_string |> print_endline @@ -23,7 +24,12 @@ let run_mode_of_string = function | "trace" -> urm_run_trace | _ -> failwith "Invalid run mode" +let lexer_of_string = function + | "urm" -> (urm_program_of_lex) + | "eurm" -> (fun toks -> eurm_program_of_lex toks |> urm_from_eurm) + | _ -> failwith "Invalid lang" + let () = match Sys.argv with | [| _; "run-tests" |] -> () (* handled in test files *) - | [| _; mode; prgm; regs |] -> run (run_mode_of_string mode) (read_prgm prgm) (read_regs regs) - | _ -> print_endline "Usage: urm | trace >" + | [| _; mode; lang; prgm; regs |] -> run (run_mode_of_string mode) (read_prgm (lexer_of_string lang) prgm) (read_regs regs) + | _ -> print_endline "Usage: urm " diff --git a/src/parser.ml b/src/parser.ml index 0bc1be6..0a0c3a8 100644 --- a/src/parser.ml +++ b/src/parser.ml @@ -8,24 +8,51 @@ open Common let rec string_of_file f = try let str = input_line f - in str ^ " " ^ (string_of_file f) + in str ^ "\n" ^ (string_of_file f) with End_of_file -> "" -let rec program_of_lex = function +let rec eurm_program_of_lex = function | [] -> [] - | instr :: tail -> match (String.lowercase_ascii instr) :: tail with - | "zero" :: arg_1 :: tail -> (URMZero (int_of_string arg_1)) :: (program_of_lex tail) - | "succ" :: arg_1 :: tail -> (URMSucc (int_of_string arg_1)) :: (program_of_lex tail) - | "copy" :: arg_1 :: arg_2 :: tail -> (URMCopy ((int_of_string arg_1), (int_of_string arg_2))) :: (program_of_lex tail) - | "jump" :: arg_1 :: arg_2 :: arg_3 :: tail -> (URMJump ((int_of_string arg_1), (int_of_string arg_2), (int_of_string arg_3))) :: (program_of_lex tail) + | l -> match l with + | "comment" :: comment :: tail -> Comment(comment) :: eurm_program_of_lex tail + | "label" :: lbl :: tail -> Label(lbl) :: eurm_program_of_lex tail + | "goto" :: lbl :: tail -> Goto(lbl) :: eurm_program_of_lex tail + | "zero" :: r :: tail -> Zero(int_of_string r) :: eurm_program_of_lex tail + | "inc" :: r :: tail -> Inc(int_of_string r) :: eurm_program_of_lex tail + | "dec" :: r :: tail -> Dec(int_of_string r) :: eurm_program_of_lex tail + | "copy" :: r1 :: r2 :: tail -> Copy(int_of_string r1, int_of_string r2) :: eurm_program_of_lex tail + | "add" :: r1 :: r2 :: tail -> Add(int_of_string r1, int_of_string r2) :: eurm_program_of_lex tail + | "sub" :: r1 :: r2 :: tail -> Sub(int_of_string r1, int_of_string r2) :: eurm_program_of_lex tail + | "mult" :: r1 :: r2 :: tail -> Mult(int_of_string r1, int_of_string r2) :: eurm_program_of_lex tail + | "eq?" :: r1 :: r2 :: lbl :: tail -> EqPredicate(int_of_string r1, int_of_string r2, lbl) :: eurm_program_of_lex tail + | "geq?" :: r1 :: r2 :: lbl :: tail -> GEqPredicate(int_of_string r1, int_of_string r2, lbl) :: eurm_program_of_lex tail + | "gt?" :: r1 :: r2 :: lbl :: tail -> GTPredicate(int_of_string r1, int_of_string r2, lbl) :: eurm_program_of_lex tail + | "leq?" :: r1 :: r2 :: lbl :: tail -> LEqPredicate(int_of_string r1, int_of_string r2, lbl) :: eurm_program_of_lex tail + | "lt?" :: r1 :: r2 :: lbl :: tail -> LTPredicate(int_of_string r1, int_of_string r2, lbl) :: eurm_program_of_lex tail + | "zero?" :: r :: lbl :: tail -> ZeroPredicate(int_of_string r, lbl) :: eurm_program_of_lex tail + | "quit" :: tail -> Quit :: eurm_program_of_lex tail + | x -> String.concat " " x |> print_endline; raise Syntax_error + +let rec urm_program_of_lex = function + | [] -> [] + | l -> match l with + | "zero" :: r :: tail -> URMZero(int_of_string r) :: urm_program_of_lex tail + | "succ" :: r :: tail -> URMSucc(int_of_string r) :: urm_program_of_lex tail + | "copy" :: r1 :: r2 :: tail -> URMCopy(int_of_string r1, int_of_string r2) :: urm_program_of_lex tail + | "jump" :: r1 :: r2 :: l :: tail -> URMJump (int_of_string r1, int_of_string r2, int_of_string l) :: urm_program_of_lex tail | _ -> raise Syntax_error -(* FIXME: reject multiple definition of a single register *) +(* TODO: reject multiple definition of a single register *) let rec regs_of_lex = function | [] -> [] | regnum :: regvalue :: tail -> Reg (int_of_string regnum, int_of_string regvalue) :: (regs_of_lex tail) | _ -> raise Syntax_error -let seq_from_string lexer_func str = Str.split (Str.regexp "[\t\n(), ]+") str |> lexer_func -let program_of_string = seq_from_string program_of_lex +let seq_from_string lexer_func str = + String.lowercase_ascii str + |> Str.global_replace (Str.regexp "comment.*\n") "" + |> Str.split (Str.regexp "[\t\n(), ]+") + |> lexer_func + +let program_of_string lexer = seq_from_string lexer let regs_of_string = seq_from_string regs_of_lex diff --git a/src/parser.mli b/src/parser.mli index 21fc940..2cad383 100644 --- a/src/parser.mli +++ b/src/parser.mli @@ -8,14 +8,17 @@ open Common (* Reads a file into a string. *) val string_of_file : in_channel -> string -(* Converts lexemes into instructions. *) -val program_of_lex : string list -> urmcmd list +(* Converts lexemes into URM instructions. *) +val urm_program_of_lex : string list -> urmcmd list + +(* Converts lexemes into EURM instructions. *) +val eurm_program_of_lex : string list -> eurmcmd list (* Converts lexemes into registers. *) val regs_of_lex : string list -> reg list (* Parses the string representation of a program. *) -val program_of_string : string -> urmcmd list +val program_of_string : (string list -> 'a list) -> string -> 'a list (* Parses the string representation of serialized registers. *) val regs_of_string : string -> reg list -- cgit v1.2.3