2017-10-18 125 views
1

我寫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

回答

1

生產規則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

相關問題