diff --git a/Package.resolved b/Package.resolved index caf85107..f32c6aab 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,5 +1,14 @@ { "pins" : [ + { + "identity" : "antlr4", + "kind" : "remoteSourceControl", + "location" : "https://github.com/antlr/antlr4", + "state" : { + "branch" : "4.10.1", + "revision" : "44d87bc1d130c88aa452894aa5f7e2f710f68253" + } + }, { "identity" : "async-http-client", "kind" : "remoteSourceControl", @@ -45,15 +54,6 @@ "version" : "1.0.2" } }, - { - "identity" : "swift-case-paths", - "kind" : "remoteSourceControl", - "location" : "https://github.com/pointfreeco/swift-case-paths", - "state" : { - "revision" : "ce9c0d897db8a840c39de64caaa9b60119cf4be8", - "version" : "0.8.1" - } - }, { "identity" : "swift-log", "kind" : "remoteSourceControl", @@ -117,15 +117,6 @@ "version" : "1.0.2" } }, - { - "identity" : "swift-parsing", - "kind" : "remoteSourceControl", - "location" : "https://github.com/pointfreeco/swift-parsing", - "state" : { - "revision" : "28d32e9ace1c4c43f5e5a177be837a202494c2d5", - "version" : "0.9.2" - } - }, { "identity" : "swiftdate", "kind" : "remoteSourceControl", @@ -134,15 +125,6 @@ "revision" : "6190d0cefff3013e77ed567e6b074f324e5c5bf5", "version" : "6.3.1" } - }, - { - "identity" : "xctest-dynamic-overlay", - "kind" : "remoteSourceControl", - "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", - "state" : { - "revision" : "50a70a9d3583fe228ce672e8923010c8df2deddd", - "version" : "0.2.1" - } } ], "version" : 2 diff --git a/Package.swift b/Package.swift index e719352f..36cfb516 100644 --- a/Package.swift +++ b/Package.swift @@ -12,10 +12,10 @@ let package = Package( dependencies: [ .package(url: "https://github.com/apple/swift-argument-parser", from: "1.1.2"), .package(url: "https://github.com/mhdhejazi/Dynamic", branch: "master"), - .package(url: "https://github.com/pointfreeco/swift-parsing", from: "0.9.2"), .package(url: "https://github.com/swift-server/async-http-client", from: "1.11.4"), .package(url: "https://github.com/apple/swift-algorithms", from: "1.0.0"), - .package(url: "https://github.com/malcommac/SwiftDate", from: "6.3.1") + .package(url: "https://github.com/malcommac/SwiftDate", from: "6.3.1"), + .package(url: "https://github.com/antlr/antlr4", revision: "4.10.1") ], targets: [ .executableTarget(name: "tart", dependencies: [ @@ -23,10 +23,9 @@ let package = Package( .product(name: "ArgumentParser", package: "swift-argument-parser"), .product(name: "AsyncHTTPClient", package: "async-http-client"), .product(name: "Dynamic", package: "Dynamic"), - .product(name: "Parsing", package: "swift-parsing"), .product(name: "SwiftDate", package: "SwiftDate"), + .product(name: "Antlr4", package: "Antlr4"), ]), .testTarget(name: "TartTests", dependencies: ["tart"]) ] ) - diff --git a/Sources/tart/OCI/Reference/Generated/Reference.interp b/Sources/tart/OCI/Reference/Generated/Reference.interp new file mode 100644 index 00000000..bdbefb08 --- /dev/null +++ b/Sources/tart/OCI/Reference/Generated/Reference.interp @@ -0,0 +1,36 @@ +token literal names: +null +':' +'/' +'.' +'@' +'-' +'_' +null +null + +token symbolic names: +null +null +null +null +null +null +null +DIGIT +LETTER + +rule names: +root +host +port +namespace +namespace_component +reference +tag +separator +name + + +atn: +[4, 1, 8, 85, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 1, 0, 1, 0, 1, 0, 3, 0, 22, 8, 0, 1, 0, 1, 0, 1, 0, 3, 0, 27, 8, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 5, 1, 34, 8, 1, 10, 1, 12, 1, 37, 9, 1, 1, 2, 4, 2, 40, 8, 2, 11, 2, 12, 2, 41, 1, 3, 1, 3, 1, 3, 5, 3, 47, 8, 3, 10, 3, 12, 3, 50, 9, 3, 1, 4, 1, 4, 3, 4, 54, 8, 4, 4, 4, 56, 8, 4, 11, 4, 12, 4, 57, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 67, 8, 5, 1, 6, 1, 6, 1, 6, 1, 6, 5, 6, 73, 8, 6, 10, 6, 12, 6, 76, 9, 6, 1, 7, 1, 7, 1, 8, 4, 8, 81, 8, 8, 11, 8, 12, 8, 82, 1, 8, 0, 0, 9, 0, 2, 4, 6, 8, 10, 12, 14, 16, 0, 2, 2, 0, 3, 3, 5, 6, 1, 0, 7, 8, 85, 0, 18, 1, 0, 0, 0, 2, 30, 1, 0, 0, 0, 4, 39, 1, 0, 0, 0, 6, 43, 1, 0, 0, 0, 8, 55, 1, 0, 0, 0, 10, 66, 1, 0, 0, 0, 12, 68, 1, 0, 0, 0, 14, 77, 1, 0, 0, 0, 16, 80, 1, 0, 0, 0, 18, 21, 3, 2, 1, 0, 19, 20, 5, 1, 0, 0, 20, 22, 3, 4, 2, 0, 21, 19, 1, 0, 0, 0, 21, 22, 1, 0, 0, 0, 22, 23, 1, 0, 0, 0, 23, 24, 5, 2, 0, 0, 24, 26, 3, 6, 3, 0, 25, 27, 3, 10, 5, 0, 26, 25, 1, 0, 0, 0, 26, 27, 1, 0, 0, 0, 27, 28, 1, 0, 0, 0, 28, 29, 5, 0, 0, 1, 29, 1, 1, 0, 0, 0, 30, 35, 3, 16, 8, 0, 31, 32, 5, 3, 0, 0, 32, 34, 3, 16, 8, 0, 33, 31, 1, 0, 0, 0, 34, 37, 1, 0, 0, 0, 35, 33, 1, 0, 0, 0, 35, 36, 1, 0, 0, 0, 36, 3, 1, 0, 0, 0, 37, 35, 1, 0, 0, 0, 38, 40, 5, 7, 0, 0, 39, 38, 1, 0, 0, 0, 40, 41, 1, 0, 0, 0, 41, 39, 1, 0, 0, 0, 41, 42, 1, 0, 0, 0, 42, 5, 1, 0, 0, 0, 43, 48, 3, 8, 4, 0, 44, 45, 5, 2, 0, 0, 45, 47, 3, 8, 4, 0, 46, 44, 1, 0, 0, 0, 47, 50, 1, 0, 0, 0, 48, 46, 1, 0, 0, 0, 48, 49, 1, 0, 0, 0, 49, 7, 1, 0, 0, 0, 50, 48, 1, 0, 0, 0, 51, 53, 3, 16, 8, 0, 52, 54, 3, 14, 7, 0, 53, 52, 1, 0, 0, 0, 53, 54, 1, 0, 0, 0, 54, 56, 1, 0, 0, 0, 55, 51, 1, 0, 0, 0, 56, 57, 1, 0, 0, 0, 57, 55, 1, 0, 0, 0, 57, 58, 1, 0, 0, 0, 58, 9, 1, 0, 0, 0, 59, 60, 5, 1, 0, 0, 60, 67, 3, 12, 6, 0, 61, 62, 5, 4, 0, 0, 62, 63, 3, 16, 8, 0, 63, 64, 5, 1, 0, 0, 64, 65, 3, 16, 8, 0, 65, 67, 1, 0, 0, 0, 66, 59, 1, 0, 0, 0, 66, 61, 1, 0, 0, 0, 67, 11, 1, 0, 0, 0, 68, 74, 3, 16, 8, 0, 69, 70, 3, 14, 7, 0, 70, 71, 3, 16, 8, 0, 71, 73, 1, 0, 0, 0, 72, 69, 1, 0, 0, 0, 73, 76, 1, 0, 0, 0, 74, 72, 1, 0, 0, 0, 74, 75, 1, 0, 0, 0, 75, 13, 1, 0, 0, 0, 76, 74, 1, 0, 0, 0, 77, 78, 7, 0, 0, 0, 78, 15, 1, 0, 0, 0, 79, 81, 7, 1, 0, 0, 80, 79, 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 82, 80, 1, 0, 0, 0, 82, 83, 1, 0, 0, 0, 83, 17, 1, 0, 0, 0, 10, 21, 26, 35, 41, 48, 53, 57, 66, 74, 82] \ No newline at end of file diff --git a/Sources/tart/OCI/Reference/Generated/Reference.tokens b/Sources/tart/OCI/Reference/Generated/Reference.tokens new file mode 100644 index 00000000..ec279c97 --- /dev/null +++ b/Sources/tart/OCI/Reference/Generated/Reference.tokens @@ -0,0 +1,14 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +DIGIT=7 +LETTER=8 +':'=1 +'/'=2 +'.'=3 +'@'=4 +'-'=5 +'_'=6 diff --git a/Sources/tart/OCI/Reference/Generated/ReferenceBaseListener.swift b/Sources/tart/OCI/Reference/Generated/ReferenceBaseListener.swift new file mode 100644 index 00000000..4912e8d4 --- /dev/null +++ b/Sources/tart/OCI/Reference/Generated/ReferenceBaseListener.swift @@ -0,0 +1,154 @@ +// Generated from Reference.g4 by ANTLR 4.10.1 + +import Antlr4 + + +/** + * This class provides an empty implementation of {@link ReferenceListener}, + * which can be extended to create a listener which only needs to handle a subset + * of the available methods. + */ +open class ReferenceBaseListener: ReferenceListener { + public init() { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func enterRoot(_ ctx: ReferenceParser.RootContext) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func exitRoot(_ ctx: ReferenceParser.RootContext) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func enterHost(_ ctx: ReferenceParser.HostContext) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func exitHost(_ ctx: ReferenceParser.HostContext) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func enterPort(_ ctx: ReferenceParser.PortContext) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func exitPort(_ ctx: ReferenceParser.PortContext) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func enterNamespace(_ ctx: ReferenceParser.NamespaceContext) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func exitNamespace(_ ctx: ReferenceParser.NamespaceContext) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func enterNamespace_component(_ ctx: ReferenceParser.Namespace_componentContext) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func exitNamespace_component(_ ctx: ReferenceParser.Namespace_componentContext) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func enterReference(_ ctx: ReferenceParser.ReferenceContext) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func exitReference(_ ctx: ReferenceParser.ReferenceContext) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func enterTag(_ ctx: ReferenceParser.TagContext) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func exitTag(_ ctx: ReferenceParser.TagContext) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func enterSeparator(_ ctx: ReferenceParser.SeparatorContext) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func exitSeparator(_ ctx: ReferenceParser.SeparatorContext) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func enterName(_ ctx: ReferenceParser.NameContext) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func exitName(_ ctx: ReferenceParser.NameContext) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func enterEveryRule(_ ctx: ParserRuleContext) throws { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func exitEveryRule(_ ctx: ParserRuleContext) throws { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func visitTerminal(_ node: TerminalNode) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + open func visitErrorNode(_ node: ErrorNode) { } +} \ No newline at end of file diff --git a/Sources/tart/OCI/Reference/Generated/ReferenceLexer.interp b/Sources/tart/OCI/Reference/Generated/ReferenceLexer.interp new file mode 100644 index 00000000..2ad7109c --- /dev/null +++ b/Sources/tart/OCI/Reference/Generated/ReferenceLexer.interp @@ -0,0 +1,41 @@ +token literal names: +null +':' +'/' +'.' +'@' +'-' +'_' +null +null + +token symbolic names: +null +null +null +null +null +null +null +DIGIT +LETTER + +rule names: +T__0 +T__1 +T__2 +T__3 +T__4 +T__5 +DIGIT +LETTER + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[4, 0, 8, 33, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 0, 0, 8, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 1, 0, 2, 1, 0, 48, 57, 2, 0, 65, 90, 97, 122, 32, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 1, 17, 1, 0, 0, 0, 3, 19, 1, 0, 0, 0, 5, 21, 1, 0, 0, 0, 7, 23, 1, 0, 0, 0, 9, 25, 1, 0, 0, 0, 11, 27, 1, 0, 0, 0, 13, 29, 1, 0, 0, 0, 15, 31, 1, 0, 0, 0, 17, 18, 5, 58, 0, 0, 18, 2, 1, 0, 0, 0, 19, 20, 5, 47, 0, 0, 20, 4, 1, 0, 0, 0, 21, 22, 5, 46, 0, 0, 22, 6, 1, 0, 0, 0, 23, 24, 5, 64, 0, 0, 24, 8, 1, 0, 0, 0, 25, 26, 5, 45, 0, 0, 26, 10, 1, 0, 0, 0, 27, 28, 5, 95, 0, 0, 28, 12, 1, 0, 0, 0, 29, 30, 7, 0, 0, 0, 30, 14, 1, 0, 0, 0, 31, 32, 7, 1, 0, 0, 32, 16, 1, 0, 0, 0, 1, 0, 0] \ No newline at end of file diff --git a/Sources/tart/OCI/Reference/Generated/ReferenceLexer.swift b/Sources/tart/OCI/Reference/Generated/ReferenceLexer.swift new file mode 100644 index 00000000..fee846b3 --- /dev/null +++ b/Sources/tart/OCI/Reference/Generated/ReferenceLexer.swift @@ -0,0 +1,90 @@ +// Generated from Reference.g4 by ANTLR 4.10.1 +import Antlr4 + +open class ReferenceLexer: Lexer { + + internal static var _decisionToDFA: [DFA] = { + var decisionToDFA = [DFA]() + let length = ReferenceLexer._ATN.getNumberOfDecisions() + for i in 0.. Vocabulary { + return ReferenceLexer.VOCABULARY + } + + public + required init(_ input: CharStream) { + RuntimeMetaData.checkVersion("4.10.1", RuntimeMetaData.VERSION) + super.init(input) + _interp = LexerATNSimulator(self, ReferenceLexer._ATN, ReferenceLexer._decisionToDFA, ReferenceLexer._sharedContextCache) + } + + override open + func getGrammarFileName() -> String { return "Reference.g4" } + + override open + func getRuleNames() -> [String] { return ReferenceLexer.ruleNames } + + override open + func getSerializedATN() -> [Int] { return ReferenceLexer._serializedATN } + + override open + func getChannelNames() -> [String] { return ReferenceLexer.channelNames } + + override open + func getModeNames() -> [String] { return ReferenceLexer.modeNames } + + override open + func getATN() -> ATN { return ReferenceLexer._ATN } + + static let _serializedATN:[Int] = [ + 4,0,8,33,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,6, + 2,7,7,7,1,0,1,0,1,1,1,1,1,2,1,2,1,3,1,3,1,4,1,4,1,5,1,5,1,6,1,6,1,7,1, + 7,0,0,8,1,1,3,2,5,3,7,4,9,5,11,6,13,7,15,8,1,0,2,1,0,48,57,2,0,65,90,97, + 122,32,0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11, + 1,0,0,0,0,13,1,0,0,0,0,15,1,0,0,0,1,17,1,0,0,0,3,19,1,0,0,0,5,21,1,0,0, + 0,7,23,1,0,0,0,9,25,1,0,0,0,11,27,1,0,0,0,13,29,1,0,0,0,15,31,1,0,0,0, + 17,18,5,58,0,0,18,2,1,0,0,0,19,20,5,47,0,0,20,4,1,0,0,0,21,22,5,46,0,0, + 22,6,1,0,0,0,23,24,5,64,0,0,24,8,1,0,0,0,25,26,5,45,0,0,26,10,1,0,0,0, + 27,28,5,95,0,0,28,12,1,0,0,0,29,30,7,0,0,0,30,14,1,0,0,0,31,32,7,1,0,0, + 32,16,1,0,0,0,1,0,0 + ] + + public + static let _ATN: ATN = try! ATNDeserializer().deserialize(_serializedATN) +} \ No newline at end of file diff --git a/Sources/tart/OCI/Reference/Generated/ReferenceLexer.tokens b/Sources/tart/OCI/Reference/Generated/ReferenceLexer.tokens new file mode 100644 index 00000000..ec279c97 --- /dev/null +++ b/Sources/tart/OCI/Reference/Generated/ReferenceLexer.tokens @@ -0,0 +1,14 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +DIGIT=7 +LETTER=8 +':'=1 +'/'=2 +'.'=3 +'@'=4 +'-'=5 +'_'=6 diff --git a/Sources/tart/OCI/Reference/Generated/ReferenceListener.swift b/Sources/tart/OCI/Reference/Generated/ReferenceListener.swift new file mode 100644 index 00000000..2c05520a --- /dev/null +++ b/Sources/tart/OCI/Reference/Generated/ReferenceListener.swift @@ -0,0 +1,117 @@ +// Generated from Reference.g4 by ANTLR 4.10.1 +import Antlr4 + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link ReferenceParser}. + */ +public protocol ReferenceListener: ParseTreeListener { + /** + * Enter a parse tree produced by {@link ReferenceParser#root}. + - Parameters: + - ctx: the parse tree + */ + func enterRoot(_ ctx: ReferenceParser.RootContext) + /** + * Exit a parse tree produced by {@link ReferenceParser#root}. + - Parameters: + - ctx: the parse tree + */ + func exitRoot(_ ctx: ReferenceParser.RootContext) + /** + * Enter a parse tree produced by {@link ReferenceParser#host}. + - Parameters: + - ctx: the parse tree + */ + func enterHost(_ ctx: ReferenceParser.HostContext) + /** + * Exit a parse tree produced by {@link ReferenceParser#host}. + - Parameters: + - ctx: the parse tree + */ + func exitHost(_ ctx: ReferenceParser.HostContext) + /** + * Enter a parse tree produced by {@link ReferenceParser#port}. + - Parameters: + - ctx: the parse tree + */ + func enterPort(_ ctx: ReferenceParser.PortContext) + /** + * Exit a parse tree produced by {@link ReferenceParser#port}. + - Parameters: + - ctx: the parse tree + */ + func exitPort(_ ctx: ReferenceParser.PortContext) + /** + * Enter a parse tree produced by {@link ReferenceParser#namespace}. + - Parameters: + - ctx: the parse tree + */ + func enterNamespace(_ ctx: ReferenceParser.NamespaceContext) + /** + * Exit a parse tree produced by {@link ReferenceParser#namespace}. + - Parameters: + - ctx: the parse tree + */ + func exitNamespace(_ ctx: ReferenceParser.NamespaceContext) + /** + * Enter a parse tree produced by {@link ReferenceParser#namespace_component}. + - Parameters: + - ctx: the parse tree + */ + func enterNamespace_component(_ ctx: ReferenceParser.Namespace_componentContext) + /** + * Exit a parse tree produced by {@link ReferenceParser#namespace_component}. + - Parameters: + - ctx: the parse tree + */ + func exitNamespace_component(_ ctx: ReferenceParser.Namespace_componentContext) + /** + * Enter a parse tree produced by {@link ReferenceParser#reference}. + - Parameters: + - ctx: the parse tree + */ + func enterReference(_ ctx: ReferenceParser.ReferenceContext) + /** + * Exit a parse tree produced by {@link ReferenceParser#reference}. + - Parameters: + - ctx: the parse tree + */ + func exitReference(_ ctx: ReferenceParser.ReferenceContext) + /** + * Enter a parse tree produced by {@link ReferenceParser#tag}. + - Parameters: + - ctx: the parse tree + */ + func enterTag(_ ctx: ReferenceParser.TagContext) + /** + * Exit a parse tree produced by {@link ReferenceParser#tag}. + - Parameters: + - ctx: the parse tree + */ + func exitTag(_ ctx: ReferenceParser.TagContext) + /** + * Enter a parse tree produced by {@link ReferenceParser#separator}. + - Parameters: + - ctx: the parse tree + */ + func enterSeparator(_ ctx: ReferenceParser.SeparatorContext) + /** + * Exit a parse tree produced by {@link ReferenceParser#separator}. + - Parameters: + - ctx: the parse tree + */ + func exitSeparator(_ ctx: ReferenceParser.SeparatorContext) + /** + * Enter a parse tree produced by {@link ReferenceParser#name}. + - Parameters: + - ctx: the parse tree + */ + func enterName(_ ctx: ReferenceParser.NameContext) + /** + * Exit a parse tree produced by {@link ReferenceParser#name}. + - Parameters: + - ctx: the parse tree + */ + func exitName(_ ctx: ReferenceParser.NameContext) +} \ No newline at end of file diff --git a/Sources/tart/OCI/Reference/Generated/ReferenceParser.swift b/Sources/tart/OCI/Reference/Generated/ReferenceParser.swift new file mode 100644 index 00000000..af3a4c54 --- /dev/null +++ b/Sources/tart/OCI/Reference/Generated/ReferenceParser.swift @@ -0,0 +1,781 @@ +// Generated from Reference.g4 by ANTLR 4.10.1 +import Antlr4 + +open class ReferenceParser: Parser { + + internal static var _decisionToDFA: [DFA] = { + var decisionToDFA = [DFA]() + let length = ReferenceParser._ATN.getNumberOfDecisions() + for i in 0.. String { return "Reference.g4" } + + override open + func getRuleNames() -> [String] { return ReferenceParser.ruleNames } + + override open + func getSerializedATN() -> [Int] { return ReferenceParser._serializedATN } + + override open + func getATN() -> ATN { return ReferenceParser._ATN } + + + override open + func getVocabulary() -> Vocabulary { + return ReferenceParser.VOCABULARY + } + + override public + init(_ input:TokenStream) throws { + RuntimeMetaData.checkVersion("4.10.1", RuntimeMetaData.VERSION) + try super.init(input) + _interp = ParserATNSimulator(self,ReferenceParser._ATN,ReferenceParser._decisionToDFA, ReferenceParser._sharedContextCache) + } + + + public class RootContext: ParserRuleContext { + open + func host() -> HostContext? { + return getRuleContext(HostContext.self, 0) + } + open + func namespace() -> NamespaceContext? { + return getRuleContext(NamespaceContext.self, 0) + } + open + func EOF() -> TerminalNode? { + return getToken(ReferenceParser.Tokens.EOF.rawValue, 0) + } + open + func port() -> PortContext? { + return getRuleContext(PortContext.self, 0) + } + open + func reference() -> ReferenceContext? { + return getRuleContext(ReferenceContext.self, 0) + } + override open + func getRuleIndex() -> Int { + return ReferenceParser.RULE_root + } + override open + func enterRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.enterRoot(self) + } + } + override open + func exitRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.exitRoot(self) + } + } + } + @discardableResult + open func root() throws -> RootContext { + var _localctx: RootContext + _localctx = RootContext(_ctx, getState()) + try enterRule(_localctx, 0, ReferenceParser.RULE_root) + var _la: Int = 0 + defer { + try! exitRule() + } + do { + try enterOuterAlt(_localctx, 1) + setState(18) + try host() + setState(21) + try _errHandler.sync(self) + _la = try _input.LA(1) + if (//closure + { () -> Bool in + let testSet: Bool = _la == ReferenceParser.Tokens.T__0.rawValue + return testSet + }()) { + setState(19) + try match(ReferenceParser.Tokens.T__0.rawValue) + setState(20) + try port() + + } + + setState(23) + try match(ReferenceParser.Tokens.T__1.rawValue) + setState(24) + try namespace() + setState(26) + try _errHandler.sync(self) + _la = try _input.LA(1) + if (//closure + { () -> Bool in + let testSet: Bool = _la == ReferenceParser.Tokens.T__0.rawValue || _la == ReferenceParser.Tokens.T__3.rawValue + return testSet + }()) { + setState(25) + try reference() + + } + + setState(28) + try match(ReferenceParser.Tokens.EOF.rawValue) + + } + catch ANTLRException.recognition(let re) { + _localctx.exception = re + _errHandler.reportError(self, re) + try _errHandler.recover(self, re) + } + + return _localctx + } + + public class HostContext: ParserRuleContext { + open + func name() -> [NameContext] { + return getRuleContexts(NameContext.self) + } + open + func name(_ i: Int) -> NameContext? { + return getRuleContext(NameContext.self, i) + } + override open + func getRuleIndex() -> Int { + return ReferenceParser.RULE_host + } + override open + func enterRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.enterHost(self) + } + } + override open + func exitRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.exitHost(self) + } + } + } + @discardableResult + open func host() throws -> HostContext { + var _localctx: HostContext + _localctx = HostContext(_ctx, getState()) + try enterRule(_localctx, 2, ReferenceParser.RULE_host) + var _la: Int = 0 + defer { + try! exitRule() + } + do { + try enterOuterAlt(_localctx, 1) + setState(30) + try name() + setState(35) + try _errHandler.sync(self) + _la = try _input.LA(1) + while (//closure + { () -> Bool in + let testSet: Bool = _la == ReferenceParser.Tokens.T__2.rawValue + return testSet + }()) { + setState(31) + try match(ReferenceParser.Tokens.T__2.rawValue) + setState(32) + try name() + + + setState(37) + try _errHandler.sync(self) + _la = try _input.LA(1) + } + + } + catch ANTLRException.recognition(let re) { + _localctx.exception = re + _errHandler.reportError(self, re) + try _errHandler.recover(self, re) + } + + return _localctx + } + + public class PortContext: ParserRuleContext { + open + func DIGIT() -> [TerminalNode] { + return getTokens(ReferenceParser.Tokens.DIGIT.rawValue) + } + open + func DIGIT(_ i:Int) -> TerminalNode? { + return getToken(ReferenceParser.Tokens.DIGIT.rawValue, i) + } + override open + func getRuleIndex() -> Int { + return ReferenceParser.RULE_port + } + override open + func enterRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.enterPort(self) + } + } + override open + func exitRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.exitPort(self) + } + } + } + @discardableResult + open func port() throws -> PortContext { + var _localctx: PortContext + _localctx = PortContext(_ctx, getState()) + try enterRule(_localctx, 4, ReferenceParser.RULE_port) + var _la: Int = 0 + defer { + try! exitRule() + } + do { + try enterOuterAlt(_localctx, 1) + setState(39) + try _errHandler.sync(self) + _la = try _input.LA(1) + repeat { + setState(38) + try match(ReferenceParser.Tokens.DIGIT.rawValue) + + + setState(41); + try _errHandler.sync(self) + _la = try _input.LA(1) + } while (//closure + { () -> Bool in + let testSet: Bool = _la == ReferenceParser.Tokens.DIGIT.rawValue + return testSet + }()) + + } + catch ANTLRException.recognition(let re) { + _localctx.exception = re + _errHandler.reportError(self, re) + try _errHandler.recover(self, re) + } + + return _localctx + } + + public class NamespaceContext: ParserRuleContext { + open + func namespace_component() -> [Namespace_componentContext] { + return getRuleContexts(Namespace_componentContext.self) + } + open + func namespace_component(_ i: Int) -> Namespace_componentContext? { + return getRuleContext(Namespace_componentContext.self, i) + } + override open + func getRuleIndex() -> Int { + return ReferenceParser.RULE_namespace + } + override open + func enterRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.enterNamespace(self) + } + } + override open + func exitRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.exitNamespace(self) + } + } + } + @discardableResult + open func namespace() throws -> NamespaceContext { + var _localctx: NamespaceContext + _localctx = NamespaceContext(_ctx, getState()) + try enterRule(_localctx, 6, ReferenceParser.RULE_namespace) + var _la: Int = 0 + defer { + try! exitRule() + } + do { + try enterOuterAlt(_localctx, 1) + setState(43) + try namespace_component() + setState(48) + try _errHandler.sync(self) + _la = try _input.LA(1) + while (//closure + { () -> Bool in + let testSet: Bool = _la == ReferenceParser.Tokens.T__1.rawValue + return testSet + }()) { + setState(44) + try match(ReferenceParser.Tokens.T__1.rawValue) + setState(45) + try namespace_component() + + + setState(50) + try _errHandler.sync(self) + _la = try _input.LA(1) + } + + } + catch ANTLRException.recognition(let re) { + _localctx.exception = re + _errHandler.reportError(self, re) + try _errHandler.recover(self, re) + } + + return _localctx + } + + public class Namespace_componentContext: ParserRuleContext { + open + func name() -> [NameContext] { + return getRuleContexts(NameContext.self) + } + open + func name(_ i: Int) -> NameContext? { + return getRuleContext(NameContext.self, i) + } + open + func separator() -> [SeparatorContext] { + return getRuleContexts(SeparatorContext.self) + } + open + func separator(_ i: Int) -> SeparatorContext? { + return getRuleContext(SeparatorContext.self, i) + } + override open + func getRuleIndex() -> Int { + return ReferenceParser.RULE_namespace_component + } + override open + func enterRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.enterNamespace_component(self) + } + } + override open + func exitRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.exitNamespace_component(self) + } + } + } + @discardableResult + open func namespace_component() throws -> Namespace_componentContext { + var _localctx: Namespace_componentContext + _localctx = Namespace_componentContext(_ctx, getState()) + try enterRule(_localctx, 8, ReferenceParser.RULE_namespace_component) + var _la: Int = 0 + defer { + try! exitRule() + } + do { + try enterOuterAlt(_localctx, 1) + setState(55) + try _errHandler.sync(self) + _la = try _input.LA(1) + repeat { + setState(51) + try name() + setState(53) + try _errHandler.sync(self) + _la = try _input.LA(1) + if (//closure + { () -> Bool in + let testSet: Bool = { () -> Bool in + let testArray: [Int] = [_la, ReferenceParser.Tokens.T__2.rawValue,ReferenceParser.Tokens.T__4.rawValue,ReferenceParser.Tokens.T__5.rawValue] + return Utils.testBitLeftShiftArray(testArray, 0) + }() + return testSet + }()) { + setState(52) + try separator() + + } + + + + setState(57); + try _errHandler.sync(self) + _la = try _input.LA(1) + } while (//closure + { () -> Bool in + let testSet: Bool = _la == ReferenceParser.Tokens.DIGIT.rawValue || _la == ReferenceParser.Tokens.LETTER.rawValue + return testSet + }()) + + } + catch ANTLRException.recognition(let re) { + _localctx.exception = re + _errHandler.reportError(self, re) + try _errHandler.recover(self, re) + } + + return _localctx + } + + public class ReferenceContext: ParserRuleContext { + open + func tag() -> TagContext? { + return getRuleContext(TagContext.self, 0) + } + open + func name() -> [NameContext] { + return getRuleContexts(NameContext.self) + } + open + func name(_ i: Int) -> NameContext? { + return getRuleContext(NameContext.self, i) + } + override open + func getRuleIndex() -> Int { + return ReferenceParser.RULE_reference + } + override open + func enterRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.enterReference(self) + } + } + override open + func exitRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.exitReference(self) + } + } + } + @discardableResult + open func reference() throws -> ReferenceContext { + var _localctx: ReferenceContext + _localctx = ReferenceContext(_ctx, getState()) + try enterRule(_localctx, 10, ReferenceParser.RULE_reference) + defer { + try! exitRule() + } + do { + setState(66) + try _errHandler.sync(self) + switch (ReferenceParser.Tokens(rawValue: try _input.LA(1))!) { + case .T__0: + try enterOuterAlt(_localctx, 1) + setState(59) + try match(ReferenceParser.Tokens.T__0.rawValue) + setState(60) + try tag() + + + break + + case .T__3: + try enterOuterAlt(_localctx, 2) + setState(61) + try match(ReferenceParser.Tokens.T__3.rawValue) + setState(62) + try name() + setState(63) + try match(ReferenceParser.Tokens.T__0.rawValue) + setState(64) + try name() + + + break + default: + throw ANTLRException.recognition(e: NoViableAltException(self)) + } + } + catch ANTLRException.recognition(let re) { + _localctx.exception = re + _errHandler.reportError(self, re) + try _errHandler.recover(self, re) + } + + return _localctx + } + + public class TagContext: ParserRuleContext { + open + func name() -> [NameContext] { + return getRuleContexts(NameContext.self) + } + open + func name(_ i: Int) -> NameContext? { + return getRuleContext(NameContext.self, i) + } + open + func separator() -> [SeparatorContext] { + return getRuleContexts(SeparatorContext.self) + } + open + func separator(_ i: Int) -> SeparatorContext? { + return getRuleContext(SeparatorContext.self, i) + } + override open + func getRuleIndex() -> Int { + return ReferenceParser.RULE_tag + } + override open + func enterRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.enterTag(self) + } + } + override open + func exitRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.exitTag(self) + } + } + } + @discardableResult + open func tag() throws -> TagContext { + var _localctx: TagContext + _localctx = TagContext(_ctx, getState()) + try enterRule(_localctx, 12, ReferenceParser.RULE_tag) + var _la: Int = 0 + defer { + try! exitRule() + } + do { + try enterOuterAlt(_localctx, 1) + setState(68) + try name() + setState(74) + try _errHandler.sync(self) + _la = try _input.LA(1) + while (//closure + { () -> Bool in + let testSet: Bool = { () -> Bool in + let testArray: [Int] = [_la, ReferenceParser.Tokens.T__2.rawValue,ReferenceParser.Tokens.T__4.rawValue,ReferenceParser.Tokens.T__5.rawValue] + return Utils.testBitLeftShiftArray(testArray, 0) + }() + return testSet + }()) { + setState(69) + try separator() + setState(70) + try name() + + + setState(76) + try _errHandler.sync(self) + _la = try _input.LA(1) + } + + } + catch ANTLRException.recognition(let re) { + _localctx.exception = re + _errHandler.reportError(self, re) + try _errHandler.recover(self, re) + } + + return _localctx + } + + public class SeparatorContext: ParserRuleContext { + override open + func getRuleIndex() -> Int { + return ReferenceParser.RULE_separator + } + override open + func enterRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.enterSeparator(self) + } + } + override open + func exitRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.exitSeparator(self) + } + } + } + @discardableResult + open func separator() throws -> SeparatorContext { + var _localctx: SeparatorContext + _localctx = SeparatorContext(_ctx, getState()) + try enterRule(_localctx, 14, ReferenceParser.RULE_separator) + var _la: Int = 0 + defer { + try! exitRule() + } + do { + try enterOuterAlt(_localctx, 1) + setState(77) + _la = try _input.LA(1) + if (!(//closure + { () -> Bool in + let testSet: Bool = { () -> Bool in + let testArray: [Int] = [_la, ReferenceParser.Tokens.T__2.rawValue,ReferenceParser.Tokens.T__4.rawValue,ReferenceParser.Tokens.T__5.rawValue] + return Utils.testBitLeftShiftArray(testArray, 0) + }() + return testSet + }())) { + try _errHandler.recoverInline(self) + } + else { + _errHandler.reportMatch(self) + try consume() + } + + } + catch ANTLRException.recognition(let re) { + _localctx.exception = re + _errHandler.reportError(self, re) + try _errHandler.recover(self, re) + } + + return _localctx + } + + public class NameContext: ParserRuleContext { + open + func LETTER() -> [TerminalNode] { + return getTokens(ReferenceParser.Tokens.LETTER.rawValue) + } + open + func LETTER(_ i:Int) -> TerminalNode? { + return getToken(ReferenceParser.Tokens.LETTER.rawValue, i) + } + open + func DIGIT() -> [TerminalNode] { + return getTokens(ReferenceParser.Tokens.DIGIT.rawValue) + } + open + func DIGIT(_ i:Int) -> TerminalNode? { + return getToken(ReferenceParser.Tokens.DIGIT.rawValue, i) + } + override open + func getRuleIndex() -> Int { + return ReferenceParser.RULE_name + } + override open + func enterRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.enterName(self) + } + } + override open + func exitRule(_ listener: ParseTreeListener) { + if let listener = listener as? ReferenceListener { + listener.exitName(self) + } + } + } + @discardableResult + open func name() throws -> NameContext { + var _localctx: NameContext + _localctx = NameContext(_ctx, getState()) + try enterRule(_localctx, 16, ReferenceParser.RULE_name) + var _la: Int = 0 + defer { + try! exitRule() + } + do { + var _alt:Int + try enterOuterAlt(_localctx, 1) + setState(80); + try _errHandler.sync(self) + _alt = 1; + repeat { + switch (_alt) { + case 1: + setState(79) + _la = try _input.LA(1) + if (!(//closure + { () -> Bool in + let testSet: Bool = _la == ReferenceParser.Tokens.DIGIT.rawValue || _la == ReferenceParser.Tokens.LETTER.rawValue + return testSet + }())) { + try _errHandler.recoverInline(self) + } + else { + _errHandler.reportMatch(self) + try consume() + } + + + break + default: + throw ANTLRException.recognition(e: NoViableAltException(self)) + } + setState(82); + try _errHandler.sync(self) + _alt = try getInterpreter().adaptivePredict(_input,9,_ctx) + } while (_alt != 2 && _alt != ATN.INVALID_ALT_NUMBER) + + } + catch ANTLRException.recognition(let re) { + _localctx.exception = re + _errHandler.reportError(self, re) + try _errHandler.recover(self, re) + } + + return _localctx + } + + static let _serializedATN:[Int] = [ + 4,1,8,85,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,6,2,7,7, + 7,2,8,7,8,1,0,1,0,1,0,3,0,22,8,0,1,0,1,0,1,0,3,0,27,8,0,1,0,1,0,1,1,1, + 1,1,1,5,1,34,8,1,10,1,12,1,37,9,1,1,2,4,2,40,8,2,11,2,12,2,41,1,3,1,3, + 1,3,5,3,47,8,3,10,3,12,3,50,9,3,1,4,1,4,3,4,54,8,4,4,4,56,8,4,11,4,12, + 4,57,1,5,1,5,1,5,1,5,1,5,1,5,1,5,3,5,67,8,5,1,6,1,6,1,6,1,6,5,6,73,8,6, + 10,6,12,6,76,9,6,1,7,1,7,1,8,4,8,81,8,8,11,8,12,8,82,1,8,0,0,9,0,2,4,6, + 8,10,12,14,16,0,2,2,0,3,3,5,6,1,0,7,8,85,0,18,1,0,0,0,2,30,1,0,0,0,4,39, + 1,0,0,0,6,43,1,0,0,0,8,55,1,0,0,0,10,66,1,0,0,0,12,68,1,0,0,0,14,77,1, + 0,0,0,16,80,1,0,0,0,18,21,3,2,1,0,19,20,5,1,0,0,20,22,3,4,2,0,21,19,1, + 0,0,0,21,22,1,0,0,0,22,23,1,0,0,0,23,24,5,2,0,0,24,26,3,6,3,0,25,27,3, + 10,5,0,26,25,1,0,0,0,26,27,1,0,0,0,27,28,1,0,0,0,28,29,5,0,0,1,29,1,1, + 0,0,0,30,35,3,16,8,0,31,32,5,3,0,0,32,34,3,16,8,0,33,31,1,0,0,0,34,37, + 1,0,0,0,35,33,1,0,0,0,35,36,1,0,0,0,36,3,1,0,0,0,37,35,1,0,0,0,38,40,5, + 7,0,0,39,38,1,0,0,0,40,41,1,0,0,0,41,39,1,0,0,0,41,42,1,0,0,0,42,5,1,0, + 0,0,43,48,3,8,4,0,44,45,5,2,0,0,45,47,3,8,4,0,46,44,1,0,0,0,47,50,1,0, + 0,0,48,46,1,0,0,0,48,49,1,0,0,0,49,7,1,0,0,0,50,48,1,0,0,0,51,53,3,16, + 8,0,52,54,3,14,7,0,53,52,1,0,0,0,53,54,1,0,0,0,54,56,1,0,0,0,55,51,1,0, + 0,0,56,57,1,0,0,0,57,55,1,0,0,0,57,58,1,0,0,0,58,9,1,0,0,0,59,60,5,1,0, + 0,60,67,3,12,6,0,61,62,5,4,0,0,62,63,3,16,8,0,63,64,5,1,0,0,64,65,3,16, + 8,0,65,67,1,0,0,0,66,59,1,0,0,0,66,61,1,0,0,0,67,11,1,0,0,0,68,74,3,16, + 8,0,69,70,3,14,7,0,70,71,3,16,8,0,71,73,1,0,0,0,72,69,1,0,0,0,73,76,1, + 0,0,0,74,72,1,0,0,0,74,75,1,0,0,0,75,13,1,0,0,0,76,74,1,0,0,0,77,78,7, + 0,0,0,78,15,1,0,0,0,79,81,7,1,0,0,80,79,1,0,0,0,81,82,1,0,0,0,82,80,1, + 0,0,0,82,83,1,0,0,0,83,17,1,0,0,0,10,21,26,35,41,48,53,57,66,74,82 + ] + + public + static let _ATN = try! ATNDeserializer().deserialize(_serializedATN) +} \ No newline at end of file diff --git a/Sources/tart/OCI/Reference/Makefile b/Sources/tart/OCI/Reference/Makefile new file mode 100644 index 00000000..de4f5300 --- /dev/null +++ b/Sources/tart/OCI/Reference/Makefile @@ -0,0 +1,5 @@ +all: clean + antlr -o Generated -Dlanguage=Swift Reference.g4 + +clean: + rm -rf Generated diff --git a/Sources/tart/OCI/Reference/Reference.g4 b/Sources/tart/OCI/Reference/Reference.g4 new file mode 100644 index 00000000..2251a68b --- /dev/null +++ b/Sources/tart/OCI/Reference/Reference.g4 @@ -0,0 +1,13 @@ +grammar Reference; + +root: host (':' port)? '/' namespace reference? EOF; +host: name ('.' name)*; +port: DIGIT+; +namespace: namespace_component ('/' namespace_component)*; +namespace_component: (name separator?)+; +reference: (':' tag) | ('@' name ':' name); +tag: name (separator name)*; +separator: '.' | '-' | '_'; +name: (LETTER | DIGIT)+; +DIGIT: [0-9]; +LETTER: [A-Za-z]; diff --git a/Sources/tart/OCI/RemoteName.swift b/Sources/tart/OCI/RemoteName.swift index 5ac6740b..2ddb35ed 100644 --- a/Sources/tart/OCI/RemoteName.swift +++ b/Sources/tart/OCI/RemoteName.swift @@ -1,5 +1,5 @@ import Foundation -import Parsing +import Antlr4 struct Reference: Comparable, Hashable, CustomStringConvertible { enum ReferenceType: Comparable { @@ -46,6 +46,39 @@ struct Reference: Comparable, Hashable, CustomStringConvertible { } } +class ReferenceCollector: ReferenceBaseListener { + var host: String? = nil + var port: String? = nil + var namespace: String? = nil + var reference: String? = nil + + override func exitHost(_ ctx: ReferenceParser.HostContext) { + host = ctx.getText() + } + + override func exitPort(_ ctx: ReferenceParser.PortContext) { + port = ctx.getText() + } + + override func exitNamespace(_ ctx: ReferenceParser.NamespaceContext) { + namespace = ctx.getText() + } + + override func exitReference(_ ctx: ReferenceParser.ReferenceContext) { + reference = ctx.getText() + } +} + +class ErrorCollector: BaseErrorListener { + var error: String? = nil + + override func syntaxError(_ recognizer: Recognizer, _ offendingSymbol: AnyObject?, _ line: Int, _ charPositionInLine: Int, _ msg: String, _ e: AnyObject?) { + if error == nil { + error = "\(msg) (character \(charPositionInLine + 1))" + } + } +} + struct RemoteName: Comparable, Hashable, CustomStringConvertible { var host: String var namespace: String @@ -58,51 +91,40 @@ struct RemoteName: Comparable, Hashable, CustomStringConvertible { } init(_ name: String) throws { - let csNormal = [ - UInt8(ascii: "a")...UInt8(ascii: "z"), - UInt8(ascii: "A")...UInt8(ascii: "Z"), - UInt8(ascii: "0")...UInt8(ascii: "9"), - ].asCharacterSet().union(CharacterSet(charactersIn: "_-.")) - - let csHex = [ - UInt8(ascii: "a")...UInt8(ascii: "f"), - UInt8(ascii: "0")...UInt8(ascii: "9"), - ].asCharacterSet() - - let parser = Parse { - Consumed { - csNormal - Optionally { - ":" - Digits() - } - } - "/" - csNormal.union(CharacterSet(charactersIn: "/")) - Optionally { - OneOf { - Parse { - ":" - csNormal.map { - Reference(tag: String($0)) - } - } - Parse { - "@sha256:" - csHex.map { - Reference(digest: "sha256:" + String($0)) - } - } - } - } - End() + let errorCollector = ErrorCollector() + let inputStream = ANTLRInputStream(Array(name.unicodeScalars), name.count) + let lexer = ReferenceLexer(inputStream) + lexer.removeErrorListeners() + lexer.addErrorListener(errorCollector) + + let tokenStream = CommonTokenStream(lexer) + let parser = try ReferenceParser(tokenStream) + parser.removeErrorListeners() + parser.addErrorListener(errorCollector) + + let referenceCollector = ReferenceCollector() + try ParseTreeWalker().walk(referenceCollector, try parser.root()) + + if let error = errorCollector.error { + throw RuntimeError("failed to parse remote name: \(error)") } - let result = try parser.parse(name) - - host = String(result.0) - namespace = String(result.1) - reference = result.2 ?? Reference(tag: "latest") + host = referenceCollector.host! + if let port = referenceCollector.port { + host += ":" + port + } + namespace = referenceCollector.namespace! + if let reference = referenceCollector.reference { + if reference.starts(with: "@sha256:") { + self.reference = Reference(digest: String(reference.dropFirst(1))) + } else if reference.starts(with: ":") { + self.reference = Reference(tag: String(reference.dropFirst(1))) + } else { + throw RuntimeError("failed to parse remote name: unknown reference format") + } + } else { + self.reference = Reference(tag: "latest") + } } static func <(lhs: RemoteName, rhs: RemoteName) -> Bool { diff --git a/Tests/TartTests/RemoteNameTests.swift b/Tests/TartTests/RemoteNameTests.swift index a0cdc71a..577d97fd 100644 --- a/Tests/TartTests/RemoteNameTests.swift +++ b/Tests/TartTests/RemoteNameTests.swift @@ -44,4 +44,8 @@ final class RemoteNameTests: XCTestCase { // Port must be specified when ":" is used XCTAssertEqual(try? RemoteName("127.0.0.1:/a/b").host, nil) } + + func testNoPathTraversal() throws { + XCTAssertEqual(try? RemoteName("ghcr.io/a/../b/c:latest"), nil) + } }