1

警告我是新手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

只是作为一个例子。我在这里根本不问细节;我要问的是如何从一开始就解决这个问题。

我至少看到了两种或三种方法。

  1. 保持现有CommandParser状态不变,并为每个命令语法排列编写特定于命令的解析器
  2. 为每个命令保留现有但编写特定于命令的、语法中立的解析器,以便可以使用任何语法,只要它被全面使用(但我该怎么做呢?)
  3. 编写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或只是增加我的能力

4

0 回答 0