indents-0.5.0.1: indentation sensitive parser-combinators for parsec

Safe HaskellSafe
LanguageHaskell98

Text.Parsec.Indent.Explicit

Contents

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

data Indentation Source #

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

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

indented Source #

Arguments

:: (Monad m, Stream s m z) 
=> Indentation

Reference indentation

-> ParsecT s u m () 

Parses only when indented past the level of the reference

sameOrIndented Source #

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

same Source #

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

checkIndent Source #

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.