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