파섹

2014-12-22 1 views
2

나는 다음과 같은 구문 분석됩니다 파섹를 사용하여 파서 쓰기를 시도하고있어와 하스켈의 하위 집합을 구문 분석 다음 data 표현파섹

data Nat = Z | S Nat 

plusNat :: Nat -> Nat -> Nat 
plusNat Z  m = m 
plusNat (S n) m = S (plusNat n m) 

을, 나는 다음과 같은 파서 있습니다

parseData = reserved "data" >> DataDefn 
     <$> identifier 
     <*> parseCnstr `sepBy` reservedOp "|" 

parseCnstr = DataCnstr <$> identifier <*> many parseTypeTerm 

parseType = buildExpressionParser table parseTypeTerm 
    where table = [[function]] 
      function = Infix (Function <$ reservedOp "->") AssocRight 

parseTypeTerm = TypeVar <$> identifier 
      <|> parens parseType 

그러나 위의 텍스트에서이 파서를 사용하는 경우 parseType 그래머는 plusNat이고 오류는 다음과 같습니다.

"test.hs" (line 3, column 9): 
unexpected ':' 
expecting "|" or end of input 

plusNatdataCnstr의 일부로 인식 되었기 때문에 문제가 무엇인지 압니다. dataCnstr 파서가 들여 쓰기되지 않은 새 줄을 가져올 때 멈추도록하려면 어떻게합니까? 나는뿐만 아니라 다음과 같은 구문 분석 할 수 있도록하려면

참고 :

data ReallyLongData reallyLongTypeVariable 
    = ReallyLongConstructor1 
    | ReallyLongConstructor2 
     reallyLongTypeVariable 
     (ReallyLongData reallyLongTypeVariable) 

concat :: ReallyLongData a -> ReallyLongData a -> ReallyLongData a 
concat = ... 
+1

'buildExpressionParser'는 * 표현식 만 이해합니다 *. 여러분은 입력 문자열을'buildExpressionParser'에 넣을 수있는 문자열로 들여 쓰기 할 수있는 들여 쓰기 파서가 필요합니다 (아마 라이브러리가 있습니다). (실제로 입력 자체를 제한하는 것 외에는 블랙 박스 파서가 취하는 것을 "제한"할 수는 없습니다.) – Rufflewind

+0

감사합니다. 입력을 들여 쓰기 블록으로 나누는 파서를 작성했습니다. –

+1

잠깐, 작동하지 않습니다. 들여 쓰기 된 블록을 나누는 String -> [String] 함수가 있지만 이제 SourcePos를 올바르게 유지하면서 각 블록을 구문 분석 할 수있는 방법을 찾을 수 없습니다. mapM을 사용하면 작동하지 않습니다. –

답변

2

나 자신 Text.Parsec.Indent를 사용하여 해결했다.

parseData = withPos $ <old definition> 

parseCntr = (DataCnstr <$> identifier) <*/> parseTypeTerm 

이렇게하면 모든 들여 쓰기가 올바른 들여 쓰기로 구문 분석됩니다.

관련 문제