Warning I am new to parboiled2
.
I would like to be able to write my CLI in a way that is somewhat agnostic of the syntax involved. It will always have the same shape, a triplet of:
case class Command(command: String, modifiers: Seq[String] = Nil, arguments: Seq[String] = Nil)
I would like to take this further to, perhaps subclass this or subclass its parser, or otherwise extend to achieve the ability to have:
case class CreateDogCommand(cmd: String, mods: Seq[String], args: Seq[String])
accept any of:
Create-Dog -Feet 4 -Name Fido -Walks Daily /Home/Dogs
create_dog -f 4 --name Fido ~/Dogs
Dog.Create Feet=4, Name=Fido, Walks=Daily in /Home/Dogs
just as an example. I am not asking for the particulars at all here; what I am asking is how I might tackle this from the get-go.
I see at least two or three approaches.
- Leave the existing
CommandParser
as is, and write command-specific parsers for each command-syntax permutation - Leave the existing but write command-specific, syntax-neutral parsers for each command so that any syntax may be used as long as it is used across the board (but how would I do this?)
- Write a
CommandParser
per syntax.
Current CommandParser
is mostly "inspired" from other open source:
object CommandParser {
case class Command(command: String, modifiers: Seq[String] = Nil, arguments: Seq[String] = Nil)
}
trait CommandParser extends Parser {
import CommandParser._
val WhiteSpaceChar = CharPredicate(" \n\r\t\f")
def CommandEntry: Rule1[Command] =
rule { commandName ~ OptionalSpace ~ modifiers ~ OptionalSpace ~ arguments ~ EOI ~> Command }
def commandName = rule { capture(oneOrMore(AlphaNum | '-')) ~> (_.toString.replace(" ", "")) }
def modifiers = rule { zeroOrMore(ch('-') ~ capture(AlphaNumericString)).separatedBy(WhiteSpace) }
def arguments = rule { zeroOrMore(capture(CharacterString)).separatedBy(WhiteSpace) }
def AlphaNumericString = rule { oneOrMore(AlphaNum) }
def CharacterString = rule { oneOrMore(Visible) }
def WhiteSpace = rule { zeroOrMore(WhiteSpaceChar) }
def OptionalSpace = rule { optional(ch(' ')) }
}
So I was thinking that perhaps I should extend the CommandParser
or just tack onto waht I ahve