包装模板中的错误
我试图理解亚历克斯和词法分析器,但是我无法运行词法分析器。
我写了“基本”和“封装”封装的词法分析器,但是我不能使用“monad”封装。 我想我必须使用monad
包装器,因为我需要在输入中收集字符串和标记位置。 我也需要多个国家。 现在我试图运行这个简单的例子:
{
module Main (main) where
}
%wrapper "monad"
$whitespace = [ btnfvr]
$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 repo中编译示例时,我也遇到各种错误,它是否可能与版本不匹配有关? 我已经用ghc 7.0.4安装了cab的alex。 有任何想法吗?
这看起来像Alex 3.0.1中的一个错误。 在处理代码1中的其他不相关的问题之后,它在2.3.3版本中可以正常工作。 问题是生成的代码中的这一行:
ignorePendingBytes (p,c,ps,s) = (p,c,s)
通过跟随生成的代码中的类型,似乎这个函数应该具有类型AlexInput -> AlexInput
,但是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您的代码缺少Lexeme
的Show
实例,并且您还在alexMonadScan
上调用了return
alexMonadScan
,该值已在Alex
monad中。