2012-05-06 43 views
1

用Parsec轻松获得仓位作为补偿(作为输入开始的字符)吗?如果是这样,怎么样?内部Parsec将该位置保持为具有源名称,行和列的数据类型。Parsec仓位作为补偿

我希望能够写一个解析器像

pWithPos p = do left <- getPosition  -- gets the current position as an offset 
       x <- p 
       right <- getPosition  -- gets the current position as an offset 
       return (x,(left,right)) 

使用的解析器P,其解析的东西,并返回其结果,以及其左,右位置偏移

alex(词法分析器生成器)例如句柄positions保持绝对字符偏移量,行号和列号。我缺少parsec中的绝对字符偏移量。

+0

偏移? parsec已经告诉你从0开始的行偏移以及从0开始的列偏移。从文件的开头偏移字符? –

+0

@DonStewart我想从输入开始的字符偏移量。 – Romildo

回答

1

您可以使用此功能来计算偏移,给定输入字符串和SourcePos:从什么

offset :: String -> SourcePos -> Maybe Location 
offset source pos = elemIndex pos positions 
    where positions = scanl updatePosChar firstPos source 
     firstPos = initialPos (sourceName pos) 
+0

这实际上是完整输入大小的O(n),还是我错过了一些让它更高效运行的东西?我会担心在任何规律性的解析器中调用它。由于updatePosChar的工作方式,它看起来像这样会将选项卡计为1(或0?)和8之间的一些不可预知的值: – rcreswick

1

不,不可能在Parsec中获取当前字符串索引,因为Parsec不会跟踪该索引。您可以在状态monad上使用monad变换器,并手动跟踪解析的索引。

+1

那有多难?我想有些原语必须重新定义,对吧? – Romildo

+0

这将是非常困难的;你必须基本上重新定义每一个基元和依赖于这些基元的一切。没有“解析器状态类型”,它有一个你可以替换的函数。我建议重新定义依赖于字符串索引信息的逻辑。无论如何你需要什么信息? – dflemstr

+0

例如,您可以创建一个将'(Line,Column)'和输入字符串转换为索引的函数。如果你愿意,我可以告诉你如何构建该功能。 – dflemstr