errorful parser

This commit is contained in:
crumbtoo
2024-01-22 09:55:58 -07:00
parent 1a881399ab
commit 5a659d22dd
4 changed files with 71 additions and 20 deletions

View File

@@ -1,6 +1,7 @@
{-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE TupleSections, PatternSynonyms #-} {-# LANGUAGE TupleSections, PatternSynonyms #-}
{-# LANGUAGE UndecidableInstances #-}
module Control.Monad.Errorful module Control.Monad.Errorful
( ErrorfulT ( ErrorfulT
, runErrorfulT , runErrorfulT
@@ -11,11 +12,12 @@ module Control.Monad.Errorful
) )
where where
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
import Control.Monad.State.Strict
import Control.Monad.Trans import Control.Monad.Trans
import Data.Functor.Identity import Data.Functor.Identity
import Data.Coerce import Data.Coerce
import Data.HashSet (HashSet) import Data.HashSet (HashSet)
import Data.HashSet qualified as H import Data.HashSet qualified as H
import Lens.Micro import Lens.Micro
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
@@ -68,3 +70,10 @@ mapErrorful f (ErrorfulT m) = ErrorfulT $
-- mapErrorful f = coerced . mapped . _2 . mappd %~ f -- mapErrorful f = coerced . mapped . _2 . mappd %~ f
-- lol -- lol
--------------------------------------------------------------------------------
-- daily dose of n^2 instances
instance (Monad m, MonadErrorful e m) => MonadErrorful e (StateT s m) where
addWound = undefined
addFatal = undefined

View File

@@ -7,12 +7,14 @@ module Rlp.Lex
, RlpToken(..) , RlpToken(..)
, Located(..) , Located(..)
, lexToken , lexToken
, lexStream
, lexDebug , lexDebug
, lexCont , lexCont
) )
where where
import Codec.Binary.UTF8.String (encodeChar) import Codec.Binary.UTF8.String (encodeChar)
import Control.Monad import Control.Monad
import Control.Monad.Errorful
import Core.Syntax (Name) import Core.Syntax (Name)
import Data.Functor.Identity import Data.Functor.Identity
import Data.Char (digitToInt) import Data.Char (digitToInt)
@@ -203,13 +205,6 @@ alexEOF = do
inp <- getInput inp <- getInput
pure (Located undefined TokenEOF) pure (Located undefined TokenEOF)
execP :: P a -> ParseState -> Maybe a
execP p st = runP p st & snd
execP' :: P a -> Text -> Maybe a
execP' p s = execP p st where
st = initParseState s
initParseState :: Text -> ParseState initParseState :: Text -> ParseState
initParseState s = ParseState initParseState s = ParseState
{ _psLayoutStack = [] { _psLayoutStack = []
@@ -228,6 +223,10 @@ initAlexInput s = AlexInput
, _aiPos = (1,1) , _aiPos = (1,1)
} }
runP' :: P a -> Text -> (ParseState, [RlpParseError], Maybe a)
runP' p s = runP p st where
st = initParseState s
lexToken :: P (Located RlpToken) lexToken :: P (Located RlpToken)
lexToken = do lexToken = do
inp <- getInput inp <- getInput
@@ -242,6 +241,7 @@ lexToken = do
AlexToken inp' l act -> do AlexToken inp' l act -> do
psInput .= inp' psInput .= inp'
act inp l act inp l
AlexError inp' -> addFatal RlpParErrLexical
lexCont :: (Located RlpToken -> P a) -> P a lexCont :: (Located RlpToken -> P a) -> P a
lexCont = (lexToken >>=) lexCont = (lexToken >>=)
@@ -260,7 +260,7 @@ lexDebug k = do
k t k t
lexTest :: Text -> Maybe [RlpToken] lexTest :: Text -> Maybe [RlpToken]
lexTest s = execP' lexStream s lexTest s = runP' lexStream s ^. _3
indentLevel :: P Int indentLevel :: P Int
indentLevel = do indentLevel = do

View File

