2017-10-18 4 views
1

사용자로부터 문자열을 읽는 스칼라 프로그램을 작성하고, 재귀 적 파생 파서 또는 파서 결합자를 사용하여 입력 문자열이 아래의 문법과 일치하는지 확인합니다 (즉, a와 b), 길을 따라 파스 트리를 만드는 동안. 일치가 성공하면 생성 된 트리를 출력합니다.스칼라 : 커스텀 문법/파서 결합 자

문법 :

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 

출력은 다음과 비슷한 모습이 될 것입니다 def c[C] = ... 이상한 보이는

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: 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