Created
February 3, 2010 13:31
-
-
Save moiseev/293600 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type LogOp = | |
| Or | |
| And | |
type Cond = | |
| Eq | |
| Neq | |
| Greater | |
| Less | |
| GreaterOrEqual | |
| LessOrEqual | |
| Contains | |
| StartsWith | |
| EndsWith | |
| In | |
type Item = | |
| Prop of string array | |
type Val = | |
| Number of int | |
| Str of string | |
| Numbers of int array | |
| Strs of string array | |
type Clause = | |
| Simple of Item * Cond * Val | |
| Complex of Clause * LogOp * Clause |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Wepr | |
open System | |
open System.Linq | |
open System.Linq.Expressions | |
open System.Collections.Generic | |
module Extensions = | |
// F# extension methods | |
type System.Linq.IQueryable<'TSource> with | |
member this.Where (s:String) = | |
let expr = Wepr.GetExpression<'TSource> s :?> Expression<Func<'TSource, bool>> | |
Queryable.Where(this, expr) | |
type System.Collections.Generic.IEnumerable<'TSource> with | |
member this.Where (s:String) = | |
let dlg = Wepr.Compile<'TSource> s | |
let predicate (arg: 'TSource) = dlg.DynamicInvoke arg :?> bool | |
Enumerable.Where(this, predicate) | |
[<System.Runtime.CompilerServices.Extension>] | |
module QueryableExtensions = | |
open Extensions | |
// C#-visible extension methods | |
[<System.Runtime.CompilerServices.Extension>] | |
let Where (src:IQueryable<'a>, where:String) = src.Where(where) | |
[<System.Runtime.CompilerServices.Extension>] | |
module EnumerableExtensions = | |
open Extensions | |
[<System.Runtime.CompilerServices.Extension>] | |
let Where (src:IEnumerable<'a>, where:String) = src.Where(where) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
module Wepr.Lexer | |
open System | |
open System.Text | |
open Wepr | |
open Wepr.Parser | |
let toString bs = Encoding.ASCII.GetString(bs) | |
let unquote (s:String) = s.[1..(s.Length-2)] | |
let splitString (sep:String) (s:String) = s.Split([|sep|], StringSplitOptions.RemoveEmptyEntries) | |
let trimString (s:String) = s.Trim() | |
} | |
let whitespace = ['\t' ' '] | |
let quotes = ['\''] | |
let literal = ['a'-'z' 'A'-'Z']+ | |
let prop = ['a'-'z' 'A'-'Z' '.']+ | |
let number = ['0'-'9']+ | |
let quoted = ('\'' [^'\'']* '\'') | |
let in_strings = (quoted (',' [' ']+ quoted)*)+ | |
let in_numbers = (number (',' [' ']+ number)*)+ | |
rule token = parse | |
whitespace { token lexbuf } | |
| "AND" | "and" { AND } | |
| "OR" | "or" { OR } | |
| '(' { LPAREN } | |
| ')' { RPAREN } | |
| "=" { EQ } | |
| "!=" { NEQ } | |
| "<>" { NEQ } | |
| ">" { GREATER } | |
| "<" { LESS } | |
| ">=" { GREATEROREQ } | |
| "<=" { LESSOREQ } | |
| "Contains" { CONTAINS } | |
| "StartsWith" { STARTSWITH } | |
| "EndsWith" { ENDSWITH } | |
| number { INT (toString lexbuf.Lexeme |> Int32.Parse) } | |
| quoted { QUOTED (toString lexbuf.Lexeme |> unquote) } | |
| ("IN" | "in") { IN } | |
| in_strings { | |
STRINGS (toString lexbuf.Lexeme |> splitString "," |> Array.map (trimString >> unquote) )} | |
| in_numbers { | |
NUMBERS (toString lexbuf.Lexeme |> splitString "," |> Array.map (trimString >> Int32.Parse) )} | |
| prop { PROP (toString lexbuf.Lexeme |> splitString ".") } | |
| eof { EOF } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%{ | |
open Wepr | |
%} | |
%start Start | |
%token <string> STRING | |
%token <string> QUOTED | |
%token <string array> PROP | |
%token <string array> STRINGS | |
%token <int array> NUMBERS | |
%token <int> INT | |
%token LPAREN RPAREN DOT | |
%token AND OR | |
%token EQ NEQ LESS GREATER LESSOREQ GREATEROREQ CONTAINS STARTSWITH ENDSWITH IN | |
%token EOF | |
%type <Clause> Start | |
%% | |
Start: Clause { $1 } | |
Clause: | |
LPAREN Clause RPAREN { $2 } | |
| Clause AND Clause { Complex ($1, And, $3) } | |
| Clause OR Clause { Complex ($1, Or, $3) } | |
| Field EQ Literal { Simple ($1, Eq, $3) } | |
| Field NEQ Literal { Simple ($1, Neq, $3) } | |
| Field LESS Literal { Simple ($1, Less, $3) } | |
| Field GREATER Literal { Simple ($1, Greater, $3) } | |
| Field LESSOREQ Literal { Simple ($1, LessOrEqual, $3) } | |
| Field GREATEROREQ Literal { Simple ($1, GreaterOrEqual, $3) } | |
| Field CONTAINS Literal { Simple ($1, Contains, $3) } | |
| Field STARTSWITH Literal { Simple ($1, StartsWith, $3) } | |
| Field ENDSWITH Literal { Simple ($1, EndsWith, $3) } | |
| Field IN LPAREN STRINGS RPAREN { Simple ($1, In, (Strs $4)) } | |
| Field IN LPAREN NUMBERS RPAREN { Simple ($1, In, (Numbers $4)) } | |
Field: | |
| PROP { Prop ($1) } | |
Literal: | |
QUOTED { Str $1 } | |
| INT { Number $1 } | |
| STRINGS { Strs $1 } | |
| NUMBERS { Numbers $1 } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment