Kiln » babybearparser
Clone URL:  
Pushed to one repository · View In Graph Contained in tip

Better error parsing.

Changeset 17b2b6ad680b

Parent ab91a87e0efb

by Profile picture of User 138Hao Lian <hao@fogcreek.com>

Changes to 2 files · Browse files at 17b2b6ad680b Showing diff from parent ab91a87e0efb Diff from another changeset...

 
27
28
29
 
30
 
 
 
 
 
 
31
 
32
33
34
 
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 
51
52
53
 
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 
45
46
47
 
 
 
 
 
 
 
48
49
50
 
51
52
53
54
@@ -27,8 +27,16 @@
   exception ParseError of string   +(* Utilities *)  let pipeline (f, a) = f a +let findFilter = function + | "author" -> Author + | "file" -> File + | "project" -> Project + | "repo" -> Repo + | _ -> raise <| Exception "Invalid filter name"   +(* Parsers *)  let word = many1Satisfy <| fun c -> c <> ' '  let phraseEscape = pchar '\\' >>. pchar '"'  let phraseInnard = phraseEscape <|> noneOf "\"" @@ -37,17 +45,10 @@
 let keyword = (phrase |>> Phrase) <|> (word |>> Word)    let filterName = ["author"; "file"; "project"; "repo"] |> Seq.map pstring |> choice -let findFilter = function - | "author" -> Author - | "file" -> File - | "project" -> Project - | "repo" -> Repo - | _ -> raise <| Exception "Invalid filter name" -  let filter =   (filterName |>> findFilter)   .>> (pchar ':') - .>>. (phrase <|> word) + .>>. (phrase <|> word <?> "filter argument")   |>> pipeline    let atom = (filter |>> FilterAtom) <|> (keyword |>> KeywordAtom)
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
65
66
 
 
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
65
 
 
66
 module babybearparser.Testing    open FParsec  open Microsoft.VisualStudio.TestTools.UnitTesting  open System    open babybearparser.Parser   -let equals actual expected = Assert.AreEqual (expected, actual) -let throws<'a when 'a :> exn> (f: unit -> unit) = +let equals actual expected = Assert.IsTrue ((actual = expected), String.Format("{0} <> {1}", actual, expected)) +let throwsParseError (f: unit -> unit) contains =   try - f(); Assert.Fail ("throws: no exception thrown of type: " + typedefof<'a>.Name) + f(); Assert.Fail ("throws: no exception thrown of type ParseError")   with - | :? 'a -> () + | ParseError(x) -> Assert.IsTrue (x.Contains(contains), String.Format("{0} does not contain {1}", x, contains))    [<TestClass>]  type public Tests () =   (* Tests that testing works *)   [<TestMethod>]   member this.TestsWorking() =   equals 1 1 - +   [<TestMethod>]   member this.TestsKeywords() =   equals (parse "foo bar") [KeywordAtom <| Word "foo"; KeywordAtom <| Word "bar"]     [<TestMethod>]   member this.TestsEmpty() =   equals (List.length <| parse "") 0     [<TestMethod>]   member this.TestsPhrase() =   equals (parse "\"foo \\\" bar\"") [KeywordAtom <| Phrase "foo \" bar"]     [<TestMethod>]   member this.TestsPhraseAndKeyword() =   equals (parse "\"foo bar\" boo") [KeywordAtom <| Phrase "foo bar"; KeywordAtom <| Word "boo"]     [<TestMethod>]   member this.TestsFilter() =   equals (parse "\"foo bar\" project:boo") [KeywordAtom <| Phrase "foo bar"; FilterAtom <| Project "boo"]     [<TestMethod>]   member this.TestsFilters() =   equals (parse "\"foo bar\" project:boo repo:radley") [KeywordAtom <| Phrase "foo bar"; FilterAtom <| Project "boo"; FilterAtom <| Repo "radley"]     [<TestMethod>]   member this.TestsFilterPhrase() =   equals (parse "\"foo bar\" project:\"boo radley\"") [KeywordAtom <| Phrase "foo bar"; FilterAtom <| Project "boo radley"]     [<TestMethod>]   member this.TestsEmptyFilter() =   equals (parse "\"foo bar\" project:\"\"") [KeywordAtom <| Phrase "foo bar"; FilterAtom <| Project ""]     [<TestMethod>]   member this.TestsConfusingFilter() =   equals (parse ":taft:") [KeywordAtom <| Word ":taft:"]     [<TestMethod>]   member this.TestsMissingFilter() =   let f () = parse "\"foo bar\" project:" |> ignore - throws<ParseError> f + throwsParseError f "filter argument"     [<TestMethod>]   member this.TestsUnknownFilter() = - equals (parse "unknown:careless") [KeywordAtom <| Word "unknown:careless"] \ No newline at end of file
+ equals (parse "unknown:careless") [KeywordAtom <| Word "unknown:careless"]