1

我想为主题标签编写一个解析器。我一直在阅读 opa 博客上有关解析的博客条目,但它们并没有涵盖很多递归解析器和列表的构造。

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

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

解析将导致["Opa", "lovely", "Haskell"].

我已经尝试过这样做,但这并不是我想要的。(它要么只能解析一个主题标签而不能解析其他任何东西,要么在无限循环中失败,要么因为输入它不理解而失败......)此外,这是一个实现它的Haskell 版本。

4

2 回答 2

2

首先说一句:通过用 Haskell 术语提出问题,您实际上是在寻找了解 OpaHaskell 的人,因此减少了找到回答问题的人的机会;)。好的,我半开玩笑地说,因为您的评论有很大帮助,但我仍然希望看到用简单的英语表达的问题。

我认为保持 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

我怀疑您需要微调此解决方案以真正符合您的要求,但它应该会给您一个良好的开端(我希望)。

于 2011-11-24T12:15:56.343 回答
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 ")}")
于 2011-12-23T19:46:25.007 回答