如何使用scala组合器为表达式赋予任意值(How to use scala combinators to give arbitrary values to expressions)

编程入门 行业动态 更新时间:2024-10-26 10:30:27
如何使用scala组合器为表达式赋予任意值(How to use scala combinators to give arbitrary values to expressions)

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

I'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.

更多推荐

本文发布于:2023-07-04 10:51:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1023511.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:组合   表达式   如何使用   scala   combinators

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!