Skip to content

Instantly share code, notes, and snippets.

@apeiros
Created February 11, 2017 16:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apeiros/fdfd522ebce9666cd41a091000d4c6e1 to your computer and use it in GitHub Desktop.
Save apeiros/fdfd522ebce9666cd41a091000d4c6e1 to your computer and use it in GitHub Desktop.
class ArgumentSplitter {
static split(argumentString) {
return (new this(argumentString)).parse().arguments
}
constructor(argumentString) {
this.argumentString = argumentString
this.arguments = null
}
get length() {
return this.arguments === null ? null : this.arguments.length
}
parse() {
this.pos = 0
this.arguments = []
this.currentArgument = ""
this.readUntilArgument()
while(this.pos < this.argumentString.length) {
switch(this.argumentString[this.pos]) {
case '"': this.readDoubleQuotedSubstring(); break
case "'": this.readSingleQuotedSubstring(); break
case " ": case "\t": case "\r": case "\n":
this.terminateArgument(); break
default: this.readBareword()
}
}
this.terminateArgument()
this.currentArgument = null
this.pos = null
return this
}
terminateArgument() {
if (this.currentArgument.length > 0) {
this.arguments.push(this.currentArgument)
this.currentArgument = ""
}
this.pos++
}
readBareword() {
var terminated = false
while(!terminated && this.pos < this.argumentString.length) {
switch(this.argumentString[this.pos]) {
case " ": case "\t": case "\r": case "\n":
case '"': case "'":
terminated = true
this.pos--
break
case '\\':
this.pos++
default:
this.currentArgument += this.argumentString[this.pos]
}
this.pos++
}
}
readDoubleQuotedSubstring() {
var terminated = false
this.pos++ // move beyond starting quote
while(!terminated && this.pos < this.argumentString.length) {
switch(this.argumentString[this.pos]) {
case '"': terminated = true; break
case '\\': this.pos++
default: this.currentArgument += this.argumentString[this.pos]
}
this.pos++
}
}
readSingleQuotedSubstring() {
var terminated = false
this.pos++ // move beyond starting quote
while(!terminated && this.pos < this.argumentString.length) {
switch(this.argumentString[this.pos]) {
case "'": terminated = true; break
case '\\': this.pos++
default: this.currentArgument += this.argumentString[this.pos]
}
this.pos++
}
}
readUntilArgument() {
while(this.pos < this.argumentString.length) {
switch(this.argumentString[this.pos]) {
case ' ':
case '\t':
case '\r':
case '\n':
this.pos++
default:
return
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment