forked from jasder/antlr
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.
|
/// 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
|
let ntags = starts.count
|
||||||
for i in 0..<ntags {
|
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)
|
throw ANTLRError.illegalArgument(msg: "tag delimiters out of order in pattern: " + pattern)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -408,7 +408,7 @@ public class ParseTreePatternMatcher {
|
||||||
// copy inside of <tag>
|
// copy inside of <tag>
|
||||||
let tag = pattern[starts[i] + start.length ..< stops[i]]
|
let tag = pattern[starts[i] + start.length ..< stops[i]]
|
||||||
var ruleOrToken = tag
|
var ruleOrToken = tag
|
||||||
var label = ""
|
var label: String?
|
||||||
let colon = tag.indexOf(":")
|
let colon = tag.indexOf(":")
|
||||||
if colon >= 0 {
|
if colon >= 0 {
|
||||||
label = tag[0 ..< colon]
|
label = tag[0 ..< colon]
|
||||||
|
@ -417,7 +417,7 @@ public class ParseTreePatternMatcher {
|
||||||
chunks.append(try TagChunk(label, ruleOrToken))
|
chunks.append(try TagChunk(label, ruleOrToken))
|
||||||
if i + 1 < ntags {
|
if i + 1 < ntags {
|
||||||
// copy from end of <tag> to start of next
|
// 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))
|
chunks.append(TextChunk(text))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,10 +87,19 @@ public class TagChunk: Chunk, CustomStringConvertible {
|
||||||
/// returned as just the tag name.
|
/// returned as just the tag name.
|
||||||
///
|
///
|
||||||
public var description: String {
|
public var description: String {
|
||||||
if label != nil {
|
if let label = label {
|
||||||
return label! + ":" + tag
|
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
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
///
|
|
||||||
///
|
///
|
||||||
/// The implementation for _org.antlr.v4.runtime.tree.pattern.TextChunk_ returns the result of
|
/// The implementation for _org.antlr.v4.runtime.tree.pattern.TextChunk_ returns the result of
|
||||||
/// _#getText()_ in single quotes.
|
/// _#getText()_ in single quotes.
|
||||||
///
|
///
|
||||||
|
|
||||||
|
|
||||||
public var description: String {
|
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