Advertisement
Guest User

FOL parser

a guest
Jul 1st, 2015
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 2.83 KB | None | 0 0
  1. #I "packages/FParsec.1.0.1/lib/net40-client/"
  2.  
  3. #r "FParsecCS.dll"
  4. #r "FParsec.dll"
  5.  
  6. open FParsec
  7.  
  8. let test p str =
  9.     match run p str with
  10.     | Success(result, _, _)   -> printfn "Success: %A" result
  11.     | Failure(errorMsg, _, _) -> printfn "Failure: %s" errorMsg
  12.  
  13. //Types
  14. type Term = | Function of string * Term list
  15.             | Constant of string
  16.             | Variable of string
  17.  
  18. type Predicate = | Predicate of string * Term list
  19.                  | Equality of Term * Term
  20.  
  21. type Expr = | Atom of Predicate
  22.             | Not of Expr
  23.             | And of Expr * Expr
  24.             | Or of Expr * Expr
  25.             | Impl of Expr * Expr
  26.             | Bicond of Expr * Expr
  27.             | ForAll of string list * Expr
  28.             | Exists of string list * Expr
  29.  
  30. //Parsing
  31. let ws = spaces
  32. let str_ws s = pstring s .>> ws
  33.  
  34. type IdentifierType = Var | NotVar                        
  35.  
  36. let identifier t =
  37.     let fl, err = match t with
  38.                   | Var -> isLower, "variable"
  39.                   | NotVar -> isUpper, "non-variable identifier"    
  40.     let isChar c = isLetter c || isDigit c || c = '_'    
  41.     many1Satisfy2L fl isChar err .>> ws
  42.  
  43.  
  44. let term, pRefTerm = createParserForwardedToRef()
  45.  
  46. let func =
  47.     //NOTE: Second part fails immediately if there is no opening bracket,
  48.     //so backtracking occurs
  49.     identifier NotVar .>>.? (between (str_ws "(") (str_ws ")") (sepBy1 term (str_ws ",")))
  50.         |>> Function
  51.  
  52. do pRefTerm := choice [
  53.         func;
  54.         identifier NotVar |>> Constant;
  55.         identifier Var |>> Variable;
  56.     ]
  57.  
  58. let termEquality =
  59.     term .>>? str_ws "=" .>>. term |>> Equality
  60.  
  61. let predicate =
  62.     choice [
  63.         termEquality;
  64.         identifier NotVar .>>.? (between (str_ws "(") (str_ws ")") (sepBy1 term (str_ws ","))) |>> Predicate
  65.         identifier NotVar |>> (fun n -> Predicate (n,[]))
  66.     ]
  67.        
  68. let opp = new OperatorPrecedenceParser<Expr,unit,unit>()
  69. let expr = opp.ExpressionParser
  70.  
  71. let quantifiedExpr isForAll =
  72.     let l,ctor = match isForAll with
  73.                  | true -> "A", ForAll
  74.                  | false -> "E", Exists
  75.     str_ws ("[" + l + "]") >>. sepBy1 (identifier Var) (str_ws ",") .>>. expr |>> ctor      
  76.  
  77. opp.TermParser <- choice [
  78.     quantifiedExpr true
  79.     quantifiedExpr false
  80.     predicate |>> Atom
  81.     between (str_ws "(") (str_ws ")") expr
  82. ]  
  83. opp.AddOperator(PrefixOperator("!", ws, 5, true, fun x -> Not x))
  84. opp.AddOperator(InfixOperator("&", ws, 4, Associativity.Left, fun x y -> And (x,y)))
  85. opp.AddOperator(InfixOperator("|", ws, 3, Associativity.Left, fun x y -> Or (x,y)))
  86. opp.AddOperator(InfixOperator("=>", ws, 2, Associativity.Left, fun x y -> Impl (x,y)))
  87. opp.AddOperator(InfixOperator("<=>", ws, 1, Associativity.Left, fun x y -> Bicond (x,y)))
  88.  
  89. test expr "[A] x !Pred1 & (([E] y Func1(x,y) = Func2(C1)) | Pred2)"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement