Scala的:自定义语法/解析器组合

Scala的:自定义语法/解析器组合

问题描述:

我写Scala程序读取来自用户的字符串,并使用任一递归下降解析器或解析器组合,以确定是否输入的字符串的下面的语法相匹配(即,是由a和b),同时建立一个分析树。如果匹配成功,则输出生成的树。Scala的:自定义语法/解析器组合

语法:

S -> E$ 
E -> C E2 
E2 -> E 
E2 -> NIL 
C -> 'a' | 'b' 

我是相当新的斯卡拉所以任何阅读我们将不胜感激,如果你有任何想法,请让我知道我怎么能实现这一点,谢谢。

这是我目前

代码我已经有:

class MPParser extends JavaTokenParsers{ 
def c[C] = (“a” | “b”) ^^ {case ch => C(ch)} 
} 

abstract class MatchTree 
case class C(s:String) extends MatchTree 

输出应该是这个样子:

scala> Microproject.main(Array("ababa")) 
input : ababa 
[1.6] parsed: S(E(C(a),E(C(b),E(C(a),E(C(b),E(C(a),NIL())))))) 

scala> Microproject.main(Array("ababac")) 
input : ababac 
[1.6] failure: `b' expected but `c' found 

ababac 
^ 
+2

我会建议[fastparse(HTTP:// WWW。 lihaoyi.com/fastparse/)。它是快速,简单和直观的库。有在文档的一些例子,这里是我的一些[东东](https://github.com/sake92/nand2tetris)。 –

+0

我只是不明白如何把我自己的语法 – Demuze28

生产规则def c[C] = ...看起来很奇怪。您可能意思是代替def c: Parser[C] = ...

下面的代码将告诉你如何定义产生式规则,并建立使用scala-parser-combinators定制解析树:

import scala.util.parsing.combinator.RegexParsers 

case class S(e: E) 

// E2 -> E | NIL 
sealed abstract class E2 
case class E(c: C, e2: E2) extends E2 
case object NIL extends E2 { override def toString = "NIL()" } 

case class C(aOrB: String) 

class MPParser extends RegexParsers { 
    // S -> E 
    def s: Parser[S] = e ^^ { S(_) } 
    // E -> C E2 
    def e: Parser[E] = c ~ e2 ^^ { case c ~ e2 => E(c, e2) } 
    // E2 -> E | NIL 
    def e2: Parser[E2] = opt(e) ^^ { _.getOrElse(NIL) } 
    // C -> 'a' | 'b' 
    def c: Parser[C] = ("a" | "b") ^^ { C(_) } 
} 

object Microproject extends App { 
    val parser = new MPParser 
    for (arg <- args) { 
    println("input : " + arg) 
    println(parser.parseAll(parser.s, arg)) 
    } 
} 

Live on Scastie

+0

谢谢主席先生,非常感谢 – Demuze28