Merge pull request #2100 from ewanmellor/swift-fix-parsetreepatternmatcher

Fix ParseTreePatternMatcher.split in the Swift runtime.
This commit is contained in:
Terence Parr 2017-11-29 09:46:03 -08:00 committed by GitHub
commit afa2574862
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 68 additions and 14 deletions

View File

@ -17,5 +17,12 @@
/// regular tokens of the text surrounding the tags.
///
public class Chunk {
public class Chunk: Equatable {
public static func ==(lhs: Chunk, rhs: Chunk) -> Bool {
return lhs.isEqual(rhs)
}
public func isEqual(_ other: Chunk) -> Bool {
return false
}
}

View File

@ -387,7 +387,7 @@ public class ParseTreePatternMatcher {
let ntags = starts.count
for i in 0..<ntags {
if starts[i] != stops[i] {
if starts[i] >= stops[i] {
throw ANTLRError.illegalArgument(msg: "tag delimiters out of order in pattern: " + pattern)
}
}
@ -408,7 +408,7 @@ public class ParseTreePatternMatcher {
// copy inside of <tag>
let tag = pattern[starts[i] + start.length ..< stops[i]]
var ruleOrToken = tag
var label = ""
var label: String?
let colon = tag.indexOf(":")
if colon >= 0 {
label = tag[0 ..< colon]
@ -417,7 +417,7 @@ public class ParseTreePatternMatcher {
chunks.append(try TagChunk(label, ruleOrToken))
if i + 1 < ntags {
// copy from end of <tag> to start of next
let text = pattern[stops[i] + stop.length ..< starts[i] + 1]
let text = pattern[stops[i] + stop.length ..< starts[i + 1]]
chunks.append(TextChunk(text))
}
}

View File

@ -87,10 +87,19 @@ public class TagChunk: Chunk, CustomStringConvertible {
/// returned as just the tag name.
///
public var description: String {
if label != nil {
return label! + ":" + tag
if let label = label {
return "\(label):\(tag)"
}
else {
return tag
}
}
override public func isEqual(_ other: Chunk) -> Bool {
guard let other = other as? TagChunk else {
return false
}
return tag == other.tag && label == other.label
}
}

View File

@ -36,15 +36,19 @@ public class TextChunk: Chunk, CustomStringConvertible {
return text
}
///
///
///
/// The implementation for _org.antlr.v4.runtime.tree.pattern.TextChunk_ returns the result of
/// _#getText()_ in single quotes.
///
public var description: String {
return "'" + text + "'"
return "'\(text)'"
}
override public func isEqual(_ other: Chunk) -> Bool {
guard let other = other as? TextChunk else {
return false
}
return text == other.text
}
}

View File

@ -0,0 +1,34 @@
/// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
/// Use of this file is governed by the BSD 3-clause license that
/// can be found in the LICENSE.txt file in the project root.
import Foundation
import XCTest
import Antlr4
class ParseTreePatternMatcherTests: XCTestCase {
func testSplit() throws {
try doSplitTest("", [TextChunk("")])
try doSplitTest("Foo", [TextChunk("Foo")])
try doSplitTest("<ID> = <e:expr> ;",
[TagChunk("ID"), TextChunk(" = "), TagChunk("e", "expr"), TextChunk(" ;")])
try doSplitTest("\\<ID\\> = <e:expr> ;",
[TextChunk("<ID> = "), TagChunk("e", "expr"), TextChunk(" ;")])
}
}
private func doSplitTest(_ input: String, _ expected: [Chunk]) throws {
let matcher = try makeMatcher()
XCTAssertEqual(try matcher.split(input), expected)
}
private func makeMatcher() throws -> ParseTreePatternMatcher {
// The lexer and parser here aren't actually used. They're just here
// so that ParseTreePatternMatcher can be constructed, but in this file
// we're currently only testing methods that don't depend on them.
let lexer = Lexer()
let ts = BufferedTokenStream(lexer)
let parser = try Parser(ts)
return ParseTreePatternMatcher(lexer, parser)
}