2014-10-11 5 views
1

Как бы вы могли использовать существующую функциональность FParsec для поиска повторяющегося последовательного шаблона в самом правом теге?как разобрать промежуток времени, когда право может появиться после повторяющегося шаблона?

Это законная возможность в этом контексте. Возможно предварительное разборка + экранирование, но есть ли лучшее решение? Нужно ли нам писать новый комбинатор, и если да, то на что это похоже?

#r"""bin\debug\FParsecCS.dll""" 
#r"""bin\debug\FParsec.dll""" 

open FParsec 

let str = pstring 
let phraseEscape = pchar '\\' >>. pchar '"' 
let phraseChar = phraseEscape <|> (noneOf "|\"\r\n]") // <- this right square bracket needs to be removed 
let phrase = manyChars phraseChar 

let wrapped = between (str"[[") (str"]]".>>newline) phrase 

run wrapped "[[some text]]\n" // <- works fine 

// !! problem 
run wrapped "[[array[] d]]\n" // <- that means we can't make ']' invalid in phraseChar 

// !! problem 
run wrapped "[[array[]]]\n"  // <- and this means that the first ]] gets match leaving a floating one to break the parser 
+0

@ Vesa.A.J.K: Я не определял язык, поэтому у меня нет роскоши делать что-то свое. Помимо этого случая с нечетным углом зрения, он очень читабельен и почти свободен от контекста. Некоторые из этих работ могут пробиться в FSharp.Data, но я пока не готов к этому. ти. – sgtz

ответ

1

Жаль быть отвечая на мой собственный вопрос, но ...

См наборный функцию phraseTill и ПЭНД анализатор, который передается к нему (notFollowedBy (с "]] ] ") >>. (s"]] "))

#r"""bin\debug\FParsecCS.dll""" 
#r"""bin\debug\FParsec.dll""" 

open FParsec 

let s = pstring 
let phraseChar = (noneOf "\r\n") 
let phrase = manyChars phraseChar 
/// keep eating characters until the pend parser is successful 
let phraseTill pend = manyCharsTill phraseChar pend 

/// when not followed by tipple, a double will truly be the end 
let repeatedTo repeatedPtrn ptrn = notFollowedBy(s repeatedPtrn)>>.(s ptrn) 
let wrapped = (s"[[")>>.phraseTill (repeatedTo "]]]" "]]") 
run wrapped "[[some text]]]" 
run wrapped "[[some text]]" 

NB. если вы попробуете это в FSharp Interactive (FSI), убедитесь, что у вас есть хотя бы одна строка «run wrapped», когда вы отправляете свой текст в FSI для оценки (т. е. щелкните правой кнопкой мыши «Execute In Interactive»). В этом примере тип только выводится/прикрепляется к приложению. Мы могли бы предоставить явные определения, рискуя быть более подробными.