Рекурсивный анализатор построения списков в Opa
Я хотел бы написать парсер для хэштегов. Я читал записи блога о разборе в опа-блоге, но они не охватывали рекурсивные парсеры и конструкции списков.
Хештеги используются некоторыми социальными сетями (Twitter, Diaspora*), чтобы пометить сообщение. Они состоят из знака хеша (#
) и буквенно-цифровая строка, такая как "интересно" или "смешно". Один пример публикации с использованием хэштегов:
Oh #Opa, you're so #lovely! (Are you a relative of #Haskell?)
Разбор, который приведет к ["Opa", "lovely", "Haskell"]
,
Я пытался сделать это, но это не совсем то, что я хочу. (Он может анализировать только один хэш-тег и ничего больше, может потерпеть неудачу в бесконечном цикле или потерпит неудачу, потому что был ввод, который он не понимал...) Кроме того, здесь есть версия на Haskell, которая его реализует.
2 ответа
Начнем с замечания: излагая вопрос в терминах языка Haskell, вы эффективно ищете кого-то, кто знает Opa и Haskell, следовательно, уменьшая шансы найти человека, который ответит на вопрос;). Хорошо, я говорю это наполовину в шутку, так как ваши комментарии очень помогают, но все же я бы предпочел, чтобы вопрос был сформулирован на простом английском языке.
Я думаю, что решение, сохраняющее структуру Хаскелла, будет примерно таким:
parse_tags =
hashtag = parser "#" tag=Rule.alphanum_string -> tag
notag = parser (!"#" .)* -> void
Rule.parse_list_sep(true, hashtag, notag)
Вероятно, главный "трюк" заключается в использовании Rule.parse_list_sep
функция для разбора списка. Я предлагаю вам взглянуть на реализацию некоторых функций в Rule
модуль, чтобы получить вдохновение и узнать больше о разборе в Opa.
Конечно, я предлагаю протестировать эту функцию, например, с помощью следующего кода:
_ =
test(s) =
res =
match Parser.try_parse(parse_tags, s) with
| {none} -> "FAILURE"
| {some=tags} -> "{tags}"
println("Parsing '{s}' -> {res}")
do test("#123 #test #this-is-not-a-single-tag, #lastone")
do test("#how#about#this?")
void
который даст следующий вывод:
Parsing '#123 #test #this-is-not-a-single-tag, #lastone' -> [123, test, this, lastone]
Parsing '#how#about#this?' -> FAILURE
Я подозреваю, что вам нужно будет настроить это решение, чтобы оно действительно соответствовало тому, что вы хотите, но оно должно дать вам хороший старт (я надеюсь).
Следующая работа, просто с использованием простых парсеров
hashtag = parser "#" tag=Rule.alphanum_string -> tag
list_tag = parser
| l=((!"#" .)* hashtag -> hashtag)* .* -> l
parsetag(s) = Parser.parse(list_tag, s)
do println("{parsetag("")}")
do println("{parsetag("aaabbb")}")
do println("{parsetag(" #tag1 #tag2")}")
do println("{parsetag("#tag1 #tag2 ")}")
do println("{parsetag("#tag1#tag2 ")}")