# language InstanceSigs , DeriveFunctor #
# options_ghc -Wincomplete - patterns #

module Gy08 where

import Control.Monad
import Control.Applicative
import Data.Char
import Debug.Trace

  PARSER LIBRARY 
--------------------------------------------------------------------------------

newtype Parser a = Parser {runParser :: String -> Maybe (a, String)}
  deriving (Functor)

instance Applicative Parser where
  pure  = return
  (<*>) = ap

instance Monad Parser where
  return :: a -> Parser a
  nincs hatás 

  (>>=) :: Parser a -> (a -> Parser b) -> Parser b
  Parser f >>= g = Parser $ \s -> do {(a, s) <- f s; runParser (g a) s}

  pontosan az üres inputot olvassuk 
eof :: Parser ()
eof = Parser $ \s -> case s of
  [] -> Just ((), [])
  _  -> Nothing

  olvassunk egy   input  ,     
satisfy :: (Char -> Bool) -> Parser Char
satisfy f = Parser $ \s -> case s of
  c:s | f c -> Just (c, s)
  _         -> Nothing

-- olvassunk egy konkrét karaktert
char :: Char -> Parser ()
char c = () <$ satisfy (==c)

-- olvassunk egy konkrét String-et
  String ~ [  ] 
string s = undefined


instance Alternative Parser where
  -- mindig hibázó parser
  empty :: Parser a
  empty = Parser $ \_ -> Nothing

  választás két parser között 
  Parser f <|> Parser g = Parser $ \s -> case f s of
    Nothing -> g s
    res     -> res

-- Control.Applicative-ból:
     many   : :  a - > Parser [ a ]        -- 0 - szor vagy többször futtatja 
     some   : :  a - > Parser [ a ]        -- 1 - szer vagy többször futtatja 

many_ :: Parser a -> Parser ()
many_ pa = () <$ many pa

some_ :: Parser a -> Parser ()
some_ pa = () <$ some pa

-- Control.Applicative-ból:
  optional : :  a - > Parser ( Maybe a )    --    ( soha   ) 
-- optional pa = (Just <$> pa) <|> pure Nothing

optional_ :: Parser a -> Parser ()
optional_ pa = () <$ optional pa

--------------------------------------------------------------------------------

    regex       
----------------------
--     c       char c
--    p|q     p <|> q
--    pq      p >> q
--    p*      many_ p
--    p+      some_ p
--    ε       eof

-- Implementáld a következő regex-eket!
  Szükség szerint definiálj segédfüggvényeket . 

-- (foo|bar)*kutya?
p0 :: Parser ()
p0 = undefined

  \[foo ( , foo)*\ ]          -- nemüres , -vel választott foo lista 
p1 :: Parser ()
p1 = undefined

  ( ac|bd)+ 
p2 :: Parser ()
p2 = undefined

inList :: [Char] -> Parser Char
inList str = undefined

inList_ :: [Char] -> Parser ()
inList_ str = undefined

-- std függvény:
choice :: [Parser a] -> Parser a
choice ps = undefined

lowercase :: Parser ()
lowercase = undefined

-- [a..z]+@foobar\.(com|org|hu)
p3 :: Parser ()
p3 = undefined

-- -?[0..9]+           -- a -? opcionális '-'-t jelent
p4 :: Parser ()
p4 = undefined

  ( [ a .. z]|[A .. Z])([a .. z]|[A .. Z]|[0 .. 9 ] ) * 
p5 :: Parser ()
p5 = undefined

  ( [ a .. z]+=[0 .. 9]+)(,[a .. z]+=[0 .. 9]+ ) * 
  példa elfogadott inputra :    foo=10,bar=30,baz=40 
p6 :: Parser ()
p6 = undefined

------------------------------------------------------------

   -- Functor/Applicative operátorok
    ( < $ )        kicserélni parser   értékre 
   --   (<$>)      fmap
    ( < * )        két parser - t futtat ,     
   --   (*>)       két parser-t futtat, a második értékét visszaadja

-- egy számjegy olvasása
digit :: Parser Int
digit = undefined

  Olvass be egy pozitív Int - et ! ( Számjegyek nemüres sorozata ) 
posInt :: Parser Int
posInt = undefined

-- Írj egy parsert, ami felsimeri Int-ek vesszővel elválasztott listáit!
   : " [ ] " , " [     12 , 34555 ] " , " [ 0,1,2,3 ] " 
intList :: Parser [Int]
intList = undefined

  Írj egy parsert ,   a        
    : " " , " ( ) " , " ( ) ( ) " , " ( ( ) ) ( ) " , " ( ( ) ( ) ) " , " ( ( ( ) ( ) ) ( ) ) " 
