如何使用 megaparsec 获取 AST 节点的源范围?
How to get source range of AST nodes using megaparsec?
我正在尝试为我正在解析的某个源文件生成一个源映射,我想获取每个节点的范围。 getSourcePos only gives the start position 个节点 (src:line:column)。如何得到它的结束位置?
如果你想为每个词位构建这样的源跨度:
data Span = Span SourcePos SourcePos
data Spanned a = Spanned Span a
你可以只调用 getSourcePos
两次,一次在标记的开头,一次在结尾,在消耗任何空格之前,假设你处于词法分析阶段。我过去使用过这样的结构来使这更方便:
-- Augment a parser with a source span.
spanned :: Parser (a, SourcePos) -> Parser (Spanned a)
spanned parser = do
start <- getSourcePos
(x, end) <- parser
pure (Spanned (Span start end) x)
-- Consume whitespace following a lexeme, but record
-- its endpoint as being before the whitespace.
lexeme :: Parser a -> Parser (a, SourcePos)
lexeme parser = (,) <$> parser <*> (getSourcePos <* whitespace)
请记住,根据文档,getSourcePos
有点贵,如果我没记错的话,这取决于源文件的大小。
如果 AST 用跨度注释,你可以计算树的任何部分的跨度,方法是用 Span
的幺半群实例折叠它,它采用它们的并集(或更具体地说是它们的边界框) ,即 a <> b
是从 (beginRow a, beginCol a) `min` (beginRow b, beginCol b)
到 (endRow a, endCol a) `max` (endRow b, endCol b)
的范围。
我正在尝试为我正在解析的某个源文件生成一个源映射,我想获取每个节点的范围。 getSourcePos only gives the start position 个节点 (src:line:column)。如何得到它的结束位置?
如果你想为每个词位构建这样的源跨度:
data Span = Span SourcePos SourcePos
data Spanned a = Spanned Span a
你可以只调用 getSourcePos
两次,一次在标记的开头,一次在结尾,在消耗任何空格之前,假设你处于词法分析阶段。我过去使用过这样的结构来使这更方便:
-- Augment a parser with a source span.
spanned :: Parser (a, SourcePos) -> Parser (Spanned a)
spanned parser = do
start <- getSourcePos
(x, end) <- parser
pure (Spanned (Span start end) x)
-- Consume whitespace following a lexeme, but record
-- its endpoint as being before the whitespace.
lexeme :: Parser a -> Parser (a, SourcePos)
lexeme parser = (,) <$> parser <*> (getSourcePos <* whitespace)
请记住,根据文档,getSourcePos
有点贵,如果我没记错的话,这取决于源文件的大小。
如果 AST 用跨度注释,你可以计算树的任何部分的跨度,方法是用 Span
的幺半群实例折叠它,它采用它们的并集(或更具体地说是它们的边界框) ,即 a <> b
是从 (beginRow a, beginCol a) `min` (beginRow b, beginCol b)
到 (endRow a, endCol a) `max` (endRow b, endCol b)
的范围。