2014-11-23 6 views
4

String과 다른 구문 분석을 위해 구문 분석 라이브러리 중 하나 (예 : Parsec)를 사용할 수 있습니까? 그리고 어떻게하면 좋을까요?하스켈 파서로 임의리스트를 파싱하는 법?

단순화를 위해 입력이 int 목록 인 [Int]이라고 가정 해 봅시다. 이 작업은 S 10보다 작은 수이고, L 숫자 크거나 10와 동일한 패턴 (S+L+)*로 나머지를 분석

  • 드롭 앞에 0
  • 수 있습니다.
  • fstSsnd의 제품입니다 튜플 (Int,Int)의 목록을 반환
  • 하면 사람이 같은 파서를 작성하는 방법을 보여 수 있다면 좋을 것 L 정수

의 제품 (또는 뭔가 비슷한).

답변

6

user5402 지적한 바와 같이 예, ParsecStream의 인스턴스를 파싱 할 수있다 임의의 목록을 포함하여 미리 정의 된 토큰 파서가 없으므로 (예 : 텍스트의 경우와 같이) 예를 들어를 사용하여 자신을 굴려야합니다 (아래 myToken). tokenPrim

내가 조금 어색하다고 느낀 유일한 것은 "소스 위치"를 처리하는 것입니다. SourcePos은 형식 클래스가 아닌 추상 형식이므로 여기에서 약간 부 자연스러운 "파일 이름/줄/열"형식을 사용해야합니다.

*Main> testMe [1,2,55,33,3,5,99] 
[(2,1815),(15,99)] 
*Main> testMe [1,2,55,33,3,5,99,1] 
*** Exception: "your list" (line 1, column 9): 
unexpected end of input 

주에게 어색한 행/열 형식 오류에 :

어쨌든

, 여기

import Text.Parsec 

myToken :: (Show a) => (a -> Bool) -> Parsec [a]() a 
myToken test = tokenPrim show incPos $ justIf test where 
    incPos pos _ _ = incSourceColumn pos 1 
    justIf test x = if (test x) then Just x else Nothing 

small = myToken (< 10) 
large = myToken (>= 10) 

smallLargePattern = do 
    smallints <- many1 small 
    largeints <- many1 large 
    let prod = foldl1 (*) 
    return (prod smallints, prod largeints) 

myIntListParser :: Parsec [Int]() [(Int,Int)] 
myIntListParser = many smallLargePattern 

testMe :: [Int] -> [(Int, Int)] 
testMe xs = case parse myIntListParser "your list" xs of 
    Left err -> error $ show err 
    Right result -> result 

은 모두 밖으로 시도 (간결함을 위해, 선행 0의 건너 뛰기없이) 코드입니다 메시지

물론 함수를 쓸 수 있습니다. sanitiseSourcePos :: SourcePos -> MyListPosition

3

Parsec이 스트림 유형으로 [a]을 사용할 수있는 가능성이 매우 높지만 파서 연결자의 개념은 실제로 매우 간단하며 사용자 고유의 라이브러리를 롤하는 것은 그리 어렵지 않습니다.

Graham Hutton 및 Erik Meijer의 Monadic Parsing in Haskell은 매우 유용한 리소스입니다.

실제로 Erik Meijer는 edx.org (link)에서 Haskell/functional 프로그래밍 과정을 소개하고 Lecture 7은 모두 기능 파서에 관한 내용입니다. 그는 강의에 대한 소개에 상태로 :.

"... 아무도 자신의 파서 콤비 라이브러리를 작성하지 않고 함수형 프로그래밍을 마스터 향한 경로를 따라 할 수 없습니다 우리는 파서가 무엇인지 설명함으로써 시작하고 어떻게 자연스럽게 할 수 사이드 행하는 함수로 간주 될 수있다. 다음 우리 파서 함께 기본적인 파서 및 고차 함수를 정의한다. ... "