A char
«потребляет» символ, если он совпадает. Так что, если мы используем char 'a'
, а следующий символ для разбора - это действительно 'a'
, мы «перемещаем курсор» на одну позицию дальше и возвращаем 'a'
.
string
, чтобы выполнить то же самое, но для списка Char
с, поэтому [Char]
или эквивалентного String
. Он делает это, глядя на String
. Если String
пусто, то ничего не нужно делать, мы можем просто вернуть пустой список (String
).
В случае, если строка содержит хотя бы один элемент, мы вызываем char c
на сначала символе этой строки, а затем мы рекурсивно на хвосте строки, в конце концов мы возвращаем (c:cs)
(строка, которую мы уже передали в качестве параметра функции string
) , Мы не принимаем во внимание результат самого синтаксического анализатора, мы просто возвращаем заданную строку, , если парсер действительно соответствует строке.
Таким образом, это делается с помощью последовательность char
вызывает, что каждая проверка действительно ли тот символ, который нам нужен, и если это так, мы продолжаем перемещать курсор и проверять следующий символ.
Если мы, таким образом, выполняем string "foo"
, это эквивалентно:
string "foo" = char 'f' >> char 'o' >> char 'o' >> return "foo"
Если, однако, в середине символ не совпадает, синтаксический анализатор не будет перемещать курсор назад. Поэтому следующий синтаксический анализ завершится неудачно:
Prelude Parsec Control.Applicative> Parsec.parse (Parsec.string "faa" <|> Parsec.string "foo") "" "foo"
Left (line 1, column 1):
unexpected "o"
expecting "faa"
Так как "faa"
пробуется первым, и это уже будет соответствовать первому символу 'f'
, что означает, что курсор переместился, передал 'f'
.