假设我想在scala中解析一个字符串,并且每次有括号嵌套在一起时,我会将一些数字与它自身相乘。防爆 数字= 3的(())+()+((()))为3 * 3 + 3 + 3 * 3 * 3。我如何使用scala组合器完成此操作。
class SimpleParser extends JavaTokenParsers {
def Base:Parser[Int] = """(""" ~remainder ~ """)"""
def Plus = atom ~ '+' ~ remainder
def Parens = Base
def remainder:Parser[Int] =(Next|Start) }
我如何制作它以便每次解析一个原子时,数字会自动相乘,然后原子内部的内容也会被解析? 我会在原子def之后放一个方法
def Base:Parser[Int] = """(""" ~remainder ~ """)""" ^^(2*paser(remainder))
?我不明白如何做到这一点,因为它的递归性质,就像我找到括号,我必须乘以这些括号中的任何三倍。
答案 0 :(得分:1)
如果您从内到外建立数字,这是最简单的。对于括号组,我们从基本情况开始(这将简单地导致数字本身),然后为每个嵌套再次添加数字。总而言之,我们从单个括号组开始,然后可选地添加加数,直到我们用完为止:
scala> ParserWith3.parseAll(ParserWith3.expr, "(())+()+((()))")
res0: ParserWith3.ParseResult[Int] = [1.15] parsed: 18
然后:
map
我使用的是map
,因为我无法支持解析库的小型运营商聚会,但您可以用{{1}替换所有^^
s }或^^^
如果你真的想要。
答案 1 :(得分:0)
如果您使用scala解析器组合器构建正确的递归规则这一事实(例如,mult
出现在其自己定义的右侧):
import scala.util.parsing.combinator.RegexParsers
trait ExprsParsers extends RegexParsers {
val value = 3
lazy val mult: Parser[Int] =
"(" ~> mult <~ ")" ^^ { _ * value } |||
"()" ^^ { _ => value }
lazy val plus: Parser[Int] =
(mult <~ "+") ~ plus ^^ { case m ~ p => m + p } |||
mult
}
要使用该代码,您只需创建一个继承ExprsParsers的结构,例如: :
object MainObj extends ExprsParsers {
def main(args: Array[String]): Unit = {
println(parseAll(plus, "() + ()")) //[1.8] parsed: 6
println(parseAll(plus, "() + (())")) //[1.10] parsed: 12
println(parseAll(plus, "((())) + ()")) //[1.12] parsed: 30
}
}
检查scala source file for parser是否有任何您不理解的操作员。