2013-06-09 1 views
3

내가 스칼라의 파서 콤비와 언어를 분석하고있어, 나는함께 스칼라 파서 콤비 여러 리터럴을 폐기 ~><~

stmt -> if (stmt) {stmt} 

당연히 CFG 규칙을 표현하고 싶습니다, I 결과를 구성 할 때 "if() {}"문자열 리터럴을 버리려고합니다. 내가 생각한 두 가지 방법은 추한 것입니다.

방법 (A)는 "사건"문 내부의 문자열 리터럴의 위치를 ​​복제하기 위해 우리를 필요

lazy val stmt: PackratParser[Stmt] = 
    (
     // other rules... 
     | "if"~"("~stmt~")"~"{"~stmt~"}" ^^ { case _~_~s1~_~_~s2~_ ⇒ If(s1, s2) } 
    ) 

방법 (B)이 때문에 ~와 ~>의 우선 순위에 혼란 괄호가 필요합니다.

lazy val stmt: PackratParser[Stmt] = 
    (
     // other rules... 
     | ("if"~>"("~>stmt)~(")"~>"{"~>stmt<~"}") ^^ { case s1~s2 ⇒ If(s1, s2) } 
    ) 

이상적으로는 폐기하고자하는 "(", ")"내 스칼라 코드에 괄호를 필요없이 리터럴. 이 작업을 수행 할 수있는 명확한 방법이 있습니까?

답변

4

괄호를 많이하지 않고 우선 순위 문제를 방지하는 가장 일반적인 방법은 몇 가지 도우미를 정의하는 것입니다, 그리고 내 눈에, 꽤 잘 여기 일이 어떤 이유로 옵션이 아닌 경우

val cond  = "(" ~> stmt <~ ")" 
val thenClause = "{" ~> stmt <~ "}" 
val ifStmt = "if" ~> cond ~ thenClause ^^ { case s1 ~ s2 => If(s1, s2) } 

, 이 같은 것을 나는 확실히 당신의 첫 번째 접근을 피할 것, 나는 우선 순위-관리 괄호는 구문 즉, 더 깨끗하게 일치하도록 두 번째를 조정할 것 :

이 크지 않다
"if" ~> ("(" ~> stmt <~ ")") ~ ("{" ~> stmt <~ "}") ^^ { 
    case s1 ~ s2 => If(s1, s2) 
} 

, 그러나 그것은 절대적으로 읽을 수있는 것도 아닙니다.

관련 문제