解析 0 个或多个 idents 后跟 ident 的列表
Parsing a list of 0 or more idents followed by ident
我想解析像这样形成的 DSL 的一部分:
configSignal: sticky Config
语义上是:
argument_name: 0_or_more_modifiers argument_type
我尝试实现以下解析器:
def parser = ident ~ ":" ~ rep(ident) ~ ident ^^ {
case name ~ ":" ~ modifiers ~ returnType => Arg(name, returnType, modifiers)
}
事实是,应用 rep(ident)
部分直到没有更多标记且解析器失败,因为最后一个 ~ ident
不匹配。我应该如何正确执行此操作?
编辑
同时我意识到,修饰符将是保留字(关键字),所以现在我有:
def parser = ident ~ ":" ~ rep(modifier) ~ ident ^^ {
case name ~ ":" ~ modifiers ~ returnType => Arg(name, returnType, modifiers)
}
def modifier = "sticky" | "control" | "count"
尽管如此,我很好奇如果没有预先定义修饰符是否可以编写解析器。
"0 or more idents followed by ident" 等同于"1 or more idents", 所以只用rep1
它的文档:
def rep1[T](p: ⇒ Parser[T]): Parser[List[T]]
A parser generator for non-empty repetitions.
rep1(p) repeatedly uses p to parse the input until p fails -- p must succeed at least once (the result is a List of the consecutive results of p)
p a Parser that is to be applied successively to the input
returns A parser that returns a list of results produced by repeatedly applying p to the input (and that only succeeds if p matches at least once).
编辑以回应 OP 的评论:
我认为没有内置方法可以执行您所描述的操作,但使用常规列表方法映射到您的自定义数据类型仍然相对容易:
def parser = ident ~ ":" ~ rep1(ident) ^^ {
case name ~ ":" ~ idents => Arg(name, idents.last, idents.dropRight(1))
}
在这种特殊情况下,您不必担心 idents
成为 Nil
,因为 rep1
解析器仅在非空列表时成功。
我想解析像这样形成的 DSL 的一部分:
configSignal: sticky Config
语义上是:
argument_name: 0_or_more_modifiers argument_type
我尝试实现以下解析器:
def parser = ident ~ ":" ~ rep(ident) ~ ident ^^ {
case name ~ ":" ~ modifiers ~ returnType => Arg(name, returnType, modifiers)
}
事实是,应用 rep(ident)
部分直到没有更多标记且解析器失败,因为最后一个 ~ ident
不匹配。我应该如何正确执行此操作?
编辑
同时我意识到,修饰符将是保留字(关键字),所以现在我有:
def parser = ident ~ ":" ~ rep(modifier) ~ ident ^^ {
case name ~ ":" ~ modifiers ~ returnType => Arg(name, returnType, modifiers)
}
def modifier = "sticky" | "control" | "count"
尽管如此,我很好奇如果没有预先定义修饰符是否可以编写解析器。
"0 or more idents followed by ident" 等同于"1 or more idents", 所以只用rep1
它的文档:
def rep1[T](p: ⇒ Parser[T]): Parser[List[T]]
A parser generator for non-empty repetitions.
rep1(p) repeatedly uses p to parse the input until p fails -- p must succeed at least once (the result is a List of the consecutive results of p)
p a Parser that is to be applied successively to the input
returns A parser that returns a list of results produced by repeatedly applying p to the input (and that only succeeds if p matches at least once).
编辑以回应 OP 的评论:
我认为没有内置方法可以执行您所描述的操作,但使用常规列表方法映射到您的自定义数据类型仍然相对容易:
def parser = ident ~ ":" ~ rep1(ident) ^^ {
case name ~ ":" ~ idents => Arg(name, idents.last, idents.dropRight(1))
}
在这种特殊情况下,您不必担心 idents
成为 Nil
,因为 rep1
解析器仅在非空列表时成功。