37. これでOK
let integer = regex "([1-9][0-9]*|0)" |>> Int
let real = regex @"([1-9][0-9]*|0).[0-9]*" |>> Real
// attemptでrealが失敗したら、realが消費した文字を入力に戻す
let number = attempt real <|> integer
44. 左再帰の繰り返しへの変換
// 元のコードの意味(左再帰)
// expr ::= expr op integer
// | integer
// から、下記(繰り返し)に変換
// expr ::= integer (op integer)*
let expr =
integer .>>. (many (op .>>. integer))
|>> fun (x, xs) -> List.fold (fun x (f, y) -> f x y) x xs
and op =
anyOf "+-" .>> ws
|>> (function
| '+' -> fun a b -> Add(a, b)
| '-' -> fun a b -> Sub(a, b)
| other -> invalidOp ("invalid char: " + string other))
46. chainl1を使いましょう
// expr ::= integer (op integer)*
let expr = chainl1 integer op
and op =
anyOf "+-" .>> ws
|>> (function
| '+' -> fun a b -> Add(a, b)
| '-' -> fun a b -> Sub(a, b)
| other -> invalidOp ("invalid char: " + string other))