Fix ParseTreePatternMatcher.split in the Swift runtime.
Fix the parsing inside ParseTreePatternMatcher.split. It was trivially broken in a number of ways, with bugs that aren't in the Java version that it was ported from, so it's obviously never been run before. This adds unit tests for ParseTreePatternMatcher.split, and makes Chunk implement Equatable, so that it we can compare Chunk instances in the tests. Tidy up the description implementations at the same time.
This commit is contained in:
parent
b4c34da1f0
commit
fd8fd175a6
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
Loading…
Reference in New Issue