indents-0.5.0.1: indentation sensitive parser-combinators for parsec

Text.Parsec.Indent.Explicit

Description

# Introduction

The Indent module provides an implicit indentation parser. For complex parsers split over many functions, this requires a good understanding from the programmer which indentation is being referenced.

This module fixes that problem by explicitly passing around indentation as a first-class value. This commonly makes complex parsers less concise but easier to understand.

# The problem with reference indentation

Many functions from that module (indented, checkIndent, sameOrIndented...) use a reference indentation. This reference indentation is stored in the IndentParserT type. It can be set by calling withPos, but also by other functions such as block.

Consider the following code snippet:

import qualified Text.Parsec.Indent as I

p = I.withPos $do foo I.block$ I.checkIndent >> bar

I.checkIndent, in this case, will always succeed, since we are comparing the current indentation to the implicit reference indentation set by I.block, not by I.withPos, and there is no way to do the latter.

# Explicit indentation

This module makes indentation first-class rather than implicit, so we can provide a good implementation without relying on withPos:

import qualified Text.Parsec.Indent as I
import qualified Text.Parsec.Indent.Explicit as EI

p = do
indentation <- EI.indentation
foo
I.block \$ EI.checkIndent indentation >> bar

In order to preserve backwards-compatibility, the names in this module are chosen to match their counterparts in Text.Parsec.Indent.

Synopsis

# Indentation type

We use our own position type that doesn't require a SourceName.

Instances
 Source # Instance detailsDefined in Text.Parsec.Indent.Internal MethodsshowList :: [Indentation] -> ShowS #

# Obtaining a reference implementation

indentation :: Monad m => ParsecT s u m Indentation Source #

Obtain the current indentation, to be used as a reference later.

# Indentation-based parser combinators

Arguments

 :: (Monad m, Stream s m z) => Indentation Reference indentation -> ParsecT s u m ()

Parses only when indented past the level of the reference

Arguments

 :: (Monad m, Stream s m z) => Indentation Reference indentation -> ParsecT s u m ()

Parses only when indented past the level of the reference or on the same line

Arguments

 :: (Monad m, Stream s m z) => Indentation Reference indentation -> ParsecT s u m ()

Parses only on the same line as the reference

block :: (Monad m, Stream s m z) => ParsecT s u m a -> ParsecT s u m [a] Source #

Parses a block of lines at the same indentation level starting at the current position

Arguments

 :: (Monad m, Stream s m z) => Indentation Reference indentation -> ParsecT s u m ()

Ensures the current indentation level matches that of the reference

topLevel :: (Monad m, Stream s m z) => ParsecT s u m () Source #

Ensures that there is no indentation.

notTopLevel :: (Monad m, Stream s m z) => ParsecT s u m () Source #

Ensures that there is at least some indentation.