{- 
    Copyright 2010-2015 Mario Blazevic

    This file is part of the Streaming Component Combinators (SCC) project.

    The SCC project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
    License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
    version.

    SCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along with SCC.  If not, see
    <http://www.gnu.org/licenses/>.
-}

-- | This module defines parsing combinators for incremental parsers with left-biased local choice.
-- 
-- The exported 'Parser' type can provide partial parsing results from partial input, as long as the output is a
-- 'Monoid'. Construct a parser using the primitives and combinators, supply it with input using functions 'feed' and
-- 'feedEof', and extract the parsed output using 'results'.
-- 
-- Implementation is based on Brzozowski derivatives.

{-# LANGUAGE EmptyDataDecls, FlexibleInstances #-}

module Text.ParserCombinators.Incremental.LeftBiasedLocal (
   module Text.ParserCombinators.Incremental,
   Parser, LeftBiasedLocal, leftmost
)
where

import Control.Applicative (Alternative (empty, (<|>), many, some))
import Control.Monad (MonadPlus (mzero, mplus))
import Data.Monoid (Monoid)

import Text.ParserCombinators.Incremental hiding (Parser)
import qualified Text.ParserCombinators.Incremental as Incremental (Parser)

-- | An empty type to specialize 'Parser' for the left-biased 'Alternative' instance.
data LeftBiasedLocal

type Parser = Incremental.Parser LeftBiasedLocal

-- | Left-biased choice. The right parser is used only if the left one utterly fails.
instance Monoid s => Alternative (Incremental.Parser LeftBiasedLocal s) where
   empty :: Parser LeftBiasedLocal s a
empty = Parser LeftBiasedLocal s a
forall t s r. Parser t s r
failure
   Parser LeftBiasedLocal s a
p1 <|> :: Parser LeftBiasedLocal s a
-> Parser LeftBiasedLocal s a -> Parser LeftBiasedLocal s a
<|> Parser LeftBiasedLocal s a
p2 = Parser LeftBiasedLocal s a
p1 Parser LeftBiasedLocal s a
-> Parser LeftBiasedLocal s a -> Parser LeftBiasedLocal s a
forall s t r.
Monoid s =>
Parser t s r -> Parser t s r -> Parser t s r
<<|> Parser LeftBiasedLocal s a
p2
   many :: Parser LeftBiasedLocal s a -> Parser LeftBiasedLocal s [a]
many = Parser LeftBiasedLocal s a -> Parser LeftBiasedLocal s [a]
forall s t r.
(Monoid s, Alternative (Parser t s)) =>
Parser t s r -> Parser t s [r]
defaultMany
   some :: Parser LeftBiasedLocal s a -> Parser LeftBiasedLocal s [a]
some = Parser LeftBiasedLocal s a -> Parser LeftBiasedLocal s [a]
forall s t r.
(Monoid s, Alternative (Parser t s)) =>
Parser t s r -> Parser t s [r]
defaultSome

-- | The 'MonadPlus' instances are the same as the 'Alternative' instances.
instance Monoid s => MonadPlus (Incremental.Parser LeftBiasedLocal s) where
   mzero :: Parser LeftBiasedLocal s a
mzero = Parser LeftBiasedLocal s a
forall t s r. Parser t s r
failure
   mplus :: Parser LeftBiasedLocal s a
-> Parser LeftBiasedLocal s a -> Parser LeftBiasedLocal s a
mplus = Parser LeftBiasedLocal s a
-> Parser LeftBiasedLocal s a -> Parser LeftBiasedLocal s a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>)

leftmost :: Parser s r -> Incremental.Parser a s r
leftmost :: Parser s r -> Parser a s r
leftmost Parser s r
p = (forall a. Parser LeftBiasedLocal s a -> Parser a s a)
-> Parser s r -> Parser a s r
forall t s b r.
(forall a. Parser t s a -> Parser b s a)
-> Parser t s r -> Parser b s r
mapType forall a. Parser LeftBiasedLocal s a -> Parser a s a
forall s r a. Parser s r -> Parser a s r
leftmost Parser s r
p