Haskell - парсек парсинг <p>элемент - PullRequest
2 голосов
/ 29 апреля 2010

Я использую Text.ParserCombinators.Parsec и Text.XHtml для синтаксического анализа ввода:

This is the first paragraph example\n
with two lines\n
\n
And this is the second paragraph\n

И мой вывод должен быть:

<p>This is the first paragraph example\n with two lines\n</p> <p>And this is the second paragraph\n</p>

Я определил:


line= do{
        ;t<-manyTill (anyChar) newline
        ;return t
        }

paragraph = do{
        t<-many1 (line) 
        ;return ( p << t )
    }

Но возвращается:

<p>This is the first paragraph example\n with two lines\n\n And this is the second paragraph\n</p>

Что не так? Есть идеи?

Спасибо!

Ответы [ 2 ]

4 голосов
/ 29 апреля 2010

Из документации для manyTill , он запускает первый аргумент ноль или более раз , поэтому 2 новых строки в строке все еще действительны, и ваш line синтаксический анализатор не потерпит неудачу.

Возможно, вы ищете что-то вроде many1Till (например, many1 против many), но, похоже, его нет в библиотеке Parsec, поэтому вам, возможно, придется свернуть свое собственное: (предупреждение: I у меня нет ghc на этой машине, так что это полностью не проверено)

many1Till p end = do
    first <- p
    rest  <- p `manyTill` end
    return (first : rest)

или более краткий путь:

many1Till p end = liftM2 (:) p (p `manyTill` end)
1 голос
/ 29 апреля 2010

Комбинатор manyTill соответствует нулю или более вхождений его первого аргумента , согласно документации, поэтому line с радостью примет пустую строку, что означает, что many1 line будет потреблять все до последнего символа новой строки в файле, вместо того, чтобы останавливаться на двойном переводе строки, как вы и предполагали.

...