Commits

camlspotter committed 6e77c4c

parser

Comments (0)

Files changed (3)

parsing/OMakefile

    lex
    lextest
 
-MyOCamlProgram(lexer0, $(FILES0))
+MyOCamlProgram(lexer_test, $(FILES0))
 
 
 FILES1[] =
    token
+   lex
    parser
-   lex
+   parsetest
 
-MyOCamlProgram(lexer1, $(FILES1))
+MyOCamlProgram(parser_test, $(FILES1))

parsing/parser.ml

+open Spotlib.Spot
+open Planck
+open Sexplib.Conv
+
+module Stream = Stoken.Make(Token)(Position.Region)(Pfile.Parser)
+
+let token_stream : Pfile.Stream.t -> Stream.t = Stream.create 
+  Planck.Pfile.Parser.(perform
+    (v, pos) <-- Lex.ocaml_token;
+    match v with
+    | Token.EOF -> return (None, pos)
+    | _ -> return (Some v, pos))
+
+module Parser = struct
+  include Ptoken.Make(Stream)
+  let with_region x = with_region Position.Region.merge x
+end
+
+open Parser
+open Token
+
+type constant = 
+  | CInt of int
+  | CString of string
+
+and patt = 
+  | PVar of string
+
+and expr = 
+  | EVar of string
+  | EConst of constant
+  | EApp of expr * expr list
+  | EFun of patt list * expr
+
+and top = 
+  | TopLet of patt * expr
+
+with sexp
+
+let patt = token_option (function LIDENT s -> Some (PVar s) | _ -> None)
+
+let constant = 
+  token_option (function 
+    | INT n -> Some (EConst (CInt n))
+    | STRING s -> Some (EConst (CString s))
+    | _ -> None)
+  
+let rec simple_expr x = begin
+
+  constant 
+
+  <|> token_option (function 
+    | LIDENT s -> Some (EVar s) 
+    | _ -> None)
+
+  <|> surrounded (token LPAREN) (token RPAREN) expr
+
+end x
+
+and application x = begin perform
+  e <-- simple_expr;
+  es <-- ?** simple_expr;
+  return & match es with [] -> e | _ -> EApp (e, es)
+end x
+
+and fun_ x = begin perform
+  token FUN;
+  ps <-- ?++ patt;
+  token MINUSGREATER;
+  e <-- expr;
+  return (EFun (ps, e))
+end x
+
+and expr x = begin
+
+  fun_
+  <|> application
+
+end x
+  
+let top_let = perform
+  token LET;
+  p <-- patt;
+  token EQUAL;
+  e <-- expr;
+  return & TopLet (p,e)
+
+let top = top_let
+
+let file = ?** top
+
+  

parsing/parsetest.ml

+open Planck
+open Sexplib.Conv
+
+type tops = Parser.top list with sexp
+
+let parse_and_print stream = 
+  match Parser.Parser.run Parser.file (Parser.token_stream stream) with
+  | Result.Ok (tops, _) -> 
+      Format.eprintf "%a@." Sexplib.Sexp.pp_hum (sexp_of_tops tops)
+      
+  | Result.Error (pos, s) -> 
+      Format.eprintf "%a: syntax error: %s@." Position.Region.format pos s
+
+let _ = Arg.parse [] (fun x ->
+  let ic = open_in x in
+  let stream = Pfile.Stream.from_chan ~filename:"" ic in
+  parse_and_print stream;
+  close_in ic) "parsetest files"
+