【问题标题】:Haskell -- parser combinators keywordsHaskell——解析器组合关键字
【发布时间】:2016-09-08 18:25:31
【问题描述】:

我正在使用解析器组合器在 Haskell 中构建解析器。我在解析“while”、“true”、“if”等关键字时遇到问题

所以我面临的问题是在关键字之后需要有分隔符或空格,例如在语句中 if cond then stat1 else stat2 fi;x = 1 使用此语句,所有关键字前面都有一个空格或分号。但是在不同的情况下可以有不同的分隔符。

目前我已经实现如下:

keyword :: String -> Parser String
keyword k = do
  kword <- leadingWS (string k)
  check (== ';') <|> check isSpace <|> check (== ',') <|> check (== ']')
  junk
  return word

然而,这个关键字解析器的问题是它会允许程序有像 if; 这样的语句。 cond 然后 stat1 else stat2 fi

我们尝试将 (Char -> Bool) 传递给关键字,然后将其传递给检查。但这行不通,因为我们在解析关键字的地方不知道允许使用哪种分隔符。

我想知道是否可以在这个问题上提供一些帮助?

【问题讨论】:

  • 仅仅因为一个关键字后跟一个分号,这并不意味着它被正确使用。关键字总是一些更大的句法结构的一部分。也就是说,关键字只是构建语法的特定标记。关键字和标识符之间的唯一区别是关键字被语法识别,而不是被视为留给后续解析和评估阶段的通用标记。
  • 分号本身就是另一个记号;您应该有另一个组合器来识别其他标记的正确集合。 (从这个意义上说,解析器实际上是在进行词法分析——将字节流转换为标记流——和解析——将标记流转换为抽象语法树。)

标签: parsing haskell parser-combinators


【解决方案1】:

不要尝试处理 keyword 中的分隔符,但您需要确保 keyword "if" 不会与标识符“iffy”混淆(参见 sepp2k 的评论)。

keyword :: String -> Parser String
keyword k = leadingWS $ try (do string k
                                notFollowedBy alphanum)

处理语句的分隔符如下:

statements = statement `sepBy` semi
statement  = ifStatement <|> assignmentStatement <|> ...

【讨论】:

  • 如果你这样做,标识符“iffy”可以被解析为关键字“if”,后跟标识符“fy”。我相信(我承认我完全在猜测)OP 决定“在关键字之后需要有分隔符或空格”的原因是不允许这样做。
  • 哦,我明白了,也许我错过了问题中的这一点。如果我有什么要补充的,我会考虑一下并更新我的答案。
猜你喜欢
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-27
  • 1970-01-01
  • 2017-09-07
  • 2012-08-28
相关资源
最近更新 更多