scala - 如何使用 Scala 组合器为表达式赋予任意值

标签 scala parsing

假设我想在 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/

相关文章:

html - (AS3) 在自动换行后获取文本字段中的 HTML 特定字符索引

string - 在 UNIX 上解析文件中的数字

scala - 自定义 Scala 并行集合的任务支持?

scala - 在 SBT 中运行测试套件之前如何启动服务器?

scala - Scala 和 Haskell 类型系统的区别和相似之处是什么?

scala - 如何在 Scala 中为更高级的类型使用通配符?

scala - 如何在 Scala 中停止回溯?

jquery - 使用jquery解析xml时出现问题

ios - 显示加载消息直到完全解析 json iOS

javascript - 如何自动搜索和过滤linkedin中的所有工程师并将结果存储在excel中?