对于一个小型编译器项目,我们目前正在为C的子集实现编译器,我们决定使用Haskell和megaparsec.总的来说,我们取得了很好的进展,但仍有一些我们无法正确处理的极端情况.其中之一是反斜杠的处理,然后换行.引用规范:
删除反斜杠字符()后面紧跟一个新行字符的每个实例,拼接物理源代码行以形成逻辑源代码行.只有任何物理源线上的最后反斜杠才有资格成为此类拼接的一部分.(§5.1.1.,ISO/IEC9899:201x)
到目前为止,我们提出了两种可能的方法来解决这个问题:
1.)实现一个前期阶段,其中再现初始输入并且每次出现都\\\n被删除.我们在这种方法中看到的最大缺点是我们丢失了我们需要的准确错误位置.
2.)实现一个特殊的char'组合器,其行为类似于char前方的额外角色并且将默默地消耗任何组合\\\n.这会给我们正确的立场.在此不利的是,我们需要更换每一个的occurence char与char'任何解析器,甚至在百万秒差距,提供的像string,integer,whitespace等...
我们很可能不是第一个尝试使用parsec/megaparsec来解析这种语法的人,所以我可以想象有一些更好的方法可以做到这一点.有没有人有想法?
我是Haskell的初学者.在尝试解决关于hackerrank的一些练习时,我偶然发现了一个错误,这让我想知道"正确的方式"(tm).
我试图做的是这样的:
import Data.Matrix
newtype Puzzle = Matrix Char
complete :: Puzzle -> Bool
complete p = '-' `elem` (toList p)
[... more functions using 'Matrix Char']
Run Code Online (Sandbox Code Playgroud)
什么给了我
Couldn't match expected type ‘Matrix Char’
with actual type ‘Puzzle’
In the first argument of ‘toList’, namely ‘p’
In the second argument of ‘elem’, namely ‘(toList p)’
Run Code Online (Sandbox Code Playgroud)
显而易见的解决方案当然只是使用Matrix Char而不是Puzzle.但我觉得这不是一个优雅的解决方案.抽象为更具体的类型感觉是正确的方式...
解决了一些练习练习,我找到了2个重新安置IO模式.第一种模式已经覆盖了方便interact.第二种模式类似,但按行处理输入.
怎么写interactLinewise方法?
我刚刚发现,RWST(从transformers)不携带一个实例MonadReader,MonadState或MonadWriter.这对我来说似乎有些奇怪,因为这些实例会立即提高可用性,例如能够使用.=,或者只是普遍提高可重用性.
当然这个决定有理由吗?