2012-05-30 2 views
6

작동하는 스칼라 파서가 있는데 해결책은 내가 원하는만큼 깨끗하지 못합니다. 문제는 일부 제작자가 공백을 토큰의 일부로 고려해야하지만 "상위 수준"제작자는 공백을 무시하거나 건너 뛸 수 있어야한다는 것입니다.스칼라 때때로 공백을 건너 뛰고 때때로하지 않는 파서

저급 파서를 확장하는 일반적인 스칼라 파서 패턴을 사용하면 skipWhitespace 설정이 상속되고 모든 것이 매우 빠르게 복잡해집니다.

확장 방법을 사용하지 않는 것이 좋지만 상위 수준의 파서 클래스에서 사용할 수있는 저급 파서의 인스턴스가 있어야한다고 생각합니다.하지만 그 작업을 수행하는 방법을 잘 모르겠습니다. 각 인스턴스는 하나의 입력 문자 스트림 만 보게됩니다. 여기

가장 낮은 수준 파서의 일부입니다 -

class VulgarFractionParser extends RegexParsers { 
    override type Elem = Char 

override val whiteSpace = "".r 

가 그럼 난

class NumberParser extends VulgarFractionParser with Positional { 

처럼 그러나이 시점에서 NumberParser 명시 적으로 단지 FractionParser처럼 공백 처리해야 함을 확장합니다. NumberParser의 경우 여전히 관리가 쉽습니다.하지만 다음 레벨에서는 실제로 프로덕션을 정의 할 수 있기를 원합니다. do 일반 정규 표현식 파서와 마찬가지로 공백을 구분 기호로 사용합니다.

예는 다음과 같을 것이다

IBM 33.33/ 1200.00 
or 
IBM 33.33/33.50 1200.00 

때로는 두 부분으로 구분 한 제 2 차 값이 "/"때로는 단지 슬래시 후 아무것도 하나의 부분이 (또는 슬래시를 포함하지 않는 조금도).

def bidOrAskPrice = ("$"?) ~> (bidOrAskPrice1 | bidOrAskPrice2 | bidOrAskPrice3) 

    def bidOrAskPrice1 = number ~ ("/".r) ~ number ~ (SPACES) ^^ { 
    case a ~ slash ~ b ~ sp1 => BidOrAsk(a,Some(b)) 
    } 
    def bidOrAskPrice2 = (number ~ "/" ~ (SPACES)) ^^ { case a ~ slash ~ sp => BidOrAsk(a,None) } 
    def bidOrAskPrice3 = (number ~ (SPACES?)) ^^ { case a ~ sp => BidOrAsk(a , None)} 
+0

공백을 고려해야하는 제작 사례와 공백을 고려하지 않아야하는 제작 사례를 제공 할 수 있습니까? – sarnold

+0

은 데이터의 예와 공백에 민감한 요소 중 하나를 사용하여 질문을 업데이트했습니다. – malsmith

답변

2

가 (정말, 렉서) 토큰 파서에 처음 파서를 설정하는 것이 더 이해가되지 않습니다, 그리고 대신 두 번째 파서 읽기를 만들 일반 Char?

+1

이 접근법의 예는 보지 못했지만 원하는 것보다 더 들립니다. – malsmith

관련 문제