假设我想在 Scala 中解析一个字符串,每次有括号嵌套在彼此中时,我都会将一些数字与它本身相乘。前任 (()) +() + ((())) with number=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) }
我该如何做到每次解析一个原子时,数字都会自乘,然后原子内部的内容也会被解析? 我会在 atom def 之后放一个方法吗?
def Base:Parser[Int] = """(""" ~remainder ~ """)""" ^^(2*paser(remainder))
?由于它的递归性质,我不明白该怎么做,就好像我找到了括号,然后我必须将这些括号中的内容乘以三倍。
最佳答案
如果您从内到外建立数字,这是最简单的。对于括号组,我们从基本情况开始(这只会导致数字本身),然后为每个嵌套再次添加数字。对于总和,我们从一个带括号的组开始,然后可选择添加被加数直到用完:
import scala.util.parsing.combinator.JavaTokenParsers
class SimpleParser(number: Int) extends JavaTokenParsers {
def base: Parser[Int] = literal("()").map(_ => number)
def pars: Parser[Int] = base | ("(" ~> pars <~ ")").map(_ + number)
def plus: Parser[Int] = "+" ~> expr
def expr: Parser[Int] = (pars ~ opt(plus).map(_.getOrElse(0))).map {
case first ~ rest => first + rest
}
}
object ParserWith3 extends SimpleParser(3)
然后:
scala> ParserWith3.parseAll(ParserWith3.expr, "(())+()+((()))")
res0: ParserWith3.ParseResult[Int] = [1.15] parsed: 18
我正在使用 map
因为我受不了解析库的小运算符(operator)派对,但你可以替换所有 map
与 ^^
或 ^^^
如果你真的想要的话。
关于scala - 如何使用 Scala 组合器为表达式赋予任意值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34278551/