2012-11-12 5 views
1

개체의 텍스트 표현이 포함 된 파일이 있습니다. 필자는 텍스트를 파싱하고 객체를 반환하는 결합 파서 문법을 작성했습니다. 이 텍스트에서 "#"은 주석 구분 기호입니다. 해당 문자에서 줄 끝까지의 모든 내용이 무시됩니다. 빈 줄도 무시됩니다. 한 번에 한 줄씩 텍스트를 처리하여 매우 큰 파일을 처리 할 수 ​​있습니다.전처리 스칼라 파서 리더 입력

일반 주석과 빈 줄 논리를 사용하여 파서 문법을 혼란스럽게하고 싶지는 않습니다. 전처리 단계로 이것을 제거하고 싶습니다. 나는 이런 식으로 뭔가를 할 수있는 라인의 반복자에 파일을 변환 :

Source.fromFile("file.txt").getLines.map(_.replaceAll("#.*", "").trim).filter(!_.isEmpty) 

어떻게 연결자 파서에 그런 식의 출력을 전달할 수 있습니다? 이 같은 필터링 된 식 밖으로 Reader 개체를 만드는 방법을 알아낼 수 없습니다. Java FileReader 인터페이스가 그런 식으로 작동하지 않습니다.

이 방법이 있습니까, 또는 내 주석 및 빈 줄 논리를 구문 분석기 문법에 넣어야합니까? 후자의 경우 이미 나를 위해 이것을 수행하는 일부 util.parsing 패키지가 있습니까?

답변

3

이 작업을 수행하는 가장 간단한 방법은 PagedSeqfromLines 방법을 사용하는 것입니다. 이는 본질적으로 java.io.Reader을 구문 분석 할 때 발생합니다. 즉, 즉시 PagedSeqReader으로 묶입니다.

0

하지 예쁜 코드 혹시 쓸 것이다,하지만, 다음과 같이 새 Source을 통해 갈 수 :

val SEP = System.getProperty("line.separator") 
def lineMap(fileName : String, trans : String=>String) : Source = { 
    Source.fromIterable(
    Source.fromFile(fileName).getLines.flatMap(
     line => trans(line) + SEP 
    ).toIterable 
) 
} 

설명 : flatMap 당신이로 설정할 수 있습니다 문자에 반복자를 생성합니다 Iterable을 사용하여 새 Source을 만들 수 있습니다. SEPgetLines이 기본적으로 제거하므로 은 줄을 제대로 구분하지 않으므로 \n이 작동하지 않을 수 있습니다. 당신이 즉, 너무 필터링을 적용 라인의 일부를 제거하려면

, 당신은 예를 들어 시도 할 수 :

// whenever `trans` returns `None`, the line is dropped. 
def lineMapFilter(fileName : String, trans : String=>Option[String]) : Source = { 
    Source.fromIterable(
    Source.fromFile(fileName).getLines.flatMap(
     line => trans(line).map(_ + SEP).getOrElse("") 
    ).toIterable 
) 
} 

를 예를 들어 :

lineMapFilter("in.txt", line => if(line.isEmpty) None else Some(line.reverse)) 

이 ... 빈 줄을 제거합니다 그리고 비어 있지 않은 것들을 뒤집는다.

import scala.collection.immutable.PagedSeq 
import scala.io.Source 
import scala.util.parsing.input.PagedSeqReader 

val lines = Source.fromFile("file.txt").getLines.map(
    _.replaceAll("#.*", "").trim 
).filterNot(_.isEmpty) 

val reader = new PagedSeqReader(PagedSeq.fromLines(lines)) 

그리고 지금 당신은 당신이 당신의 파서에 연결 할 수있는 scala.util.parsing.input.Reader있어 :