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)
+ }
}