From d96e1839eb800bf26bcc38272072d98af69f5d83 Mon Sep 17 00:00:00 2001 From: Marc Coquand Date: Tue, 26 Dec 2023 10:08:23 -0600 Subject: Support const keyword --- lib/ast_types.ml | 5 +++++ lib/fixture.ml | 5 +++-- lib/lexer.mll | 18 ++++++++++++++++++ lib/parser.mly | 7 +++++++ 4 files changed, 33 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/ast_types.ml b/lib/ast_types.ml index b9f4294..c278d59 100644 --- a/lib/ast_types.ml +++ b/lib/ast_types.ml @@ -5,6 +5,7 @@ type ast_row = | Uuidv4 of string * ast_row | Name of string * ast_row | Int of string * int * int * ast_row + | Const of string * string * ast_row | Foreign of string * string * string * ast_row (* parent, row, child_name, row *) | End @@ -19,6 +20,9 @@ let rec print_row = function | Uuidv4 (s, r) -> printf "UUIDv4(%s)," s; print_row r + | Const (s, v, r) -> + printf "Const(%s, %s)," s v; + print_row r | Foreign (p, r, c, next_row) -> printf "Foreign(%s.%s, %s)," p r c; print_row next_row @@ -60,6 +64,7 @@ let rec ast_row_to_fixtures = function CRow (p, r, fun l -> Fixture.Foreign (c, l)) :: ast_row_to_fixtures next_row | Name (s, r) -> PRow (Fixture.Name s) :: ast_row_to_fixtures r | Int (s, min, max, r) -> PRow (Fixture.Int (s, min, max)) :: ast_row_to_fixtures r + | Const (s, v, r) -> PRow (Fixture.Const (s, v)) :: ast_row_to_fixtures r | End -> [] diff --git a/lib/fixture.ml b/lib/fixture.ml index 25f6a8f..2b17a02 100644 --- a/lib/fixture.ml +++ b/lib/fixture.ml @@ -22,12 +22,12 @@ let names = let random_name () = List.nth names (Random.int (List.length names)) let%test "random_name" = List.mem (random_name ()) names -(* TODO: Support names *) type t = | Name of string | Uuidv4 of string | Foreign of (string * string list) | Int of string * int * int + | Const of string * string (* (Name, foreign ids to pick from) *) let add_name name fixtures = Name name :: fixtures @@ -46,6 +46,7 @@ let generate_fixture fixture = | Name _ -> random_name () | Uuidv4 _ -> Uuidm.v `V4 |> Uuidm.to_string | Foreign (_, reference) -> random_value_in_list reference + | Const (_, value) -> value | Int (_, min, max) -> Random.int (max - min) + min |> string_of_int @@ -58,10 +59,10 @@ let id_of_fixture fixture = | Name id -> id | Uuidv4 id -> id | Foreign (id, _) -> id + | Const (id, _) -> id | Int (id, _, _) -> id -(* TODO: Support const *) (* TODO: Support email *) (* TODO: Support list *) diff --git a/lib/lexer.mll b/lib/lexer.mll index e0c5453..6e9b975 100644 --- a/lib/lexer.mll +++ b/lib/lexer.mll @@ -23,6 +23,7 @@ rule read = | "_int" { INTSYMBOL } | "(" { LBRACE } | ")" { RBRACE } + | '"' { read_string (Buffer.create 20) lexbuf } | int { INT (Lexing.lexeme lexbuf |> int_of_string) } | white { read lexbuf } | ":" { COLON } @@ -32,3 +33,20 @@ rule read = | "." { DOT } | eof { EOF } | _ as c { failwith (Printf.sprintf "unexpected character: %C" c) } + +and read_string buf = + parse + | '"' { STRING (Buffer.contents buf) } + | '\\' '/' { Buffer.add_char buf '/'; read_string buf lexbuf } + | '\\' '\\' { Buffer.add_char buf '\\'; read_string buf lexbuf } + | '\\' 'b' { Buffer.add_char buf '\b'; read_string buf lexbuf } + | '\\' 'f' { Buffer.add_char buf '\012'; read_string buf lexbuf } + | '\\' 'n' { Buffer.add_char buf '\n'; read_string buf lexbuf } + | '\\' 'r' { Buffer.add_char buf '\r'; read_string buf lexbuf } + | '\\' 't' { Buffer.add_char buf '\t'; read_string buf lexbuf } + | [^ '"' '\\']+ + { Buffer.add_string buf (Lexing.lexeme lexbuf); + read_string buf lexbuf + } + | _ { raise (SyntaxError ("Illegal string character: " ^ Lexing.lexeme lexbuf)) } + | eof { raise (SyntaxError ("String is not terminated")) } diff --git a/lib/parser.mly b/lib/parser.mly index e9d06bc..6e21480 100644 --- a/lib/parser.mly +++ b/lib/parser.mly @@ -14,6 +14,7 @@ %token INT %token LBRACE %token RBRACE +%token STRING %start prog %% @@ -30,10 +31,16 @@ expr: row: | row_title = IDENTIFIER; parent = IDENTIFIER; DOT; parent_id = IDENTIFIER; COMMA; r = row { Foreign (parent,parent_id,row_title, r) } | row_title = IDENTIFIER; parent = IDENTIFIER; DOT; parent_id = IDENTIFIER; { Foreign (parent,parent_id,row_title, End) } + | row_title = IDENTIFIER; UUIDV4; COMMA; r = row { Uuidv4 (row_title, r) } | row_title = IDENTIFIER; UUIDV4 { Uuidv4 (row_title, End) } + | row_title = IDENTIFIER; NAME; COMMA; r = row { Name (row_title, r) } | row_title = IDENTIFIER; NAME { Name (row_title, End) } + + | row_title = IDENTIFIER; const = STRING; COMMA; r = row { Const (row_title, const, r) } + | row_title = IDENTIFIER; const = STRING { Const (row_title, const, End) } + | row_title = IDENTIFIER; INTSYMBOL;LBRACE;min = INT;COMMA;max = INT;RBRACE;COMMA; r = row { Int (row_title,min,max,r) } | row_title = IDENTIFIER; INTSYMBOL;LBRACE;min = INT;COMMA;max = INT;RBRACE; { Int (row_title,min,max,End) } ; -- cgit v1.2.3