2012-09-19 5 views
1

하나의 특성에서 다른 특성의 메서드에서 반환 된 Parser를 사용하는 데 문제가 있습니다. 컴파일러는 형식 불일치에 대해 불평하며 문제는 경로 종속 클래스로 인한 것입니다. 나는 내가 원하는 것을 얻는 방법을 모르겠다. 경로 종속 형으로 말미 느낀다

trait Outerparser extends RegexParsers { 

    def inner: Innerparser 

    def quoted[T](something: Parser[T]) = "\"" ~> something <~ "\"" 
    def quotedNumber = quoted(inner.number)  // Compile error 
    def quotedLocalNumber = quoted(number)  // Compiles just fine 
    def number: Parser[Int] = ("""[1-9][0-9]*"""r) ^^ {str => str.toInt} 

} 

trait Innerparser extends RegexParsers { 

    def number: Parser[Int] = ("""[1-9][0-9]*"""r) ^^ {str => str.toInt} 

} 

그리고 오류 :

[error] /Path/to/MyParser.scala:6: type mismatch 
[error] found : minerals.Innerparser#Parser[Int] 
[error] required: Outerparser.this.Parser[?] 
[error] def quotedNumber = quoted(inner.number) 

I 정렬의 아이디어를 얻을 : 각 "뭔가"방법은 그 경로 둘러싸는 클래스 (Outerparser 또는 Innerparser)에 특정한 파서 유형을 정의한다. Outerparser의 "quoted"메소드는 Outerparser.this.Parser 유형의 인스턴스를 기대하지만 Innerparser # Parser를 얻습니다.

나는이 클래스 또는 다른 클래스에서 얻은 파서에 인용 부호를 사용할 수 있기를 좋아합니다. 어떻게해야합니까?

답변

1

당신은 여전히 ​​모듈화를 유지하면서 컴파일하기 위해 자기 형의 주석을 사용할 수 있습니다 할 수있는 :

trait OuterParser extends RegexParsers { this: InnerParser => 
    def quoted[T](something: Parser[T]) = "\"" ~> something <~ "\"" 
    def quotedNumber = quoted(number)  // Compile error 
} 

trait InnerParser extends RegexParsers { 
    def number: Parser[Int] = ("""[1-9][0-9]*"""r) ^^ {str => str.toInt} 
} 

object MyCompleteParser extends OuterParser with InnerParser 

기본적으로 자체 형식 주석은 OuterParser가 InnerParser에 종속되어 있다고 말합니다 (적절한 인스턴스화 가능한 클래스를 만들기 위해서는 함께 혼합해야 함). 따라서 컴파일러는 OuterParser 및 InnerParser에서 Parser이 동일한 유형을 참조하는지 확인합니다.

2

일반적으로 스칼라 파서 연결자 라이브러리를 사용하는 방식은 특성 인 RegexParsers과 같은 모든 특성 또는 개체를 모두 포함하는 것입니다. API가 이렇게 설계된 이유는 잘 모르겠습니다.

trait Everything extends RegexParsers { 
    trait Outerparser { 
     ... 
    } 

    trait Innerparser { 
     ... 
    } 
} 

그리고 모두가 행복하다 : 그들은 모두 RegexParsers의 동일한 인스턴스에 속하는 일단

그러나 어쨌든, 그들은 모두 같은 Parser 유형을 참조하십시오.


모든 것을 같은 범위에 두는 것으로 생각하지 마십시오. 즉 수입 이름의 파서 콤비 API의 괴짜 방법으로 생각, 당신은 쉽게

import scala.util.parsing.combinator._ 
import scala.util.parsing.input._ 

object blah extends RegexParsers 
import blah._ 

trait Outerparser { 
    ... 
} 

trait Innerparser { 
    ... 
} 
+0

나는 모든 파싱 코드를 같은 범위에 넣고 싶지 않습니다. 다른 아이디어? – Ladlestein

관련 문제