2013-01-11 2 views

답변

13

구현 세부 사항입니다. string 파서가 성공할 수있는 입력이 충분한 지 여부를 알기 전에 파서가 완료되지 않습니다. 이 구문 분석기의 전부 또는 일부 동작 (결과적으로 일반적으로 좋다고 생각합니다)의 결과입니다.

string :: Text -> Parser Text 
string s = takeWith (T.length s) (==s) 

string s

Textlength s 유닛을 다음 s과 비교하려고합니다.

takeWith :: Int -> (Text -> Bool) -> Parser Text 
takeWith n p = do 
    s <- ensure n 
    let h = unsafeTake n s 
     t = unsafeDrop n s 
    if p h 
    then put t >> return h 
    else fail "takeWith" 

takeWith n p 첫 번째 시도는 Textn 단위를 사용할 수 있는지 확인하고,

ensure :: Int -> Parser Text 
ensure !n = T.Parser $ \i0 a0 m0 kf ks -> 
    if lengthAtLeast (unI i0) n 
    then ks i0 a0 m0 (unI i0) 
    else runParser (demandInput >> go n) i0 a0 m0 kf ks 
    where 
    go n' = T.Parser $ \i0 a0 m0 kf ks -> 
     if lengthAtLeast (unI i0) n' 
     then ks i0 a0 m0 (unI i0) 
     else runParser (demandInput >> go n') i0 a0 m0 kf ks 

ensure n는 찾을 수없는 경우 (A Partial 결과) 더 입력을 요구 연속을 만듭니다 충분한 입력 즉시.

당신은

Prelude Data.Attoparsec.Text Data.Text> parseOnly (string (pack "module")) (pack "mox") 
Left "not enough input" 

이 더 이상 입력 (다음 ensure에서 demandInput가 실패한다) 얻을, 이상

Prelude Data.Attoparsec.Text Data.Text> parse (string (pack "module")) (pack "mox") 
Partial _ 
Prelude Data.Attoparsec.Text Data.Text> feed it (pack "") 
Fail "mox" ["demandInput"] "not enough input" 
하지 않습니다 앞까지 파서 이야기와 실패를 얻을 수 있습니다

Partial 결과를 말하면 공백으로 먹이십시오. Text.

+0

감사의 말 - 설명 후에 이해해주십시오. – timbod