2017-10-18 1 views
1

Ich schreibe ein Scala-Programm, das eine Zeichenfolge aus dem Benutzer liest, und verwendet entweder eine rekursive Abstammung Parser oder Parser Kombinator, um festzustellen, ob die Eingabezeichenfolge der folgenden Grammatik entspricht (dh besteht aus a's und b's), während man einen Parsebaum auf dem Weg baut. Und dann geben Sie den generierten Baum aus, wenn die Übereinstimmung erfolgreich ist.Scala: benutzerdefinierte Grammatik/Parser Kombinator

Grammatik:

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

Ich bin ziemlich neu in Scala so wird jede Lesung sehr geschätzt, wenn Sie irgendwelche Ideen haben, lassen Sie es mich wissen, wie ich das umsetzen kann, danke.

Dies ist, was ich zur Zeit

-Code habe ich bereits:

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

Ich würde empfehlen, [fastparse] (http: // www. lihaoyi.com/fastparse/). Es ist eine schnelle, einfache und intuitive Bibliothek. Es gibt einige Beispiele in den Dokumenten und hier sind einige meiner [Zeug] (https://github.com/sake92/nand2tetris). –

+0

Ich verstehe einfach nicht, wie man meine eigenen Grammatiken einfügt – Demuze28

Antwort

1

Produktionsregel def c[C] = ... seltsam aussieht:

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

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

Die Ausgabe wie folgt aussehen sollte. Sie haben wahrscheinlich stattdessen def c: Parser[C] = ... gemeint.

Der folgende Code wird Ihnen zeigen, wie Produktionsregeln definieren und einen benutzerdefinierten Parse-Baum scala-parser-combinators mit bauen:

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

Vielen Dank Sir, sehr geschätzt – Demuze28

Verwandte Themen