@@ -161,7 +161,7 @@ mkProgram ds = do
pure $ RlpProgram (associate pt <$> ds) pure $ RlpProgram (associate pt <$> ds)
parseError :: Located RlpToken -> P a parseError :: Located RlpToken -> P a
parseError = error . show parseError (Located ((l,c),s) t) = addFatal RlpParErrUnknown
mkInfixD :: Assoc -> Int -> Name -> P PartialDecl' mkInfixD :: Assoc -> Int -> Name -> P PartialDecl'
mkInfixD a p n = do mkInfixD a p n = do

View File

@@ -1,11 +1,42 @@
{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE ImplicitParams, ViewPatterns, PatternSynonyms #-} {-# LANGUAGE ImplicitParams, ViewPatterns, PatternSynonyms #-}
{-# LANGUAGE LambdaCase #-} {-# LANGUAGE LambdaCase #-}
module Rlp.Parse.Types where module Rlp.Parse.Types
( LexerAction
, AlexInput(..)
, Position(..)
, RlpToken(..)
, P(..)
, ParseState(..)
, psLayoutStack
, psLexState
, psInput
, psOpTable
, Layout(..)
, Located(..)
, OpTable
, OpInfo
, RlpParseError(..)
, PartialDecl'
, Partial(..)
, pL, pR
, PartialE
, pattern WithInfo
, opInfoOrDef
, PartialExpr'
, aiPrevChar
, aiSource
, aiBytes
, aiPos
, addFatal
, addWound
)
where
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
import Core.Syntax (Name) import Core.Syntax (Name)
import Control.Monad import Control.Monad
import Control.Monad.State.Class import Control.Monad.State.Strict
import Control.Monad.Errorful
import Data.Text (Text) import Data.Text (Text)
import Data.Maybe import Data.Maybe
import Data.Fix import Data.Fix
@@ -71,24 +102,31 @@ data RlpToken
| TokenEOF | TokenEOF
deriving (Show) deriving (Show)
newtype P a = P { runP :: ParseState -> (ParseState, Maybe a) } newtype P a = P { runP :: ParseState -> (ParseState, [RlpParseError], Maybe a) }
deriving (Functor) deriving (Functor)
instance Applicative P where instance Applicative P where
pure a = P $ \st -> (st,Just a) pure a = P $ \st -> (st, [], pure a)
liftA2 = liftM2 liftA2 = liftM2
instance Monad P where instance Monad P where
p >>= k = P $ \st -> p >>= k = P $ \st ->
let (st',a) = runP p st let (st',es,ma) = runP p st
in case a of in case ma of
Just x -> runP (k x) st' Just a -> runP (k a) st'
Nothing -> (st', Nothing) & _2 %~ (es<>)
Nothing -> (st',es,Nothing)
{-# INLINE (>>=) #-}
instance MonadState ParseState P where instance MonadState ParseState P where
state f = P $ \st -> state f = P $ \st ->
let (a,st') = f st let (a,st') = f st
in (st', Just a) in (st', [], Just a)
instance MonadErrorful RlpParseError P where
addWound e = P $ \st -> (st, [e], Just ())
addFatal e = P $ \st -> (st, [e], Nothing)
data ParseState = ParseState data ParseState = ParseState
{ _psLayoutStack :: [Layout] { _psLayoutStack :: [Layout]
@@ -112,6 +150,8 @@ type OpInfo = (Assoc, Int)
data RlpParseError = RlpParErrOutOfBoundsPrecedence Int data RlpParseError = RlpParErrOutOfBoundsPrecedence Int
| RlpParErrDuplicateInfixD | RlpParErrDuplicateInfixD
| RlpParErrLexical
| RlpParErrUnknown
deriving (Eq, Ord, Show) deriving (Eq, Ord, Show)
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
@@ -161,3 +201,5 @@ type PartialExpr' = Fix Partial
makeLenses ''AlexInput makeLenses ''AlexInput
makeLenses ''ParseState makeLenses ''ParseState
--------------------------------------------------------------------------------