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

How can I unit test Alex code?

我正在使用 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]

这似乎有正确的类型,但它 returns Right [TokenEOF],显然丢弃了它在途中看到的标记。

我怎样才能做到这一点?

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

在文件中定义templates/wrappers.hs

这是我找到的一个 monadic 版本 here:

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