namespace ParseExample [] type Expr = | Plus of Expr * Expr | Times of Expr * Expr | UnaryMinus of Expr | Minus of Expr * Expr | Equal of Expr * Expr | Int of int | FunctionCall of Expr * Expr | Var of string | Factorial of Expr | Paren of Expr | IfThenElse of Expr * Expr * Expr | IfThen of Expr * Expr | ArrayIndex of Expr * Expr [] module Expr = let plus a b = Expr.Plus (a, b) let equal a b = Expr.Equal (a, b) let times a b = Expr.Times (a, b) let unaryMinus a = Expr.UnaryMinus a let minus a b = Expr.Minus (a, b) let constInt a = Expr.Int a let functionCall f x = Expr.FunctionCall (f, x) let var name = Expr.Var name let factorial a = Expr.Factorial a let paren a = Expr.Paren a let arrayIndex a b = Expr.ArrayIndex (a, b) let ifThenElse ifClause thenClause elseClause = Expr.IfThenElse (ifClause, thenClause, elseClause) let ifThen ifClause thenClause = Expr.IfThen (ifClause, thenClause) [] type TokenType = | Plus | Minus | Times | Equal | ConstInt | LeftBracket | RightBracket | ArrayIndex | RightSquareBracket | Var | Factorial | If | Then | Else type Token = { Type : TokenType /// The token is represented in the string as s.[left .. left + len], i.e. inclusive. Trivia : int * int } [] module Token = let standalone (ty : TokenType) (left : int) (len : int) = { Type = ty Trivia = (left, len) } let standalone' (ty : TokenType) (singleCharPos : int) = { Type = ty Trivia = (singleCharPos, 1) } let (|SingleChar|_|) (i : int, c : char) : Token option = match c with | '(' -> standalone' TokenType.LeftBracket i |> Some | ')' -> standalone' TokenType.RightBracket i |> Some | '*' -> standalone' TokenType.Times i |> Some | '+' -> standalone' TokenType.Plus i |> Some | '-' -> standalone' TokenType.Minus i |> Some | '!' -> standalone' TokenType.Factorial i |> Some | '=' -> standalone' TokenType.Equal i |> Some | ']' -> standalone' TokenType.RightSquareBracket i |> Some | _ -> None