intellij-haskforce icon indicating copy to clipboard operation
intellij-haskforce copied to clipboard

Parser consumes too much in do block

Open carymrobbins opened this issue 10 years ago • 8 comments

I'm pretty sure the problem here either lies in HaskellParserUtilBase.stateHackMess or HaskellParserWrapper.increaseRbraceDebt. I'm having trouble deciphering the logic in those methods.

The line runGhcModT' :: IOish m ... is being considered part of the do block and parsed as an exp instead of a gendecl.

module Layout00021 where

runGhcModT :: IOish m
           => Options
           -> GhcModT m a
           -> m (Either GhcModError a, GhcModLog)
runGhcModT opt action = do
    env <- liftBase $ newGhcModEnv opt =<< getCurrentDirectory
    first (fst <$>) <$> (runGhcModT' env defaultState $ do
        dflags <- getSessionDynFlags
        defaultCleanupHandler dflags $ do
            initializeFlagsWithCradle opt (gmCradle env)
            action)

runGhcModT' :: IOish m
           => GhcModEnv
           -> GhcModState
           -> GhcModT m a
           -> m (Either GhcModError (a, GhcModState), GhcModLog)
runGhcModT' r s a = do
  (res, w') <-
      flip runReaderT r $ runJournalT $ runErrorT $
        runStateT (unGhcModT $ initGhcMonad (Just ghcLibDir) >> a) s
  return (res, w')

carymrobbins avatar Aug 28 '14 04:08 carymrobbins

The logic is broken and hard to decipher as you say; we're essentially squeezing square pegs into round holes. Will take a look on saturday.

pjonsson avatar Aug 28 '14 08:08 pjonsson

The problem is line 33-38 in Layout00021.txt for the parsing lexer test suite. The lexer alone can't compensate for that though, so ideally the parser should tell the lexer to get a grip and insert the synthetic braces in the right place. That's not possible with IntelliJ though; the lexer runs over the entire file and the content is cached so the parser can work on that. So the problem on lines 33-38 must remain, it's supposed to look that way despite being wrong.

The broken logic tries to compensate for the situation dynamically, but as expected it's fragile and doesn't work all the time.

pjonsson avatar Aug 28 '14 17:08 pjonsson

This seems like it may be useful: http://stackoverflow.com/questions/1413204/how-to-use-indentation-as-block-delimiters-with-bison-and-flex

carymrobbins avatar Sep 04 '14 01:09 carymrobbins

There's a paper about parsing Haskell with Parsec at the Haskell Symposium this year. That approach doesn't need the L algorithm (which is what the crap in the parsing lexer + the logic you pointed out tries to implement), so it might actually work. Will start in that end; our current lexer is sufficient for that approach.

pjonsson avatar Sep 04 '14 08:09 pjonsson

I had a look at the approach. I think it will pan out in the long run, but it's not exactly a work of art. Nevertheless--works is a pretty important metric. I just pushed a partial fix for this ticket.

pjonsson avatar Sep 08 '14 12:09 pjonsson

This is definitely fixable with the approach. I have a large outstanding patch for Haskell.bnf that is not ready for merging yet, so it would be great if we could hold off other commits to that file for a few days to avoid conflicts.

pjonsson avatar Sep 08 '14 17:09 pjonsson

Please ignore if not not related (or move to a different issue). I have the following test case:

module Hello where

-- | Parser for the endianess.
endianessParser :: IO Char
endianessParser = do
    case 'c' of
     x | x == 'c'    -> return 'b'
     x                  -> return 'a'
{-# INLINE endianessParser #-}

symParser :: Char
symParser = 'a' -- Need to consume the \0 byte
{-# INLINE symParser #-}

I'm not entirely sure what is happening, but if I remove the do it is fine, similarly when I remove the case statement or the INLINE pragma. Otherwise it is complaining with:

" unexpected.

I understand this is a completely evil piece of code, in reality it is blowing up on this code: https://github.com/jkozlowski/kdb-haskell/blob/kdb-haskell-2/src/Database/Kdb/Internal/IPC.hs#L302.

jkozlowski avatar Nov 01 '14 08:11 jkozlowski

Almost all weird parsing error messages relate to the same shortcoming with indentation handling, so you're probably in the right ticket.

We should probably have a disclaimer about the shortcomings of the parser somewhere. HaskForce should parse all legal Haskell, whether it's evil or not.

pjonsson avatar Nov 01 '14 12:11 pjonsson