You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 

57 lines
1.2 KiB

let sprintf = Printf.sprintf
type cardinality =
| Optional
| One
| N
type relcol = { rctabnam: string; rccardty: cardinality }
type table =
{ tprimkeys: string list
; tattrs: string list
}
type relation =
{ rname: string
; relates: relcol list
; rattrs: string list
}
type ent =
| Table of string * table
| Relation of relation
module Tables = Map.Make(String)
type ast =
{ atables: table Tables.t
; arelations: relation list
}
let map_and_concat f xs = List.map f xs |> String.concat ""
(* access the last character, raise exception if given string is empty *)
let parse_rtabnam x =
let lcidx = (String.length x) - 1 in
match String.get x lcidx with
| '+' -> { rctabnam = (String.sub x 0 lcidx); rccardty = N }
| '?' -> { rctabnam = (String.sub x 0 lcidx); rccardty = Optional }
| _ -> { rctabnam = x; rccardty = One }
let empty =
{ atables = Tables.empty
; arelations = []
}
let update_ast e a =
match e with
| Table (name, t) -> { a with atables = Tables.add name t a.atables }
| Relation (r) -> { a with arelations = r::a.arelations }
let build_ast_of_list x =
let rec intern = function
| [] -> empty
| x::xs -> (intern xs |> update_ast x)
in
List.rev x |> intern