2017-10-18 22 views
1

ユーザから文字列を読み込み、再帰的降下パーサまたはパーサコンビネータのどちらかを使って、入力文字列が以下の文法と一致するかどうかを判断するScalaプログラムを作成します。 aとb)、途中に解析木を構築します。そして、マッチが成功すれば、生成されたツリーを出力する。Scala:カスタム文法/パーサーコンビネータ

文法:

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

は、私はあなたが任意のアイデアを持っている場合はありがとう、私はこれを実装する方法を教えてください、ので、任意の読み取りがはるかに高く評価されるためのScalaかなり新しいです。これは私が既に持っている私は現在持っているもの

コードです

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をお勧めします。 lihaoyi.com/fastparse/)。それは速く、シンプルで直感的な図書館です。ドキュメントにはいくつかの例があり、私の[stuff](https://github.com/sake92/nand2tetris)のいくつかがあります。 –

+0

私はちょうど私自身の文法を入れる方法を理解していません – Demuze28

答えて

1

プロダクションルールdef c[C] = ...は奇妙に見えます。あなたはおそらくdef c: Parser[C] = ...を意味しました。

次のコードでは、生成規則を定義し、scala-parser-combinatorsを使用してカスタム構文解析ツリーを構築する方法を紹介します:// WWW:

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

関連する問題