From bb1ebacb7b504d99997b73266a5067cf4eb8cbd5 Mon Sep 17 00:00:00 2001 From: Coen Wessels Date: Mon, 31 Aug 2015 19:54:01 +0200 Subject: [PATCH 1/2] Updated the dependencies --- Cartfile | 8 +-- Cartfile.private | 4 +- Cartfile.resolved | 14 ++--- Carthage/Checkouts/Box | 2 +- Carthage/Checkouts/Either | 2 +- Carthage/Checkouts/Madness | 2 +- Carthage/Checkouts/Nimble | 2 +- Carthage/Checkouts/Prelude | 2 +- Carthage/Checkouts/Quick | 2 +- Carthage/Checkouts/xcconfigs | 2 +- OGDL/Parser.swift | 111 ++++++++++++++++++----------------- OGDLTests/ParserSpec.swift | 30 +++++----- 12 files changed, 91 insertions(+), 90 deletions(-) diff --git a/Cartfile b/Cartfile index e424d0f..f3045b7 100644 --- a/Cartfile +++ b/Cartfile @@ -1,4 +1,4 @@ -github "robrix/Madness" "significant-indentation" -github "robrix/Either" ~> 1.1 -github "robrix/Box" ~> 1.0.1 -github "robrix/Prelude" ~> 1.4 +github "robrix/Madness" "master" +github "robrix/Either" ~> 1.2.2 +github "robrix/Box" ~> 1.2.2 +github "robrix/Prelude" ~> 1.5 diff --git a/Cartfile.private b/Cartfile.private index e88c05b..4c81532 100644 --- a/Cartfile.private +++ b/Cartfile.private @@ -1,3 +1,3 @@ github "jspahrsummers/xcconfigs" -github "Quick/Quick" ~> 0.2.2 -github "Quick/Nimble" ~> 0.2 +github "Quick/Quick" ~> 0.3.1 +github "Quick/Nimble" ~> 1.0.0 diff --git a/Cartfile.resolved b/Cartfile.resolved index 24c98e1..1105559 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,7 +1,7 @@ -github "robrix/Box" "1.0.1" -github "robrix/Either" "1.1" -github "robrix/Madness" "b5e2882e924b2377da83adcdb59592ba7fdab52a" -github "Quick/Nimble" "v0.2.0" -github "robrix/Prelude" "1.4" -github "Quick/Quick" "v0.2.2" -github "jspahrsummers/xcconfigs" "0.7.1" +github "robrix/Box" "1.2.2" +github "Quick/Nimble" "v1.0.0" +github "robrix/Prelude" "1.5.0" +github "Quick/Quick" "v0.3.1" +github "jspahrsummers/xcconfigs" "0.8.1" +github "robrix/Either" "1.2.2" +github "robrix/Madness" "fa440dd21e7341f687f748afd98ccb12574e1bd0" diff --git a/Carthage/Checkouts/Box b/Carthage/Checkouts/Box index 1bb4b48..bbe4e61 160000 --- a/Carthage/Checkouts/Box +++ b/Carthage/Checkouts/Box @@ -1 +1 @@ -Subproject commit 1bb4b482fddbad54466e73f91e98bca5c59abf54 +Subproject commit bbe4e612a03ffe0bbb0e2e476c2be4534b6777a5 diff --git a/Carthage/Checkouts/Either b/Carthage/Checkouts/Either index af46d1e..e26f160 160000 --- a/Carthage/Checkouts/Either +++ b/Carthage/Checkouts/Either @@ -1 +1 @@ -Subproject commit af46d1e2952753fda70c6f5984ee713fb4c6e9be +Subproject commit e26f160a978bea26ddc4efce92edeee9dd2085cc diff --git a/Carthage/Checkouts/Madness b/Carthage/Checkouts/Madness index b5e2882..fa440dd 160000 --- a/Carthage/Checkouts/Madness +++ b/Carthage/Checkouts/Madness @@ -1 +1 @@ -Subproject commit b5e2882e924b2377da83adcdb59592ba7fdab52a +Subproject commit fa440dd21e7341f687f748afd98ccb12574e1bd0 diff --git a/Carthage/Checkouts/Nimble b/Carthage/Checkouts/Nimble index 6f787ee..61697d0 160000 --- a/Carthage/Checkouts/Nimble +++ b/Carthage/Checkouts/Nimble @@ -1 +1 @@ -Subproject commit 6f787eeb75b2fa71464981f28b3dc8d7bd532e69 +Subproject commit 61697d0b11bc5160fd620737365dcdd31cd5cf86 diff --git a/Carthage/Checkouts/Prelude b/Carthage/Checkouts/Prelude index dcd04cb..223829a 160000 --- a/Carthage/Checkouts/Prelude +++ b/Carthage/Checkouts/Prelude @@ -1 +1 @@ -Subproject commit dcd04cb7de654f8ee122890fa43f2df1f49306a9 +Subproject commit 223829acf3f8a44fb56388f56d55c0fb98fbd81e diff --git a/Carthage/Checkouts/Quick b/Carthage/Checkouts/Quick index b0e9828..8bf96f7 160000 --- a/Carthage/Checkouts/Quick +++ b/Carthage/Checkouts/Quick @@ -1 +1 @@ -Subproject commit b0e98286db7e9d1f1e73cd4e69eac2aae2a1e3f8 +Subproject commit 8bf96f708924d728dab5f0cf7543b6f1b896a209 diff --git a/Carthage/Checkouts/xcconfigs b/Carthage/Checkouts/xcconfigs index b09b4b6..99624a6 160000 --- a/Carthage/Checkouts/xcconfigs +++ b/Carthage/Checkouts/xcconfigs @@ -1 +1 @@ -Subproject commit b09b4b63235b760a3a48a8dd19c0415aaaa8f269 +Subproject commit 99624a6af366c015b678a1135e4c558776a59be6 diff --git a/OGDL/Parser.swift b/OGDL/Parser.swift index e652365..2a4498f 100644 --- a/OGDL/Parser.swift +++ b/OGDL/Parser.swift @@ -12,30 +12,27 @@ import Madness import Prelude /// Returns a parser which parses one character from the given set. -internal prefix func % (characterSet: NSCharacterSet) -> Parser.Function { - return { string in - let scalars = string.unicodeScalars - - if let scalar = first(scalars) { - if characterSet.longCharacterIsMember(scalar.value) { - return (String(scalar), String(dropFirst(scalars))) - } - } - - return nil +internal prefix func % (characterSet: NSCharacterSet) -> Parser.Function { + return { collection, index in + if index != collection.endIndex { + if let scalar = first(String(collection[index]).unicodeScalars) where characterSet.longCharacterIsMember(scalar.value) { + return .right(String(scalar), index.successor()) + } + } + return .left(.leaf("Character is not present in NSCharacterSet", index)) } } /// Removes the characters in the given string from the character set. internal func - (characterSet: NSCharacterSet, characters: String) -> NSCharacterSet { - let mutableSet = characterSet.mutableCopy() as NSMutableCharacterSet + let mutableSet = characterSet.mutableCopy() as! NSMutableCharacterSet mutableSet.removeCharactersInString(characters) return mutableSet } /// Removes characters in the latter set from the former. internal func - (characterSet: NSCharacterSet, subtrahend: NSCharacterSet) -> NSCharacterSet { - let mutableSet = characterSet.mutableCopy() as NSMutableCharacterSet + let mutableSet = characterSet.mutableCopy() as! NSMutableCharacterSet mutableSet.formIntersectionWithCharacterSet(subtrahend.invertedSet) return mutableSet } @@ -44,8 +41,8 @@ internal func - (characterSet: NSCharacterSet, subtrahend: NSCharacterSet) -> NS postfix operator |? {} /// Matches zero or one occurrence of the given parser. -internal postfix func |? (parser: Parser.Function) -> Parser.Function { - return (parser * (0..<2)) --> first +internal postfix func |? (parser: Parser.Function) -> Parser.Function { + return first <^> (parser * (0..<2)) } private let char_control = NSCharacterSet.controlCharacterSet() @@ -57,43 +54,46 @@ private let char_break = NSCharacterSet.newlineCharacterSet() // TODO: Use this somewhere. private let char_end = char_control - NSCharacterSet.whitespaceAndNewlineCharacterSet() -private let wordStart: Parser.Function = %(char_word - "#'\"") -private let wordChars: Parser.Function = (%(char_word - "'\""))* --> { strings in join("", strings) } -private let word: Parser.Function = wordStart ++ wordChars --> (+) -private let br: Parser<()>.Function = ignore(%char_break) -private let eof: Parser<()>.Function = { $0 == "" ? ((), "") : nil } -private let comment: Parser<()>.Function = ignore(%"#" ++ (%char_text)+ ++ (br | eof)) +private let wordStart: Parser.Function = %(char_word - "#'\"") +private let wordChars: Parser.Function = { join("", $0) } <^> (%(char_word - "'\""))* +private let word: Parser.Function = (+) <^> wordStart ++ wordChars +private let br: Parser.Function = ignore(%char_break) +private let eof: Parser.Function = ignore("")//{ $0 == "" ? ((), "") : nil } + +private let br_eof = br | eof +private let comment: Parser.Function = ignore(%"#" ++ (%char_text)+ ++ br_eof) + // TODO: Escape sequences. -private let singleQuotedChars: Parser.Function = (%(char_text - "'"))* --> { strings in join("", strings) } -private let singleQuoted: Parser.Function = ignore(%"'") ++ singleQuotedChars ++ ignore(%"'") -private let doubleQuotedChars: Parser.Function = (%(char_text - "\""))* --> { strings in join("", strings) } -private let doubleQuoted: Parser.Function = ignore(%"\"") ++ doubleQuotedChars ++ ignore(%"\"") -private let quoted: Parser.Function = singleQuoted | doubleQuoted -private let requiredSpace: Parser<()>.Function = ignore((comment | %char_space)+) -private let optionalSpace: Parser<()>.Function = ignore((comment | %char_space)*) -private let separator: Parser<()>.Function = ignore(optionalSpace ++ %"," ++ optionalSpace) +private let singleQuotedChars: Parser.Function = { join("", $0) } <^> (%(char_text - "'"))* +private let singleQuoted: Parser.Function = ignore(%"'") ++ singleQuotedChars ++ ignore(%"'") +private let doubleQuotedChars: Parser.Function = { join("", $0) } <^> (%(char_text - "\""))* +private let doubleQuoted: Parser.Function = ignore(%"\"") ++ doubleQuotedChars ++ ignore(%"\"") +private let quoted: Parser.Function = singleQuoted | doubleQuoted +private let requiredSpace: Parser.Function = ignore((comment | %char_space)+) +private let optionalSpace: Parser.Function = ignore((comment | %char_space)*) +private let separator: Parser.Function = ignore(optionalSpace ++ %"," ++ optionalSpace) -private let value: Parser.Function = word | quoted +private let value: Parser.Function = word | quoted /// A function taking an Int and returning a parser which parses at least that many /// indentation characters. -func indentation(n: Int) -> Parser.Function { - return (%char_space * (n.. { $0.count } +func indentation(n: Int) -> Parser.Function { + return count <^> (%char_space * (n..(parser: () -> Parser.Function) -> Parser.Function { +private func lazy(parser: () -> Parser.Function) -> Parser.Function { return { parser()($0) } } /// Returns a parser which produces an array of parse trees produced by `parser` interleaved with ignored parses of `separator`. /// /// This is convenient for e.g. comma-separated lists. -private func interleave(separator: Parser.Function, parser: Parser.Function) -> Parser<[T]>.Function { - return (parser ++ (ignore(separator) ++ parser)*) --> { [$0] + $1 } +private func interleave(separator: Parser.Function, parser: Parser.Function) -> Parser.Function { + return { [$0] + $1 } <^> (parser ++ (ignore(separator) ++ parser)*) } private func foldr(sequence: S, initial: Result, combine: (S.Generator.Element, Result) -> Result) -> Result { @@ -105,12 +105,12 @@ private func foldr(inout generator: G, initial: Result return generator.next().map { combine($0, foldr(&generator, initial, combine)) } ?? initial } -private func | (left: Parser.Function, right: String -> U) -> Parser>.Function { - return left | { (right($0), $0) } +private func | (left: Parser.Function, right: () -> U) -> Parser>.Function { + return left | { .right(right(), $1 == $0.endIndex ? $1 : $1.successor()) } } -private func | (left: Parser.Function, right: String -> T) -> Parser.Function { - return left | { (right($0), $0) } +private func | (left: Parser.Function, right: () -> T) -> Parser.Function { + return left | { .right(right(), $1 == $0.endIndex ? $1 : $1.successor()) } } private func flatMap(x: [T], f: T -> [U]) -> [U] { @@ -119,45 +119,46 @@ private func flatMap(x: [T], f: T -> [U]) -> [U] { // MARK: OGDL -private let children: Parser<[Node]>.Function = lazy { group | (element --> { elem in [ elem ] }) } +private let children: Parser.Function = lazy { group | ({ elem in [ elem ] } <^> element) } -private let element = lazy { value ++ (optionalSpace ++ children)|? --> { value, children in Node(value: value, children: children ?? []) } } +private let element = lazy { { Node(value: $0, children: $1 ?? []) } <^> value ++ (optionalSpace ++ children)|? } // TODO: See Carthage/ogdl-swift#3. -private let block: Int -> Parser<()>.Function = { n in const(nil) } +private let block: Int -> Parser.Function = { _ in ignore(any) } /// Parses a single descendent element. /// /// This is an element which may be an in-line descendent, and which may further have in-line descendents of its own. -private let descendent = value --> { Node(value: $0) } +private let descendent = { Node(value: $0) } <^> value /// Parses a sequence of hierarchically descending elements, e.g.: /// /// x y z # => Node(x, [Node(y, Node(z))]) -public let descendents: Parser.Function = interleave(requiredSpace, descendent) --> { - foldr(dropLast($0), last($0)!) { $0.nodeByAppendingChildren([ $1 ]) } -} +public let descendents: Parser.Function = + { foldr(dropLast($0), last($0)!) { $0.nodeByAppendingChildren([ $1 ]) } } + <^> interleave(requiredSpace, descendent) /// Parses a chain of descendents, optionally ending in a group. /// /// x y (u, v) # => Node(x, [ Node(y, [ Node(u), Node(v) ]) ]) -private let descendentChain: Parser.Function = (descendents ++ ((optionalSpace ++ group) | const([]))) --> uncurry(Node.nodeByAppendingChildren) +private let descendentChain: Parser.Function = + uncurry(Node.nodeByAppendingChildren) <^> (descendents ++ ((optionalSpace ++ group) | const([]))) /// Parses a sequence of adjacent sibling elements, e.g.: /// /// x, y z, w (u, v) # => [ Node(x), Node(y, Node(z)), Node(w, [ Node(u), Node(v) ]) ] -public let adjacent: Parser<[Node]>.Function = lazy { interleave(separator, descendentChain) } +public let adjacent: Parser.Function = lazy { interleave(separator, descendentChain) } /// Parses a parenthesized sequence of sibling elements, e.g.: /// /// (x, y z, w) # => [ Node(x), Node(y, Node(z)), Node(w) ] private let group = lazy { ignore(%"(") ++ optionalSpace ++ adjacent ++ optionalSpace ++ ignore(%")") } -private let subgraph: Int -> Parser<[Node]>.Function = { n in - (descendents ++ lines(n + 1) --> { [ $0.nodeByAppendingChildren($1) ] }) | adjacent +private let subgraph: Int -> Parser.Function = { n in + ({ [ $0.nodeByAppendingChildren($1) ] } <^> descendents ++ lines(n + 1)) | adjacent } -private let line: Int -> Parser<[Node]>.Function = fix { line in +private let line: Int -> Parser.Function = fix { line in { n in // TODO: block parsing: ignore(%char_space+ ++ block(n))|?) ++ // See Carthage/ogdl-swift#3. @@ -167,9 +168,9 @@ private let line: Int -> Parser<[Node]>.Function = fix { line in } } -private let followingLine: Int -> Parser<[Node]>.Function = { n in (ignore(comment | br)+ ++ line(n)) } -private let lines: Int -> Parser<[Node]>.Function = { n in - (line(n)|? ++ followingLine(n)*) --> { ($0 ?? []) + flatMap($1, id) } +private let followingLine: Int -> Parser.Function = { n in (ignore(comment | br)+ ++ line(n)) } +private let lines: Int -> Parser.Function = { n in + { ($0 ?? []) + flatMap($1, id) } <^> (line(n)|? ++ followingLine(n)*) } /// Parses a textual OGDL graph into a list of nodes (and their descendants). @@ -177,4 +178,4 @@ private let lines: Int -> Parser<[Node]>.Function = { n in /// Example: /// /// let nodes = parse(graph, "foo (bar, buzz baz)") -public let graph: Parser<[Node]>.Function = ignore(comment | br)* ++ (lines(0) | adjacent) ++ ignore(comment | br)* +public let graph: Parser.Function = ignore(comment | br)* ++ (lines(0) | adjacent) ++ ignore(comment | br)* diff --git a/OGDLTests/ParserSpec.swift b/OGDLTests/ParserSpec.swift index a75a907..c4ca8c6 100644 --- a/OGDLTests/ParserSpec.swift +++ b/OGDLTests/ParserSpec.swift @@ -15,34 +15,34 @@ import Quick class ParserSpec: QuickSpec { override func spec() { it("should parse the empty string") { - expect(parse(graph, "")).to(equal([])) + expect(parse(graph, "").right).to(equal([])) } it("should parse a line break") { - expect(parse(graph, "\n")).to(equal([])) + expect(parse(graph, "\n").right).to(equal([])) } it("should parse a series of line breaks") { - expect(parse(graph, "\n\n\n")).to(equal([])) + expect(parse(graph, "\n\n\n").right).to(equal([])) } it("should parse a single node with descendents") { - expect(parse(descendents, "foobar")).to(equal(Node(value: "foobar"))) + expect(parse(descendents, "foobar").right).to(equal(Node(value: "foobar"))) } it("should parse a single node with adjacent") { - expect(parse(adjacent, "foobar")).to(equal([ Node(value: "foobar") ])) + expect(parse(adjacent, "foobar").right).to(equal([ Node(value: "foobar") ])) } it("should parse a single node") { let expectedGraph = [ Node(value: "foobar") ] - let parsedGraph = parse(graph, "foobar") + let parsedGraph = parse(graph, "foobar").right expect(parsedGraph).to(equal(expectedGraph)) } it("should parse a single node ending with a newline") { let expectedGraph = [ Node(value: "foobar") ] - let parsedGraph = parse(graph, "foobar\n") + let parsedGraph = parse(graph, "foobar\n").right expect(parsedGraph).to(equal(expectedGraph)) } @@ -57,7 +57,7 @@ class ParserSpec: QuickSpec { ]) ] - let parsedGraph = parse(graph, "foo bar fuzz buzz") + let parsedGraph = parse(graph, "foo bar fuzz buzz").right expect(parsedGraph).to(equal(expectedGraph)) } @@ -70,7 +70,7 @@ class ParserSpec: QuickSpec { ]) ] - let parsedGraph = parse(graph, "foo \"bar\" \"fuzz buzz\"") + let parsedGraph = parse(graph, "foo \"bar\" \"fuzz buzz\"").right expect(parsedGraph).to(equal(expectedGraph)) } @@ -86,7 +86,7 @@ class ParserSpec: QuickSpec { ]) ] - let parsedGraph = parse(graph, "foo bar, fuzz buzz") + let parsedGraph = parse(graph, "foo bar, fuzz buzz").right expect(parsedGraph).to(equal(expectedGraph)) } @@ -99,7 +99,7 @@ class ParserSpec: QuickSpec { ]) ] - let parsedGraph = parse(graph, "foo (bar, quux)") + let parsedGraph = parse(graph, "foo (bar, quux)").right expect(parsedGraph).to(equal(expectedGraph)) } @@ -112,12 +112,12 @@ class ParserSpec: QuickSpec { ]) ] - let parsedGraph = parse(graph, "foo ( bar.o 1.2, quux.o 2.1 )") + let parsedGraph = parse(graph, "foo ( bar.o 1.2, quux.o 2.1 )").right expect(parsedGraph).to(equal(expectedGraph)) } it("should parse comments") { - let parsedGraph = parse(graph, "#foo") + let parsedGraph = parse(graph, "#foo").right expect(parsedGraph).to(equal([])) } @@ -142,10 +142,10 @@ class ParserSpec: QuickSpec { for i in 1...5 { let URL = NSBundle(forClass: self.dynamicType).URLForResource("Example2-\(i)", withExtension: "ogdl", subdirectory: "Samples")! - let sample = NSString(contentsOfURL: URL, encoding: NSUTF8StringEncoding, error: nil) + let sample = NSString(contentsOfURL: URL, encoding: NSUTF8StringEncoding, error: nil) as? String expect(sample).notTo(beNil()) - let parsedGraph = parse(graph, sample ?? "") + let parsedGraph = parse(graph, sample ?? "").right if let parsedGraph = parsedGraph { println("graph \(i):\n\(parsedGraph)\n") } From 34be29f989389aed8d147f3acd40b3467eaced09 Mon Sep 17 00:00:00 2001 From: Coen Wessels Date: Fri, 4 Sep 2015 11:47:50 +0200 Subject: [PATCH 2/2] Fix comma-separated siblings and groups --- OGDL/Parser.swift | 11 ++++------- OGDLTests/ParserSpec.swift | 6 ++---- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/OGDL/Parser.swift b/OGDL/Parser.swift index 2a4498f..09bf48b 100644 --- a/OGDL/Parser.swift +++ b/OGDL/Parser.swift @@ -119,10 +119,6 @@ private func flatMap(x: [T], f: T -> [U]) -> [U] { // MARK: OGDL -private let children: Parser.Function = lazy { group | ({ elem in [ elem ] } <^> element) } - -private let element = lazy { { Node(value: $0, children: $1 ?? []) } <^> value ++ (optionalSpace ++ children)|? } - // TODO: See Carthage/ogdl-swift#3. private let block: Int -> Parser.Function = { _ in ignore(any) } @@ -138,11 +134,12 @@ public let descendents: Parser.Function = { foldr(dropLast($0), last($0)!) { $0.nodeByAppendingChildren([ $1 ]) } } <^> interleave(requiredSpace, descendent) +private let children: Parser.Function = lazy { group | ({ [$0] } <^> descendentChain) } + /// Parses a chain of descendents, optionally ending in a group. /// /// x y (u, v) # => Node(x, [ Node(y, [ Node(u), Node(v) ]) ]) -private let descendentChain: Parser.Function = - uncurry(Node.nodeByAppendingChildren) <^> (descendents ++ ((optionalSpace ++ group) | const([]))) +private let descendentChain = lazy { { Node(value: $0, children: $1 ?? []) } <^> value ++ (optionalSpace ++ children)|? } /// Parses a sequence of adjacent sibling elements, e.g.: /// @@ -155,7 +152,7 @@ public let adjacent: Parser.Function = lazy { interleave(separat private let group = lazy { ignore(%"(") ++ optionalSpace ++ adjacent ++ optionalSpace ++ ignore(%")") } private let subgraph: Int -> Parser.Function = { n in - ({ [ $0.nodeByAppendingChildren($1) ] } <^> descendents ++ lines(n + 1)) | adjacent + adjacent | ({ [ $0.nodeByAppendingChildren($1) ] } <^> descendents ++ lines(n + 1)) } private let line: Int -> Parser.Function = fix { line in diff --git a/OGDLTests/ParserSpec.swift b/OGDLTests/ParserSpec.swift index c4ca8c6..c88c56e 100644 --- a/OGDLTests/ParserSpec.swift +++ b/OGDLTests/ParserSpec.swift @@ -74,8 +74,7 @@ class ParserSpec: QuickSpec { expect(parsedGraph).to(equal(expectedGraph)) } - // TODO: Not yet supported. See Carthage/ogdl-swift#6. - pending("should parse siblings") { + it("should parse siblings") { let expectedGraph = [ Node(value: "foo", children: [ Node(value: "bar") @@ -90,8 +89,7 @@ class ParserSpec: QuickSpec { expect(parsedGraph).to(equal(expectedGraph)) } - // TODO: Not yet supported. See Carthage/ogdl-swift#7. - pending("should parse grouped siblings") { + it("should parse grouped siblings") { let expectedGraph = [ Node(value: "foo", children: [ Node(value: "bar"),