请求对简单的Alex解析器发表评论

我一直在寻找Haskell Yi编辑器的贡献代码,我想向它添加Git commit和rebase模式。 我以前从来没有和Alex做过任何事情,所以我决定在Yi之外单独编写一个提交解析器,然后再尝试添加一个到编辑器。 除了Alex页面上的文档外,我无法找到关于Alex的很多文档,这些文档对于Yi项目模拟的monad包装的信息非常轻。

任何人都可以给我评论关于这段代码有什么错误(并希望是正确的)吗? 我对Haskell很新,所以在那里的任何评论也将被赞赏。 这个想法是,这将正确处理消息行,注释和差异行(当你运行git commit -v时,这将在所有上面)。 我可能会增加对区分消化系列和后续系列的支持,但我现在想保持简单。


{
module Main where
}

%wrapper "monad"

$commitChars = [$printablet]
@diffStart = diff --git $commitChars*

gitCommit :-

 {
^@diffStart$                   {makeAlexAction DiffDeclaration `andBegin` diff}
^# $commitChars*$             {makeAlexAction Comment}
$commitChars*$                 {makeAlexAction MessageLine}
}

 {
^@diffStart$                   {makeAlexAction DiffDeclaration}
^- $commitChars*$             {makeAlexAction DiffRemove}
^+ $commitChars*$             {makeAlexAction DiffAdd}
^$commitChars*$                {makeAlexAction DiffContext}
}

.                                     ;
[nr]                                ;

{
data GitCommitToken = Digest String
                    | MessageLine String
                    | Comment String
                    | DiffDeclaration String
                    | DiffAdd String
                    | DiffRemove String
                    | DiffContext String
                    | CommitEOF
                  deriving (Show, Eq)

makeAlexAction ::Monad m => (String -> GitCommitToken) ->AlexInput ->Int ->m GitCommitToken
makeAlexAction cons =  (_,_,inp) len ->return $cons (take len inp)

alexEOF = return CommitEOF

alexMonadScanTokens ::Alex [GitCommitToken]
alexMonadScanTokens = do                                                                                 
  inp  alexEOF >>= eof ->return [eof]
    AlexError inp' ->alexError $ "lexical error: " ++ show inp'
    AlexSkip  inp' len ->do
        alexSetInput inp'
        alexMonadScanTokens
    AlexToken inp' len action ->do
        alexSetInput inp'
        token <- action inp len
        tokens <-alexMonadScanTokens
        return $ token : tokens

main = do
     s <- getContents
     mapM_ print $ either (_ -> []) id (runAlex s alexMonadScanTokens)
}

首先,感谢为Haskell和Yi的贡献!

代码审查

  • 我会使用bytestring解析。 Alex现在支持这一点。 使用%wrapper "strict-bytestring"模式。
  • either (_ -> []) id :有点奇怪。 我会使用一个明确的案例,对于解析失败有一个更好的错误。
  • 它在alexMonadScanTokens是否有空间泄漏(至少,它会消耗堆栈)。 Alex为你定义了alexScanTokens ,是对输入的一个折叠。 我想你应该使用alexMonadScan
  • 在一个沉重的解析器中,我会使用解压缩的,严格的字符串作为标记类型。 例如Digest !ByteString
  • 你的正则表达式看起来很好。
  • 总结,相当不错的先走吧! 切换到字符串解析,并尝试测试一些大文件,以确保您的扫描仪没有空间泄漏,假设您不使用开箱即用的alexScanTokens

    资源

    查看基于字符串的Alex分析器的bytestring-lexing包。 其次,alex软件包本身有很多很好的例子,可以帮助进行惯用语法分析:

      $ cabal unpack alex
      $ cd examples
    
    链接地址: http://www.djcxy.com/p/65625.html

    上一篇: Request for comments on simple Alex parser

    下一篇: style indent/dedent tokens with alex/haskell?