Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
231
Task/S-expressions/F-Sharp/s-expressions-1.fs
Normal file
231
Task/S-expressions/F-Sharp/s-expressions-1.fs
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
module SExpr
|
||||
(* This module is a very simple port of the OCaml version to F# (F-Sharp) *)
|
||||
(* The original OCaml setatment is comment out and the F# statement(s) follow *)
|
||||
(* Port performed by Bob Elward 23 Feb 2020 *)
|
||||
|
||||
(* The .Net standard would use "+" and not "^" for string concatenation *)
|
||||
(* I kept the "^" to be compatable with the "ml" standard *)
|
||||
(* The line below eliminates the warning/suggestion to use "+" *)
|
||||
#nowarn "62"
|
||||
|
||||
(** This module is a very simple parsing library for S-expressions. *)
|
||||
(* Copyright (C) 2009 Florent Monnier, released under MIT license. *)
|
||||
(* modified to match the task description *)
|
||||
|
||||
(* Code obtained from: https://rosettacode.org/wiki/S-Expressions#OCaml *)
|
||||
|
||||
(* Note: The type below defines the grammar for this S-Expression (S-Expr).
|
||||
An S-Expr is either an Atom or an S-Expr
|
||||
*)
|
||||
|
||||
open System.Text
|
||||
open System.IO
|
||||
open System
|
||||
|
||||
type sexpr = Atom of string | Expr of sexpr list
|
||||
|
||||
type state =
|
||||
| Parse_root of sexpr list
|
||||
| Parse_content of sexpr list
|
||||
| Parse_word of StringBuilder * sexpr list
|
||||
| Parse_string of bool * StringBuilder * sexpr list
|
||||
|
||||
let parse pop_char =
|
||||
let rec aux st =
|
||||
match pop_char() with
|
||||
| None ->
|
||||
begin match st with
|
||||
| Parse_root sl -> (List.rev sl)
|
||||
| Parse_content _
|
||||
| Parse_word _
|
||||
| Parse_string _ ->
|
||||
failwith "Parsing error: content not closed by parenthesis"
|
||||
end
|
||||
| Some c ->
|
||||
match c with
|
||||
| '(' ->
|
||||
begin match st with
|
||||
| Parse_root sl ->
|
||||
let this = aux(Parse_content []) in
|
||||
aux(Parse_root((Expr this)::sl))
|
||||
| Parse_content sl ->
|
||||
let this = aux(Parse_content []) in
|
||||
aux(Parse_content((Expr this)::sl))
|
||||
| Parse_word(w, sl) ->
|
||||
let this = aux(Parse_content []) in
|
||||
(* aux(Parse_content((Expr this)::Atom(Buffer.contents w)::sl)) *)
|
||||
aux(Parse_content((Expr this)::Atom(w.ToString())::sl))
|
||||
| Parse_string(_, s, sl) ->
|
||||
//Buffer.add_char s c;
|
||||
s.Append(c) |> ignore;
|
||||
aux(Parse_string(false, s, sl))
|
||||
end
|
||||
| ')' ->
|
||||
begin match st with
|
||||
| Parse_root sl ->
|
||||
failwith "Parsing error: closing parenthesis without openning"
|
||||
| Parse_content sl -> (List.rev sl)
|
||||
(* | Parse_word(w, sl) -> List.rev(Atom(Buffer.contents w)::sl) *)
|
||||
| Parse_word(w, sl) -> List.rev(Atom(w.ToString())::sl)
|
||||
| Parse_string(_, s, sl) ->
|
||||
(* Buffer.add_char s c; *)
|
||||
s.Append(c) |> ignore;
|
||||
aux(Parse_string(false, s, sl))
|
||||
end
|
||||
| ' ' | '\n' | '\r' | '\t' ->
|
||||
begin match st with
|
||||
| Parse_root sl -> aux(Parse_root sl)
|
||||
| Parse_content sl -> aux(Parse_content sl)
|
||||
(* | Parse_word(w, sl) -> aux(Parse_content(Atom(Buffer.contents w)::sl)) *)
|
||||
| Parse_word(w, sl) -> aux(Parse_content(Atom(w.ToString())::sl))
|
||||
| Parse_string(_, s, sl) ->
|
||||
//Buffer.add_char s c;
|
||||
s.Append(c) |> ignore;
|
||||
aux(Parse_string(false, s, sl))
|
||||
end
|
||||
| '"' ->
|
||||
(* '"' *)
|
||||
begin match st with
|
||||
| Parse_root _ -> failwith "Parse error: double quote at root level"
|
||||
| Parse_content sl ->
|
||||
(* let s = Buffer.create 74 in *)
|
||||
let s = StringBuilder(74) in
|
||||
aux(Parse_string(false, s, sl))
|
||||
| Parse_word(w, sl) ->
|
||||
(* let s = Buffer.create 74 in *)
|
||||
let s = StringBuilder(74) in
|
||||
(* aux(Parse_string(false, s, Atom(Buffer.contents w)::sl)) *)
|
||||
aux(Parse_string(false, s, Atom(w.ToString())::sl))
|
||||
| Parse_string(true, s, sl) ->
|
||||
(* Buffer.add_char s c; *)
|
||||
s.Append(c) |> ignore;
|
||||
aux(Parse_string(false, s, sl))
|
||||
| Parse_string(false, s, sl) ->
|
||||
(* aux(Parse_content(Atom(Buffer.contents s)::sl)) *)
|
||||
aux(Parse_content(Atom(s.ToString())::sl))
|
||||
end
|
||||
| '\\' ->
|
||||
begin match st with
|
||||
| Parse_string(true, s, sl) ->
|
||||
(* Buffer.add_char s c; *)
|
||||
s.Append(c) |> ignore;
|
||||
aux(Parse_string(false, s, sl))
|
||||
| Parse_string(false, s, sl) ->
|
||||
aux(Parse_string(true, s, sl))
|
||||
| _ ->
|
||||
failwith "Parsing error: escape character in wrong place"
|
||||
end
|
||||
| _ ->
|
||||
begin match st with
|
||||
| Parse_root _ ->
|
||||
failwith(Printf.sprintf "Parsing error: char '%c' at root level" c)
|
||||
| Parse_content sl ->
|
||||
(* let w = Buffer.create 16 in *)
|
||||
let w = StringBuilder(16) in
|
||||
(* Buffer.add_char w c; *)
|
||||
w.Append(c) |> ignore;
|
||||
aux(Parse_word(w, sl))
|
||||
| Parse_word(w, sl) ->
|
||||
(* Buffer.add_char w c; *)
|
||||
w.Append(c) |> ignore;
|
||||
aux(Parse_word(w, sl))
|
||||
| Parse_string(_, s, sl) ->
|
||||
(* Buffer.add_char s c; *)
|
||||
s.Append(c) |> ignore;
|
||||
aux(Parse_string(false, s, sl))
|
||||
end
|
||||
in
|
||||
aux (Parse_root [])
|
||||
|
||||
|
||||
let string_pop_char str =
|
||||
let len = String.length str in
|
||||
let i = ref(-1) in
|
||||
(function () -> incr i; if !i >= len then None else Some(str.[!i]))
|
||||
|
||||
|
||||
let parse_string str =
|
||||
parse (string_pop_char str)
|
||||
|
||||
(*
|
||||
let ic_pop_char ic =
|
||||
(function () ->
|
||||
try Some(input_char ic)
|
||||
with End_of_file -> (None))
|
||||
*)
|
||||
|
||||
let ic_pop_char (ic:TextReader) =
|
||||
(function () -> try Some(Convert.ToChar(ic.Read()))
|
||||
with _End_of_file -> (None)
|
||||
)
|
||||
|
||||
|
||||
let parse_ic ic =
|
||||
parse (ic_pop_char ic)
|
||||
|
||||
|
||||
let parse_file filename =
|
||||
(* let ic = open_in filename in *)
|
||||
let ic = File.OpenText filename in
|
||||
let res = parse_ic ic in
|
||||
(* close_in ic; *)
|
||||
ic.Close();
|
||||
(res)
|
||||
|
||||
|
||||
let quote s =
|
||||
"\"" ^ s ^ "\""
|
||||
|
||||
let needs_quote s =
|
||||
(* List.exists (String.contains s) [' '; '\n'; '\r'; '\t'; '('; ')'] *)
|
||||
List.exists (fun elem -> (String.exists (fun c -> c = elem) s)) [' '; '\n'; '\r'; '\t'; '('; ')']
|
||||
|
||||
let protect s =
|
||||
(* There is no need to "escape" .Net strings the framework takes care of this *)
|
||||
(* let s = String.escaped s in *)
|
||||
if needs_quote s then quote s else s
|
||||
|
||||
|
||||
let string_of_sexpr s =
|
||||
let rec aux acc = function
|
||||
| (Atom tag)::tl -> aux ((protect tag)::acc) tl
|
||||
| (Expr e)::tl ->
|
||||
let s =
|
||||
"(" ^
|
||||
(String.concat " " (aux [] e))
|
||||
^ ")"
|
||||
in
|
||||
aux (s::acc) tl
|
||||
| [] -> (List.rev acc)
|
||||
in
|
||||
String.concat " " (aux [] s)
|
||||
|
||||
|
||||
let print_sexpr s =
|
||||
(* print_endline (string_of_sexpr s) *)
|
||||
printfn "%s" (string_of_sexpr s)
|
||||
|
||||
|
||||
let string_of_sexpr_indent s =
|
||||
let rec aux i acc = function
|
||||
| (Atom tag)::tl -> aux i ((protect tag)::acc) tl
|
||||
| (Expr e)::tl ->
|
||||
let s =
|
||||
(*
|
||||
"\n" ^ (String.make i ' ') ^ "(" ^
|
||||
(String.concat " " (aux (succ i) [] e))
|
||||
^ ")"
|
||||
*)
|
||||
"\n" ^ (String.replicate i " ") ^ "(" ^
|
||||
(String.concat " " (aux (i + 1) [] e))
|
||||
^ ")"
|
||||
in
|
||||
aux i (s::acc) tl
|
||||
| [] -> (List.rev acc)
|
||||
in
|
||||
String.concat "\n" (aux 0 [] s)
|
||||
|
||||
|
||||
let print_sexpr_indent s =
|
||||
(* print_endline (string_of_sexpr_indent s) *)
|
||||
printfn "%s" (string_of_sexpr_indent s)
|
||||
37
Task/S-expressions/F-Sharp/s-expressions-2.fs
Normal file
37
Task/S-expressions/F-Sharp/s-expressions-2.fs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
module Program
|
||||
(* Learn more about F# at https://fsharp.org *)
|
||||
|
||||
open System
|
||||
|
||||
[<EntryPoint>]
|
||||
let main argv =
|
||||
let sexpr =
|
||||
|
||||
(* Data from file supplied at runtime or a preset string? *)
|
||||
if argv.Length > 0 then
|
||||
(* Data from file supplied at runtime *)
|
||||
begin
|
||||
(* Get the file to parse *)
|
||||
let name = argv.[0] in
|
||||
|
||||
(* parse the program file *)
|
||||
SExpr.parse_file name
|
||||
end
|
||||
else
|
||||
(* Data from a preset string *)
|
||||
begin
|
||||
(* preset the string *)
|
||||
let data= "((data \"quoted data\" 123 4.5) (data (!@# (4.5) \"(more\" \"data)\")))" in
|
||||
|
||||
(* parse the program file *)
|
||||
SExpr.parse_string data
|
||||
end
|
||||
|
||||
(* Print the parsed program token list *)
|
||||
(printf "\nSExpr: \n");
|
||||
SExpr.print_sexpr sexpr;
|
||||
(printf "\nSExpr - Indented: \n");
|
||||
SExpr.print_sexpr_indent sexpr;
|
||||
|
||||
(* return an integer exit code *)
|
||||
0
|
||||
Loading…
Add table
Add a link
Reference in a new issue