balancedPar :: Parser ()
balancedPar = undefined

------------------------------------------------------------------------------
 olvassunk egy konkrét karaktert
 olvassunk egy konkrét String-et
 mindig hibázó parser
 Control.Applicative-ból:
 0 - szor vagy többször futtatja 
 1 - szer vagy többször futtatja 
 Control.Applicative-ból:
    ( soha   ) 
 optional pa = (Just <$> pa) <|> pure Nothing
------------------------------------------------------------------------------
--------------------
     c       char c
    p|q     p <|> q
    pq      p >> q
    p*      many_ p
    p+      some_ p
    ε       eof
 Implementáld a következő regex-eket!
 (foo|bar)*kutya?
 nemüres , -vel választott foo lista 
 std függvény:
 [a..z]+@foobar\.(com|org|hu)
 -?[0..9]+           -- a -? opcionális '-'-t jelent
----------------------------------------------------------
 Functor/Applicative operátorok
   (<$>)      fmap
   (*>)       két parser-t futtat, a második értékét visszaadja
 egy számjegy olvasása
 Írj egy parsert, ami felsimeri Int-ek vesszővel elválasztott listáit!

# language InstanceSigs , DeriveFunctor #
# options_ghc -Wincomplete - patterns #

module Gy08 where

import Control.Monad
import Control.Applicative
import Data.Char
import Debug.Trace

  PARSER LIBRARY 

newtype Parser a = Parser {runParser :: String -> Maybe (a, String)}
  deriving (Functor)

instance Applicative Parser where
  pure  = return
  (<*>) = ap

instance Monad Parser where
  return :: a -> Parser a
  nincs hatás 

  (>>=) :: Parser a -> (a -> Parser b) -> Parser b
  Parser f >>= g = Parser $ \s -> do {(a, s) <- f s; runParser (g a) s}

  pontosan az üres inputot olvassuk 
eof :: Parser ()
eof = Parser $ \s -> case s of
  [] -> Just ((), [])
  _  -> Nothing

  olvassunk egy   input  ,     
satisfy :: (Char -> Bool) -> Parser Char
satisfy f = Parser $ \s -> case s of
  c:s | f c -> Just (c, s)
  _         -> Nothing

char :: Char -> Parser ()
char c = () <$ satisfy (==c)

  String ~ [  ] 
string s = undefined


instance Alternative Parser where
  empty :: Parser a
  empty = Parser $ \_ -> Nothing

  választás két parser között 
  Parser f <|> Parser g = Parser $ \s -> case f s of
    Nothing -> g s
    res     -> res


many_ :: Parser a -> Parser ()
many_ pa = () <$ many pa

some_ :: Parser a -> Parser ()
some_ pa = () <$ some pa


optional_ :: Parser a -> Parser ()
optional_ pa = () <$ optional pa


    regex       

  Szükség szerint definiálj segédfüggvényeket . 

p0 :: Parser ()
p0 = undefined

p1 :: Parser ()
p1 = undefined

  ( ac|bd)+ 
p2 :: Parser ()
p2 = undefined

inList :: [Char] -> Parser Char
inList str = undefined

inList_ :: [Char] -> Parser ()
inList_ str = undefined

choice :: [Parser a] -> Parser a
choice ps = undefined

lowercase :: Parser ()
lowercase = undefined

p3 :: Parser ()
p3 = undefined

p4 :: Parser ()
p4 = undefined

  ( [ a .. z]|[A .. Z])([a .. z]|[A .. Z]|[0 .. 9 ] ) * 
p5 :: Parser ()
p5 = undefined

  ( [ a .. z]+=[0 .. 9]+)(,[a .. z]+=[0 .. 9]+ ) * 
  példa elfogadott inputra :    foo=10,bar=30,baz=40 
p6 :: Parser ()
p6 = undefined


    ( < $ )        kicserélni parser   értékre 
    ( < * )        két parser - t futtat ,     

digit :: Parser Int
digit = undefined

  Olvass be egy pozitív Int - et ! ( Számjegyek nemüres sorozata ) 
posInt :: Parser Int
posInt = undefined

   : " [ ] " , " [     12 , 34555 ] " , " [ 0,1,2,3 ] " 
intList :: Parser [Int]
intList = undefined

  Írj egy parsert ,   a        
    : " " , " ( ) " , " ( ) ( ) " , " ( ( ) ) ( ) " , " ( ( ) ( ) ) " , " ( ( ( ) ( ) ) ( ) ) " 
balancedPar :: Parser ()
balancedPar = undefined
