2021年1月26日

できたっぽい.要base/parser

let main =
  let digit-parser =
    let aux s i = (string s) >>= (fun _ -> pure i) in
    aux `0` 0.0 <|> aux `1` 1.0 <|> aux `2` 2.0 <|>
    aux `3` 3.0 <|> aux `4` 4.0 <|> aux `5` 5.0 <|>
    aux `6` 6.0 <|> aux `7` 7.0 <|> aux `8` 8.0 <|>
    aux `9` 9.0
  in
  
  let digits-parser-u =
    (some digit-parser) >>= (fun s -> pure (List.fold-left (fun a b -> 10.0 *. a +. b) 0.0 s))
  in
  
  let digits-parser-l =
    (some digit-parser) >>= (fun s -> pure (0.1 *. (List.fold-right (fun a b -> a +. (0.1 *. b)) 0.0 s)))
  in
  
  let float-parser =
    choice [
      try (sequence [(digits-parser-u << string `.`); digits-parser-l] >>= (fun s -> pure (List.fold-left (+.) 0.0 s)));
      digits-parser-u
    ]
  in


  let expr = fix (fun expr -> (
    let fctr = choice [
      try float-parser;
      between (string `(`) (string `)`) expr;
    ] in
    let term = sequence [
      fctr;
      many (choice [
        try ((string `*`) >> fctr);
        (string `/`) >> fctr >>= (fun l -> pure (1.0 /. l));
      ]) >>= (fun s -> pure (List.fold-left (*.) 1.0 s));
    ] >>= (fun s -> pure (List.fold-left (*.) 1.0 s))
    in
    let expr = sequence [
      choice [
        try((string `-`) >> term >>= (fun s -> pure (0.0 -. s)));
        term;
      ];
      (many (choice[
        try((string `-`) >> term >>= (fun s -> pure (0.0 -. s)));
        (string `+`) >> term;
      ])) >>= (fun s -> pure (List.fold-left (+.) 0.0 s))
    ] >>= (fun s -> pure (List.fold-left (+.) 0.0 s))
    in
    expr
  ))
  in
  expr
  
let () =
  match StringParser.run main `1+2.0*(3.0+2)` with
  |Err(_) -> display-message `err` 
  |Ok(f) -> display-message (Float.to-string f)

0 件のコメント:

コメントを投稿

コメントの追加にはサードパーティーCookieの許可が必要です