できたっぽい.要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の許可が必要です