无论您是否想要实现一个合适的解析器,您至少应该创建能够忠实地表示您的命令的数据结构。
这里有一个建议:
sealed trait Dimension {
def translate(implicit t: Map[Symbol, String]) =
t(Symbol(toString.toLowerCase))
}
case object W extends Dimension
case object H extends Dimension
case object L extends Dimension
case object R extends Dimension
case object T extends Dimension
case object B extends Dimension
object Dimension {
def all = List(W, H, L, R, T, B)
}
sealed trait CommandModifier {
def translate(implicit t: Map[Symbol, String]): String
}
case object Unmodified extends CommandModifier {
def translate(implicit t: Map[Symbol, String]) = ""
}
case class Multiplied(factor: Int) extends CommandModifier {
def translate(implicit t: Map[Symbol, String]) = t('m) + " " + factor
}
case class Command(dim: Dimension, mod: CommandModifier) {
def translate(implicit t: Map[Symbol, String]) =
dim.translate + " " + mod.translate
}
A.
Command
是一个适当的case类,它将维度和修改器作为成员。这个
CommandModifier
s被建模为一个单独的封闭特征。这个
Dimension
s(宽度、高度等)本质上只是一个枚举。短魔术值字符串
"w"
,则,
"h"
已替换为符号
'w
,则,
'h
等
现在您可以实现
Untranslation
一次提取整个命令的提取器,因此不需要任何其他参数:
object Untranslation {
def unapply(s: String)(implicit t: Map[Symbol, String]): Option[Command] = {
val sParts = s.split(" ").toList
for (dim <- Dimension.all) {
val a: List[String] = dim.translate.split(" ").toList
val b: List[String] = t('m).split(" ").toList
val ab: List[String] = a ++ b
sParts match {
case `a` => return Some(Command(dim, Unmodified))
case `ab` :+ value => return Some(Command(dim, Multiplied(value.toInt)))
// + some more cases
case _ => None
}
}
None
}
}
一个小例子。下面是如何用英语和德语解析和写出命令。首先,将形式符号映射到自然语言中实际单词的两个词典:
val En = Map(
'w -> "width",
'h -> "height",
'l -> "left",
'r -> "right",
't -> "top",
'b -> "bottom",
'm -> "multiplied by"
)
val De = Map(
'w -> "Breite",
'h -> "Höhe",
'l -> "links",
'r -> "rechts",
't -> "oben",
'b -> "unten",
'm -> "mal"
)
使用
En
-字典中,您现在可以用英语匹配命令:
for (example <- List(
"width multiplied by 2",
"top",
"height multiplied by 42"
)) {
println("-" * 60)
implicit val lang = En
example match {
case Untranslation(v) => {
println(v)
println(v.translate(En))
println(v.translate(De))
}
case _ => println("invalid command")
}
}
以下是匹配的内容,以及如何将其翻译成英语和德语:
------------------------------------------------------------
Command(W,Multiplied(2))
width multiplied by 2
Breite mal 2
------------------------------------------------------------
Command(T,Unmodified)
top
oben
------------------------------------------------------------
Command(H,Multiplied(42))
height multiplied by 42
Höhe mal 42
从德语到英语,情况正好相反:
for (example <- List(
"Breite mal 2",
"oben",
"Höhe mal 42"
)) {
println("-" * 60)
implicit val lang = De
example match {
case Untranslation(v) => {
println(v)
println(v.translate(En))
println(v.translate(De))
}
case _ => println("invalid command")
}
}
输出:
------------------------------------------------------------
命令(W,乘以(2))
宽度乘以2
布雷特mal 2
------------------------------------------------------------
命令(T,未修改)
顶部
奥本
------------------------------------------------------------
命令(H,乘以(42))
高度乘以42
Hhe mal 42
请注意,字符串拆分和模式匹配的整个方法是
极其
易碎,根本不起作用。如果您想正确地完成它,您必须编写一个正确的解析器(使用解析器生成器或解析器组合器库)。