@Daniel Wagner의 대답에 정교하게 ... 파서가 일반적으로 Parsec으로 구축되는 방식은 특정 문자 (예 : 더하기 기호 또는 숫자)를 구문 분석하는 저급 파서로 시작하고 상단에 파서를 작성합니다 (하나의 숫자를 하나 이상의 숫자를 읽는 파서로 읽는 파서를 만드는 many1
조합 자나 "하나 이상의 숫자"를 파싱하는 모나드 구문 분석 "더하기 기호"와 " 하나 이상의 숫자 ").
그러나 각 파서는 하위 수준 디지타이저 파서 또는 상위 수준 "추가 식"파서이든 상관없이 동일한 입력 스트림에 직접 적용됩니다.
그렇지 는 일반적으로 음주, 말, 구문 분석 String
다른 파서를 생성하는 입력 스트림의 덩어리를 먹는다 파서를 쓰기 란 그 (대신 원래의 입력 스트림의) String
및 그들을 결합하려고합니다. 이것은 Parsec이 직접 지원하지 않는 부 자연스러운 비 모나드 식의 "수직 구성"입니다.
로가 수직 조성은 (당신이 하나 개의 언어가 구성 요소 또는 다른 언어의 표현에 내장 된 때 등) 깨끗한 전반적인 접근 방식이다 일부 상황이 있지만, 촬영 일반적인 접근 방법이 아니다, 의견에서 지적 Parsec 파서에 의해.
String
만 생성하는 파서는 cell
파서가 유용하기에 너무 전문화되어 있습니다.이제
import Text.Parsec
import Text.Parsec.String
-- | `csv cell` parses a CSV file each of whose elements is parsed by `cell`
csv :: Parser a -> Parser [[a]]
csv cell = many (row cell)
-- | `row cell` parses a newline-terminated row of comma separated
-- `cell`-expressions
row :: Parser a -> Parser [a]
row cell = sepBy cell (char ',') <* char '\n'
, 당신은 양의 정수를 구문 분석 사용자 정의 셀 파서 쓸 수 있습니다 : CSV 파일에 대한 더 유용한 파섹 프레임 워크는 것
customCell :: Parser Int
customCell = read <$> many1 digit
및 CSV 파일을 구문 분석 :
> parse (csv customCell) "" "1,2,3\n4,5,6\n"
Right [[1,2,3],[4,5,6]]
>
을
여기서 쉼표로 구분 된 셀을 다른 파서에 공급할 문자열로 명시 적으로 구문 분석하는 하위 파서를 cell
대신 사용하는 대신 "셀"은 suppl ia 셀 파서는, 입력 스트림의 중간의 행의 중간에 콤마로 단락 지어진 셀을 필요로하는 적절한 포인트에서 기본이되는 입력 스트림을 구문 분석하기 위해서 불려갑니다.
수직 파서 구도가 무슨 뜻인지 잘 모르겠습니다. 조금 더 확장 해 주시겠습니까? – gallais
@gallais "파서 푸 바 (Parser Foo Bar)"와 "파서 바 바즈 (Parser Bar Baz)"를 가져 와서 파서 푸 바즈 (Parser Foo Baz)로 바꾸는 방법을 말합니다. –
아, 알겠습니다. 이러한 간단한 유형의 목표는 OP의 질문보다 훨씬 명확합니다. 설명 주셔서 감사합니다! – gallais