Opa中的递归列表构造解析器

时间:2011-11-23 12:39:06

标签: parsing recursion opa

我想为hashtags写一个解析器。我一直在看博客 关于在opa博客上解析的条目,但它们没有涵盖递归 解析器和列表的构造很多。

某些社交网络(Twitter,Diaspora *)使用了Hashtags 标记帖子。它们由井号(#)和字母数字组成 字符串,如“有趣”或“有趣”。帖子使用的一个例子 主题标签:

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

解析会导致["Opa", "lovely", "Haskell"]

我有tried to do it,但它并不是我想要的。 (它可能 要么只解析一个标签而没有别的,就会无休止地失败 循环或失败,因为有输入它不明白...) 另外,这是一个实现它的Haskell version

2 个答案:

答案 0 :(得分:2)

首先要说一句:通过用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函数来解析列表。我建议您查看implementation of some functions模块中的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

我怀疑你需要微调这个解决方案才能真正符合你想要的但是它应该给你一个良好的开端(我希望)。

答案 1 :(得分:0)

以下工作,只使用普通解析器

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