miso
Copyright(C) 2016-2026 David M. Johnson
LicenseBSD3-style (see the file LICENSE)
MaintainerDavid M. Johnson <code@dmj.io>
Stabilityexperimental
Portabilitynon-portable
Safe HaskellSafe-Inferred
LanguageHaskell2010

Miso.Util.Lexer

Description

Overview

Miso.Util.Lexer is an internal lexer combinator library used by miso's JSON pipeline (Miso.JSON.Lexer) and URI/router tokeniser (Miso.Router). It is not designed for general application use, but is exposed for downstream code that needs to build custom lexers.

The central type is Lexer:

newtype Lexer token = Lexer
  { runLexer :: Stream -> Either LexerError (token, Stream) }

Lexer is a Monad, Alternative, and MonadFail. Its Alternative instance implements the maximal munch rule: when both branches succeed, the one that consumes the most input wins.

Key types

  • Stream — the remaining input text together with a Location (line and column) cursor.
  • Location{line :: Int, column :: (Int, Int)}, used in error messages and Located tokens.
  • Located token — a lexed value paired with the Location at which it was recognised.
  • LexerError — either LexerError MisoString Location (unexpected input) or UnexpectedEOF Location (ran out of input).

Primitive combinators

satisfy  :: (Char -> Bool) -> Lexer Char   -- consume one matching char
char     :: Char -> Lexer Char              -- consume a specific char
string   :: MisoString -> Lexer MisoString   -- consume a literal prefix
string'  :: String -> Lexer String          -- same for String
peek     :: Lexer (Maybe Char)              -- look ahead without consuming
oops     :: Lexer token                     -- always fails

Stream and location access

getInput     :: Lexer Stream
putInput     :: Stream -> Lexer ()
modifyInput  :: (Stream -> Stream) -> Lexer ()
getLocation  :: Lexer Location
setLocation  :: Location -> Lexer ()

Running a lexer

runLexer :: Lexer token -> Stream -> Either LexerError (token, Stream)
mkStream :: MisoString -> Stream   -- create initial stream

See also

Synopsis

Types

newtype Lexer token Source #

A Lexer is a state monad with optional failure the abides by the maximal munch rule in its Alternative instance.

Constructors

Lexer 

Fields

Instances

Instances details
Alternative Lexer Source # 
Instance details

Defined in Miso.Util.Lexer

Methods

empty :: Lexer a #

(<|>) :: Lexer a -> Lexer a -> Lexer a #

some :: Lexer a -> Lexer [a] #

many :: Lexer a -> Lexer [a] #

Applicative Lexer Source # 
Instance details

Defined in Miso.Util.Lexer

Methods

pure :: a -> Lexer a #

(<*>) :: Lexer (a -> b) -> Lexer a -> Lexer b #

liftA2 :: (a -> b -> c) -> Lexer a -> Lexer b -> Lexer c #

(*>) :: Lexer a -> Lexer b -> Lexer b #

(<*) :: Lexer a -> Lexer b -> Lexer a #

Functor Lexer Source # 
Instance details

Defined in Miso.Util.Lexer

Methods

fmap :: (a -> b) -> Lexer a -> Lexer b #

(<$) :: a -> Lexer b -> Lexer a #

Monad Lexer Source # 
Instance details

Defined in Miso.Util.Lexer

Methods

(>>=) :: Lexer a -> (a -> Lexer b) -> Lexer b #

(>>) :: Lexer a -> Lexer b -> Lexer b #

return :: a -> Lexer a #

MonadPlus Lexer Source # 
Instance details

Defined in Miso.Util.Lexer

Methods

mzero :: Lexer a #

mplus :: Lexer a -> Lexer a -> Lexer a #

MonadFail Lexer Source # 
Instance details

Defined in Miso.Util.Lexer

Methods

fail :: String -> Lexer a #

data Stream Source #

A Stream of text used as input to lexing

Constructors

Stream 

Fields

Instances

Instances details
Eq Stream Source # 
Instance details

Defined in Miso.Util.Lexer

Methods

(==) :: Stream -> Stream -> Bool #

(/=) :: Stream -> Stream -> Bool #

data Located token Source #

A Located token holds the lexed output the Location at which the successful lex occurred.

Constructors

Located 

Fields

Instances

Instances details
Show token => Show (Located token) Source # 
Instance details

Defined in Miso.Util.Lexer

Methods

showsPrec :: Int -> Located token -> ShowS #

show :: Located token -> String #

showList :: [Located token] -> ShowS #

Eq token => Eq (Located token) Source # 
Instance details

Defined in Miso.Util.Lexer

Methods

(==) :: Located token -> Located token -> Bool #

(/=) :: Located token -> Located token -> Bool #

data Location Source #

Type to hold the location (line and column) of a Token

Constructors

Location 

Fields

  • line :: Int

    Current line number (1-based)

  • column :: (Int, Int)

    (start, end) column offsets for the current token (1-based)

Instances

Instances details
Show Location Source # 
Instance details

Defined in Miso.Util.Lexer

Eq Location Source # 
Instance details

Defined in Miso.Util.Lexer

data LexerError Source #

Potential errors during lexing

Instances

Instances details
Show LexerError Source # 
Instance details

Defined in Miso.Util.Lexer

Eq LexerError Source # 
Instance details

Defined in Miso.Util.Lexer

Combinators

getStartColumn :: Location -> Int Source #

Helper for extracting column from Location

mkStream Source #

Arguments

:: MisoString

Input text to lex

-> Stream 

Smart constructor for Stream

oops :: Lexer token Source #

Combinator that always fails to lex

streamError Source #

Arguments

:: Stream

The stream at the point of failure; used to populate the error location

-> LexerError 

Smart constructor for LexerError

string Source #

Arguments

:: MisoString

Literal string prefix to consume from the input

-> Lexer MisoString 

Lexer combinator for matching a MisoString

string' Source #

Arguments

:: String

Literal string prefix to consume character by character

-> Lexer String 

Lexer combinator for matching a String

char Source #

Arguments

:: Char

The exact character to consume

-> Lexer Char 

Lexer combinator for matching a Char

satisfy Source #

Arguments

:: (Char -> Bool)

Predicate; the next character is consumed only if this returns True

-> Lexer Char 

Predicate combinator that consumes matching input

peek :: Lexer (Maybe Char) Source #

Fetches the first character in the Stream, does not consume input

getInput :: Lexer Stream Source #

Retrieves current input from Lexer

putInput Source #

Arguments

:: Stream

Replacement stream; replaces the current lexer input

-> Lexer () 

Overrides current Stream in Lexer to user-specified Stream.

getLocation :: Lexer Location Source #

Retrieves the current Stream Location

setLocation Source #

Arguments

:: Location

New location to record in the stream cursor

-> Lexer () 

Sets the current Stream Location

modifyInput Source #

Arguments

:: (Stream -> Stream)

Transform to apply to the current lexer input

-> Lexer () 

Modifies a Stream

withLocation Source #

Arguments

:: ToMisoString token 
=> Lexer token

Inner lexer whose result is wrapped with its source Location

-> Lexer (Located token) 

Lexer combinator for executing a Lexer with annotated Location information