2016-11-03 1 views
3

주어진이 제대로 마지막을 제외한 다음의 모든 일치옵션 인 후행 쉼표는 어떻게 처리합니까?

let maxCount = System.Int32.MaxValue 
let pmlcomment = pstring "/*" >>. skipCharsTillString "*/" true (maxCount) 
let ws = pspaces >>. many (pspaces >>. pmlcomment .>> pspaces) |>> (function | [] ->() | _ ->()) 
let str_ws s = pstring s .>> ws 
let exprBraceSeqOpt p = 
    let trailingComma = (str_ws "," |>> fun _ -> None) 
    between (str_ws "{") (str_ws "}") ((opt (attempt (sepBy p (str_ws ",")))) <|> (attempt trailingComma)) 
let sampleP = exprBraceSeqOpt (str_ws "x") 

다음 주 또는 무언가를 바꾸고 내가 뭔가를 추측하고있어

["{}";"{x}";"{x,x}";"{x,x,}"] 

합니다.

fparsec에 옵션 인 후행 쉼표는 어떻게 처리합니까?

+0

아마도'opt (시도 trailingComma)'여야할까요? – Yawar

+0

아니, 컴파일하지 않는다 – Maslow

답변

4

sepBy "있는 경우"여분의 분리 기호를 "먹습니다". 그게 어떻게 작동하는지, 기간. attempt을 여러 위치에 적용하여 해킹 할 수 없습니다. attempt을 구분 기호에 적용하면 마지막 구분 기호가 실제로 성공하므로 유용하지 않으므로 attempt은 아무 효과가 없습니다. 그리고 전체 sepByattempt을 적용하면 도움이되지 않습니다. 그 이유는 전체 sepBy이 마지막 분리 기호가 아니라 롤백되기 때문입니다. 원하는 후행 쉼표 동작을 달성하면서 "x"파서 자체에 attempt을 적용하면 파서가 여러 쉼표를 연속적으로 받아들이도록 만드는 부작용이 생깁니다.

그리고 결합자를 영리하게 사용하여 원하는 결과를 얻는 것이 불가능하기 때문에 실제로는 후속 조치를 수행하는 특별한 기능이 있습니다 (sepEndBy). 원하는대로이 작동 할

:

또한
let exprBraceSeqOpt p = 
    between (str_ws "{") (str_ws "}") (sepEndBy p (str_ws ",")) 

, 여담으로, 나는 function | [] ->() | _ ->()ignore을 할 수있는 상당히 정교한 방법이라고 지적한다. :-)

+1

아주 좋은 정보. 무시에 관해서는 ... 나는 이것을 일반적인 소비를 위해 제대로 처리하지 못했고, 실제 코드에는 거기에 것들이있다. =) – Maslow

관련 문제