2 people like it.

Simple four function calculator

This is a simple four function calculator using FParsec. It would be easy to replace the FParsec combinators with simple parsing combinators to produce the same results, but without the nice error messages produced by FParsec.

 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: 
open System
open FParsec
open FParsec.CharParsers

let token p = p .>> spaces

let number = token pint32
let c s = token (skipChar s)

let rec sum s = s |> chainl1 product (choice [c '+' >>% (+); c '-' >>% (-)])
and product s = s |> chainl1 atom    (choice [c '*' >>% (*); c '/' >>% (/)])
and atom    s = s |> choice [c '(' >>. sum .>> c ')'; number]

let parser = spaces >>. sum .>> eof

[<EntryPoint>]
let main argv =
  match argv with
   | [|input|] ->
     input
     |> runParserOnString parser () "input"
     |> function
         | Success (r, (), _) -> printfn "%d" r ; 0
         | Failure (s, _, ()) -> printfn "%s" s ; 1
   | _ ->
     printfn "Calculator 'expression'"
     1
namespace System
namespace FParsec
module CharParsers

from FParsec
val token : p:Parser<'a,'b> -> Parser<'a,'b>

Full name: Script.token
val p : Parser<'a,'b>
val spaces : Parser<unit,'u>

Full name: FParsec.CharParsers.spaces
val number : Parser<int32,unit>

Full name: Script.number
val pint32 : Parser<int32,'u>

Full name: FParsec.CharParsers.pint32
val c : s:char -> Parser<unit,'a>

Full name: Script.c
val s : char
val skipChar : char -> Parser<unit,'u>

Full name: FParsec.CharParsers.skipChar
val sum : s:CharStream<unit> -> Reply<int32>

Full name: Script.sum
val s : CharStream<unit>
val chainl1 : Parser<'a,'u> -> Parser<('a -> 'a -> 'a),'u> -> Parser<'a,'u>

Full name: FParsec.Primitives.chainl1
val product : s:CharStream<unit> -> Reply<int32>

Full name: Script.product
val choice : seq<Parser<'a,'u>> -> Parser<'a,'u>

Full name: FParsec.Primitives.choice
val atom : s:CharStream<unit> -> Reply<int32>

Full name: Script.atom
val parser : Parser<int32,unit>

Full name: Script.parser
val eof : Parser<unit,'u>

Full name: FParsec.CharParsers.eof
Multiple items
type EntryPointAttribute =
  inherit Attribute
  new : unit -> EntryPointAttribute

Full name: Microsoft.FSharp.Core.EntryPointAttribute

--------------------
new : unit -> EntryPointAttribute
val main : argv:string [] -> int

Full name: Script.main
val argv : string []
val input : string
val runParserOnString : Parser<'a,'u> -> 'u -> streamName:string -> string -> ParserResult<'a,'u>

Full name: FParsec.CharParsers.runParserOnString
union case ParserResult.Success: 'Result * 'UserState * Position -> ParserResult<'Result,'UserState>
val r : int32
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
union case ParserResult.Failure: string * ParserError * 'UserState -> ParserResult<'Result,'UserState>
val s : string
Raw view Test code New version

More information

Link:http://fssnip.net/qU
Posted:8 years ago
Author:Vesa Karvonen
Tags: parsing