Last active
June 23, 2018 06:09
-
-
Save dburriss/5407a37f08127679750a73e639665ab5 to your computer and use it in GitHub Desktop.
A F# script file showing parsing text to a typed list. Run with `fsi.exe TextToList.fsx`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System | |
type Type1 = { | |
val1:string | |
val2:string | |
} | |
type Type2 = { | |
val1:string | |
val2:string | |
} | |
type Aggregate = | |
| T1 of Type1 | |
| T2 of Type2 | |
type State = | |
| Start of Aggregate list | |
| Collecting of Aggregate list * string * (Map<string,string> -> Aggregate) * Map<string,string> | |
let lines = seq { | |
yield "BEGINTYPE1" | |
yield "VAL1: xxx" | |
yield "VAL2: yyy" | |
yield "ENDTYPE1" | |
yield "BEGINTYPE2" | |
yield "VAL1: xxx" | |
yield "VAL2: yyy" | |
yield "ENDTYPE2" | |
} | |
let mapType1 (dic:Map<string,string>) = | |
Aggregate.T1 | |
{ | |
val1 = dic.["VAL1"] | |
val2 = dic.["VAL2"] | |
} | |
let mapType2 (dic:Map<string,string>) = | |
Aggregate.T2 | |
{ | |
val1 = dic.["VAL1"] | |
val2 = dic.["VAL2"] | |
} | |
let (|Begin|_|) input = | |
match input with | |
| "BEGINTYPE1" -> Some ("TYPE1", mapType1) | |
| "BEGINTYPE2" -> Some ("TYPE2", mapType2) | |
| _ -> None | |
let (|Prop|_|) input = | |
if(String.IsNullOrEmpty(input:string)) then None | |
else | |
if(input.Contains(":")) then | |
let split = input.Split(':') | |
let pName = split.[0].Trim() | |
let pValue = split.[1].Trim() | |
Some (pName,pValue) | |
else None | |
let (|End|_|) (l,label,f,m) input = | |
match input with | |
| "ENDTYPE1" -> Some (List.append l ([f m]), label) | |
| "ENDTYPE2" -> Some (List.append l ([f m]), label) | |
| _ -> None | |
let folder state line = | |
match state with | |
| Start xs -> | |
match line with | |
| Begin (label, f) -> Collecting (xs, label, f, Map.empty<string,string>) | |
| _ -> failwithf "Should start with a BEGINTYPEx, intead was %s" line | |
| Collecting (xs, label, f, m) -> | |
match line with | |
| Prop (k,v) -> Collecting (xs, label, f, Map.add k v m) | |
| End(xs, label, f, m) (ys, s) -> Start ys | |
| _ -> failwithf "Expecting property or ENDTYPEx, instead was %s" line | |
let extractTypeList state = | |
match state with | |
| Start xs -> xs | |
| Collecting (xs, _,_,_) -> xs | |
let extractTypes lines = | |
lines | |
|> Seq.fold folder (Start []) | |
|> extractTypeList | |
let printTypes types = | |
types |> List.iter (fun a -> printfn "%A" a) | |
extractTypes lines | |
|> printTypes |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Or as a console app: