警告我是新手parboiled2
。
我希望能够以某种与所涉及的语法无关的方式编写我的 CLI。它将始终具有相同的形状,三元组:
case class Command(command: String, modifiers: Seq[String] = Nil, arguments: Seq[String] = Nil)
我想更进一步,也许是子类这个或子类它的解析器,或者以其他方式扩展以实现具有以下功能的能力:
case class CreateDogCommand(cmd: String, mods: Seq[String], args: Seq[String])
接受以下任何一项:
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
只是作为一个例子。我在这里根本不问细节;我要问的是如何从一开始就解决这个问题。
我至少看到了两种或三种方法。
- 保持现有
CommandParser
状态不变,并为每个命令语法排列编写特定于命令的解析器 - 为每个命令保留现有但编写特定于命令的、语法中立的解析器,以便可以使用任何语法,只要它被全面使用(但我该怎么做呢?)
- 编写
CommandParser
每个语法。
CurrentCommandParser
主要是从其他开源“启发”而来的:
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(' ')) }
}
所以我在想,也许我应该扩展CommandParser
或只是增加我的能力