假设我想在scala中解析一个字符串,并且每次在括号内嵌套括号时,我会将一些数字与它自身相乘。 数字= 3的Ex(())+()+((()))为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))? 我不明白如何做到这一点,因为它的递归性质,就好像我找到括号,我必须乘以这些括号中的三倍。
Lets say I want to parse a string in scala, and every time there were parenthesis nested within each other I would multiply some number with itself . Ex (()) +() + ((())) with number=3 would be 3*3 + 3 + 3*3*3. How would I do this with scala combinators.
class SimpleParser extends JavaTokenParsers { def Base:Parser[Int] = """(""" ~remainder ~ """)""" def Plus = atom ~ '+' ~ remainder def Parens = Base def remainder:Parser[Int] =(Next|Start) }How would I make it so that every time an atom is parsed the number would multiply by itself, and then what was inside the atom will also be parsed? would I put a method after the atom def like
def Base:Parser[Int] = """(""" ~remainder ~ """)""" ^^(2*paser(remainder))? I don't understand how to do this because of the recursive nature of it, as if I find parenthesis, I must then multiply by three times whatever is in these parenthesis.
最满意答案
如果你从里到外建立数字,这是最简单的。 对于括号组,我们从基本情况开始(这将导致数字本身),然后再为每个嵌套添加数字。 总而言之,我们从单个括号组开始,然后可选地添加加数,直到我们用完为止:
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因为我无法忍受解析库的小操作员派对,但如果你真的想要,你可以用^^或^^^替换所有map 。
This is easiest if you build up the number from the inside out. For the parenthetical groups, we start with the base case (which will result in simply the number itself), and then add the number again for each nesting. For the sum, we start with a single parenthetical group and then optionally add summands until we run out:
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)And then:
scala> ParserWith3.parseAll(ParserWith3.expr, "(())+()+((()))") res0: ParserWith3.ParseResult[Int] = [1.15] parsed: 18I'm using map because I can't stand the parsing library's little operator party, but you could replace all the maps with ^^ or ^^^ if you really wanted to.
更多推荐
发布评论