Сочетание Алекса и Хеппи под стандартной "монадной" оберткой

Мне удалось совместить Алекс лексер и Счастливый парсер. Однако есть некоторые аспекты моего текущего решения, которыми я не доволен:

  1. Настройка начального состояния,
  2. Код Boilerplate при передаче состояния Алексу,
  3. Alex и мой ExpParser Монада это отдельные сущности.

Я объясню эти аспекты ниже.

мой ExpParser Монада выглядит следующим образом:

 data ParserEnv = ParserEnv
  { varModifier :: String -> String }

newtype ExpParser a = ExpParser 
  { runExpParser :: ReaderT ParserEnv (StateT AlexState (Except String)) a }
  deriving ( Functor, Applicative, Monad
           , MonadReader ParserEnv
           , MonadState AlexState
           , MonadError String
           )

И функция синтаксического анализа верхнего уровня определяется как:

-- | Parsing function.
parse :: (String -> String) -> String -> Either String Exp
parse f str = runExcept $ (`evalStateT` initState) $ runReaderT (runExpParser calc) initEnv
  where initEnv = ParserEnv { varModifier = f}
        initState = AlexState -- TODO: isn't it a standard initial state that we can use?        
          { alex_pos = AlexPn 0 0 0
          , alex_inp = str
          , alex_chr = '\n' -- TODO: What to include here?
          , alex_bytes = []
          , alex_scd = 0
          }

Первая проблема заключается в том, что я должен установить начальное состояние с некоторыми полями, в которых я не уверен. Более того, я ожидаю, что будет определено стандартное "начальное состояние" для лексера Alex.

Затем я использую лексер (сгенерированный с использованием оболочки "monad") следующим образом:

mLexer :: (Token -> ExpParser a) -> ExpParser a
mLexer cont = do -- TODO: is there a way to reduce this boilerplate?
  alexSt <- get
  case unAlex alexMonadScan alexSt of
    Left err -> throwError err
    Right (nextAlexSt, token) ->
      do
        put nextAlexSt
        cont token

Но я пишу некоторые шаблоны, а также повторяю себя, поскольку в приведенном выше коде есть поведение монады состояния. Если Alex определил экземпляр для State Монада Я мог бы избежать этого, однако я не думаю, что это так.

Есть ли способы улучшить текущее решение в аспектах, упомянутых выше?

0 ответов

Другие вопросы по тегам