1 people like it.

Simple FParsec int32 parser

Like FParsec's pint32, but accepts only optionally-signed base-10 input

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
open System

module Char = begin
  let hspace = function
    | ' ' | '\t' -> true
    | _ -> false
end

module Parsers = begin
  open FParsec

  module Utils = begin
    let mk_res inp = function
      | Success (res, _, _) -> Result.Ok (inp, res)
      | Failure (errstr, _, _) -> Result.Error (inp, errstr)

    let run = run
  end

  let int32_of_digits ds =
    let rec aux acc = function
      | [] -> acc
      | x::xs -> aux (10 * acc + (int x - int '0')) xs
    in
    if List.isEmpty ds then 0 else aux 0 ds

  let psint32 : Parser<int, unit> =
    let sign = (pchar '-' >>% (~-)) <|> (pchar '+' >>% (~+)) in
    let optsign = sign <|>% (~+) in
    let digits = many1 digit in
    let mk_int32 = (>>) int32_of_digits in
    pipe2 optsign digits mk_int32

  let pcoord : Parser<int * int, unit> =
    psint32 .>>. (pchar ',' >>. skipManySatisfy Char.hspace >>. psint32)
end

open Parsers
open Parsers.Utils

let diag inp = inp |> run pcoord |> mk_res inp |> printfn "%A\n====="

#if !INTERACTIVE
[<EntryPoint>]
let main _ =
#else
let _ =
#endif
  let testvals =
    [ "1, 2"
    ; "-3, 4"
    ; "0, -9"
    ; "-5, -4"
    ; "+4, -3"
    ; "-0, 99"
    ; "-93, 77"
    ; "-000234, +0043"
    ; "hi"
    ; "0.2, 3.4"
    ; "123,-456"
    ]
  in
  List.iter diag testvals;
  0
namespace System
type Char =
  struct
    member CompareTo : value:obj -> int + 1 overload
    member Equals : obj:obj -> bool + 1 overload
    member GetHashCode : unit -> int
    member GetTypeCode : unit -> TypeCode
    member ToString : unit -> string + 1 overload
    static val MaxValue : char
    static val MinValue : char
    static member ConvertFromUtf32 : utf32:int -> string
    static member ConvertToUtf32 : highSurrogate:char * lowSurrogate:char -> int + 1 overload
    static member GetNumericValue : c:char -> float + 1 overload
    ...
  end

Full name: System.Char
val hspace : _arg1:char -> bool

Full name: Script.Char.hspace
namespace FParsec
val mk_res : inp:'a -> _arg1:ParserResult<'b,'c> -> 'd

Full name: Script.Parsers.Utils.mk_res
val inp : 'a
union case ParserResult.Success: 'Result * 'UserState * Position -> ParserResult<'Result,'UserState>
val res : 'b
val Ok : ReplyStatus

Full name: FParsec.Primitives.Ok
union case ParserResult.Failure: string * ParserError * 'UserState -> ParserResult<'Result,'UserState>
val errstr : string
Multiple items
val Error : ReplyStatus

Full name: FParsec.Primitives.Error

--------------------
module Error

from FParsec
val run : (Parser<'a,unit> -> string -> ParserResult<'a,unit>)

Full name: Script.Parsers.Utils.run
val int32_of_digits : ds:char list -> int

Full name: Script.Parsers.int32_of_digits
val ds : char list
val aux : (int -> char list -> int)
val acc : int
val x : char
val xs : char list
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member GetSlice : startIndex:int option * endIndex:int option -> 'T list
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val isEmpty : list:'T list -> bool

Full name: Microsoft.FSharp.Collections.List.isEmpty
val psint32 : Parser<int,unit>

Full name: Script.Parsers.psint32
type Parser<'Result,'UserState> = CharStream<'UserState> -> Reply<'Result>

Full name: FParsec.Primitives.Parser<_,_>
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
val sign : Parser<(int -> int),unit>
val pchar : char -> Parser<char,'u>

Full name: FParsec.CharParsers.pchar
val optsign : Parser<(int -> int),unit>
val digits : Parser<char list,unit>
val many1 : Parser<'a,'u> -> Parser<'a list,'u>

Full name: FParsec.Primitives.many1
val digit : Parser<char,'u>

Full name: FParsec.CharParsers.digit
val mk_int32 : ((int -> int) -> char list -> int)
val pipe2 : Parser<'a,'u> -> Parser<'b,'u> -> ('a -> 'b -> 'c) -> Parser<'c,'u>

Full name: FParsec.Primitives.pipe2
val pcoord : Parser<(int * int),unit>

Full name: Script.Parsers.pcoord
val skipManySatisfy : (char -> bool) -> Parser<unit,'u>

Full name: FParsec.CharParsers.skipManySatisfy
module Parsers

from Script
module Utils

from Script.Parsers
val diag : inp:string -> unit

Full name: Script.diag
val inp : string
val run : (FParsec.Primitives.Parser<'a,unit> -> string -> FParsec.CharParsers.ParserResult<'a,unit>)

Full name: Script.Parsers.Utils.run
val pcoord : FParsec.Primitives.Parser<(int * int),unit>

Full name: Script.Parsers.pcoord
val mk_res : inp:'a -> _arg1:FParsec.CharParsers.ParserResult<'b,'c> -> 'd

Full name: Script.Parsers.Utils.mk_res
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
Multiple items
type EntryPointAttribute =
  inherit Attribute
  new : unit -> EntryPointAttribute

Full name: Microsoft.FSharp.Core.EntryPointAttribute

--------------------
new : unit -> EntryPointAttribute
val testvals : string list
val iter : action:('T -> unit) -> list:'T list -> unit

Full name: Microsoft.FSharp.Collections.List.iter
Raw view Test code New version

More information

Link:http://fssnip.net/7W6
Posted:5 years ago
Author:Mark Laws
Tags: fparsec , parsing