Haskell Alex - 包装模板中的错误

2023-12-23

我正在尝试总体理解 Alex 和词法分析器,但我在运行我的词法分析器时遇到困难。

我在“basic”和“posn”包装器中编写了词法分析器,但在“monad”包装器中却不能。我想我必须使用monad包装器,因为我需要收集输入中的字符串和标记位置。我还需要多个状态。现在我正在尝试运行这个简单的例子:

{
module Main (main) where
}

%wrapper "monad"

$whitespace = [\ \b\t\n\f\v\r]
$digit      = 0-9
$alpha      = [a-zA-Z_]
$upper      = [A-Z]
$lower      = [a-z]

@tidentifier = $upper($alpha|_|$digit)*
@identifier  = $lower($alpha|_|$digit)*


tokens :-

$whitespace+ ;
$upper $alpha+ { typeId }
$lower $alpha+ { id_ }
$digit+ { int }

{

data Lexeme = L AlexPosn LexemeClass String

data LexemeClass
        = TypeId String
        | Id String
        | Int Int
        | EOF
    deriving (Show, Eq)

typeId :: AlexInput -> Int -> Alex Lexeme
typeId = undefined

id_ :: AlexInput -> Int -> Alex Lexeme
id_ = undefined

int :: AlexInput -> Int -> Alex Lexeme
int = undefined

alexEOF = return (L undefined EOF "")

main :: IO ()
main = do
    s <- getContents
    let r = runAlex s $ do
                return alexMonadScan
    print r
}

我的行动是undefined目前。当我尝试编译它时,我收到此错误:

➜  haskell  ghc --make Tokens.hs
[1 of 1] Compiling Main             ( Tokens.hs, Tokens.o )

templates/wrappers.hs:208:17:
    Couldn't match expected type `(AlexPosn, Char, [Byte], String)'
                with actual type `(t0, t1, t2)'
    Expected type: AlexInput
      Actual type: (t0, t1, t2)
    In the return type of a call of `ignorePendingBytes'
    In the first argument of `action', namely
      `(ignorePendingBytes inp)'

当我尝试编译 Alex 的 github 存储库中的示例时,我也遇到了各种错误,这是否与版本不匹配有关?我已经使用 ghc 7.0.4 安装了 cabal 的 alex。有任何想法吗?


This looks like a bug in Alex 3.0.1. It works fine in version 2.3.3 after dealing with some other unrelated issues in your code1. The problem is this line in the generated code:

ignorePendingBytes (p,c,ps,s) = (p,c,s)

通过跟踪生成代码中的类型,该函数似乎应该具有以下类型AlexInput -> AlexInput, but AlexInput显然不能同时是 3 元组和 4 元组。

这可能发生是因为定义AlexInput两个版本之间发生了变化。

type AlexInput = (AlexPosn, Char, String)         -- v2.3.3
type AlexInput = (AlexPosn, Char, [Byte], String) -- v3.0.1

据我所知,正确的代码应该是

ignorePendingBytes (p,c,ps,s) = (p,c,[],s)

并在生成的代码中手动进行此更改,使其在处理其他问题后进行编译。

但是,除非您需要 3.0.1 中的某些内容,否则我建议降级直到该问题得到解决,因为必须针对生成的代码维护补丁通常会带来麻烦而不值得。

1 Your code is missing a Show instance for Lexeme and you're also calling return on alexMonadScan, which is already in the Alex monad.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Haskell Alex - 包装模板中的错误 的相关文章

随机推荐