Рекурсивный анализатор построения списков в Opa - PullRequest
1 голос
/ 23 ноября 2011

Я хотел бы написать парсер для хэштегов.Я читал записи блога о разборе в опа-блоге, но они не охватывали рекурсивные парсеры и конструкции списков.

Хештеги используются некоторыми социальными сетями (Twitter, Diaspora *) для теговПочта.Они состоят из знака хеша (#) и буквенно-цифровой строки, такой как «интересно» или «смешно».Один пример поста, использующего хэштеги:

Oh #Opa, you're so #lovely! (Are you a relative of #Haskell?)

Разбор, который привел бы к ["Opa", "lovely", "Haskell"].

Я попытался сделать это , но это не такименно то, что я хочу.(Он может анализировать только один хэш-тег и ничего больше, может потерпеть неудачу в бесконечном цикле или потерпит неудачу, потому что был ввод, который он не понимал ...) Кроме того, здесь есть версия Haskell , которая его реализует.

Ответы [ 2 ]

2 голосов
/ 24 ноября 2011

Начнем с замечания: излагая вопрос в терминах языка Haskell, вы фактически ищете кого-то, кто знает Opa и Haskell, следовательно, уменьшая шансы найти человека для ответа на вопрос; Хорошо, я говорю это наполовину в шутку, так как ваши комментарии очень помогают, но все же я бы предпочел, чтобы вопрос был сформулирован на простом английском языке.

Я думаю, что решение, сохраняющее структуру 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

Я подозреваю, что вам нужно будет настроить это решение, чтобы оно действительно соответствовало тому, что вы хотите, но оно должно дать вам хороший старт (надеюсь).

0 голосов
/ 23 декабря 2011

Следующая работа, только с использованием простых парсеров

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 ")}")
...