我该如何对Alex的代码进行单元测试?

3

我正在使用monad封装的Alex编写词法分析器。它的表现不像我期望的那样,因此我想为其编写一些单元测试。我可以通过以下方式编写单元测试来对单个标记进行词法分析:

runAlex "foo" alexMonadScan `shouldBe` Right TokenFoo

但我不知道如何测试字符串“foo bar”被词法分析为[TokenFoo,TokenBar]

假设Token是我的标记类型,我需要一个像runAlex这样的函数,其类型为String -> Alex [Token] -> Either String [Token],但我不知道如何将alexMonadScan转换为具有类型Alex [Token]而不是Alex Token

我尝试过

runAlex "foo bar" (liftM (:[]) alexMonadScan) `shouldBe` [TokenFoo, TokenBar]

这个问题似乎选择了正确的类型,但返回了Right [TokenEOF],显然丢失了它沿途看到的标记。

我该如何解决这个问题?


3
请不要对我进行单元测试,这会让我感到不舒服。 - user932887
1
@AlexM,为什么?你有什么需要隐藏的吗? - Shoe
@ʎǝɹɟɟɟǝſ 这不是那样的。 - user932887
1个回答

4

有一个函数alexScanTokens :: String -> [token]可以使用。

它定义在文件templates/wrappers.hs中。

这是我在这里找到的一种单子版本:

alexScanTokens :: String -> Either String [Keyword]
alexScanTokens inp = runAlex inp gather
  where
  gather = do
    t <- alexMonadScan
    case trace (show t) t of
      EOF -> return [EOF]
      _   -> (t:) `liftM` gather

那个能和单子包装一起使用吗?我之前的印象是它只能用于基本包装。当我尝试使用它时,出现了“未在范围内:alexScanTokens”的错误提示。 - Patrick Collins
1
答案已更新。要使 alexScanTokens 在作用域内,您需要定义 ALEX_BASICALEX_BASIC_BYTESTRING 或另一个 ALEX_... 符号之一。请参见此处 - ErikR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接