2014-05-17 2 views
0

나는 attoparsec으로 간단한 파서를 만들고자합니다. 생산 규칙의 라인을 따라있는이 : 내가 무엇에 있습니다 얻으려고Out of Memory Attoparsec 사용

block: ?token> [inline] 
inline: <?token>foo<?> | anyText 

따라서, 블록은 문자로 시작 시퀀스 다음에>를 다음에, 토큰 다음에? 인라인.

인라인은 foo 형식의 시퀀스이거나 일반 텍스트 일뿐입니다.

나는 폭발적인 메모리 사용을하고있다. 그러나 나는 그것을 피하기 위해 어떻게 파서를 고려해야할지 모르겠다. 내가 쓰고있는 파서의 요점은 그 '토큰'물건들을 꺼내는 것이다. 다음은 구현 예입니다.

이것은 제작 규칙을 LL 파서로 매우 직관적으로 번역 한 것으로 보입니다. 난 어려울 것이라고 생각합니다. 인라인으로 작품을 표현하는 방법을 모르겠습니다. "임의"텍스트로되어 있지만 숨겨진 인라인을 찾자 마자 구문 분석이 중지되어야합니다.

답변

2

many을 사용하여 manyTill으로 전화를 중첩하는 것이 문제입니다. inline의 종료 조건은 endOfFile이므로 manyTill anyChar 은 모든 입력을 행복하게 소비 한 다음 성공합니다. manyTill은 첫 번째 파서 0을 번 이상 실행할 수 있으므로 inline을 계속 사용하면 성공할 수 있습니다. 그래서 파서에서 many을 사용하면 many이 무한 루프 빈 문자열 목록을 생성하는 동안 영원히 루프가됩니다. 이 동작은 역 추적을 관리 할 수 ​​ 연속 요청을 구축이 예 attoparsec에 할당의 많은 양의 아마 때문입니다

parseOnly (many (manyTill anyChar endOfInput)) $ Text.pack "" 

더 분명하다. 일반적으로, 당신은 many로 공급 파서는 하찮게 성공 수 없어야합니다 (즉, 입력 스트림의 소비없이). 그래서, 당신은 inline를 다시 작성하거나이 사건을 피하기 위해 파서 구조 조정 중 하나가 필요합니다.