megaparsec-9.3.1: Text/Megaparsec/Lexer.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE Safe #-}
-- |
-- Module : Text.Megaparsec.Common
-- Copyright : © 2018–present Megaparsec contributors
-- License : FreeBSD
--
-- Maintainer : Mark Karpov <markkarpov92@gmail.com>
-- Stability : experimental
-- Portability : portable
--
-- Common token combinators. This module is not public, the functions from
-- it are re-exported in "Text.Megaparsec.Byte" and "Text.Megaparsec.Char".
--
-- @since 7.0.0
module Text.Megaparsec.Lexer
( -- * White space
space,
lexeme,
symbol,
symbol',
)
where
import qualified Data.CaseInsensitive as CI
import Text.Megaparsec
import Text.Megaparsec.Common
----------------------------------------------------------------------------
-- White space
-- | @'space' sc lineComment blockComment@ produces a parser that can parse
-- white space in general. It's expected that you create such a parser once
-- and pass it to other functions in this module as needed (when you see
-- @spaceConsumer@ in documentation, usually it means that something like
-- 'space' is expected there).
--
-- @sc@ is used to parse blocks of space characters. You can use
-- 'Text.Megaparsec.Char.space1' from "Text.Megaparsec.Char" for this
-- purpose as well as your own parser (if you don't want to automatically
-- consume newlines, for example). Make sure that the parser does not
-- succeed on the empty input though. In an earlier version of the library
-- 'Text.Megaparsec.Char.spaceChar' was recommended, but now parsers based
-- on 'takeWhile1P' are preferred because of their speed.
--
-- @lineComment@ is used to parse line comments. You can use
-- @skipLineComment@ if you don't need anything special.
--
-- @blockComment@ is used to parse block (multi-line) comments. You can use
-- @skipBlockComment@ or @skipBlockCommentNested@ if you don't need anything
-- special.
--
-- If you don't want to allow a kind of comment, simply pass 'empty' which
-- will fail instantly when parsing of that sort of comment is attempted and
-- 'space' will just move on or finish depending on whether there is more
-- white space for it to consume.
space ::
(MonadParsec e s m) =>
-- | A parser for space characters which does not accept empty
-- input (e.g. 'Text.Megaparsec.Char.space1')
m () ->
-- | A parser for a line comment (e.g. 'skipLineComment')
m () ->
-- | A parser for a block comment (e.g. 'skipBlockComment')
m () ->
m ()
space sp line block =
skipMany $
choice
[hidden sp, hidden line, hidden block]
{-# INLINEABLE space #-}
-- | This is a wrapper for lexemes. The typical usage is to supply the first
-- argument (parser that consumes white space, probably defined via 'space')
-- and use the resulting function to wrap parsers for every lexeme.
--
-- > lexeme = L.lexeme spaceConsumer
-- > integer = lexeme L.decimal
lexeme ::
(MonadParsec e s m) =>
-- | How to consume white space after lexeme
m () ->
-- | How to parse actual lexeme
m a ->
m a
lexeme spc p = p <* spc
{-# INLINEABLE lexeme #-}
-- | This is a helper to parse symbols, i.e. verbatim strings. You pass the
-- first argument (parser that consumes white space, probably defined via
-- 'space') and then you can use the resulting function to parse strings:
--
-- > symbol = L.symbol spaceConsumer
-- >
-- > parens = between (symbol "(") (symbol ")")
-- > braces = between (symbol "{") (symbol "}")
-- > angles = between (symbol "<") (symbol ">")
-- > brackets = between (symbol "[") (symbol "]")
-- > semicolon = symbol ";"
-- > comma = symbol ","
-- > colon = symbol ":"
-- > dot = symbol "."
symbol ::
(MonadParsec e s m) =>
-- | How to consume white space after lexeme
m () ->
-- | Symbol to parse
Tokens s ->
m (Tokens s)
symbol spc = lexeme spc . string
{-# INLINEABLE symbol #-}
-- | A case-insensitive version of 'symbol'. This may be helpful if you're
-- working with case-insensitive languages.
symbol' ::
(MonadParsec e s m, CI.FoldCase (Tokens s)) =>
-- | How to consume white space after lexeme
m () ->
-- | Symbol to parse (case-insensitive)
Tokens s ->
m (Tokens s)
symbol' spc = lexeme spc . string'
{-# INLINEABLE symbol' #-}