StillerHarpo / masterarbeit

BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

Combination of try and (<|>) in megaparsec #6

Open StillerHarpo opened 4 years ago

StillerHarpo commented 4 years ago

when i have to parsers p1 and p2, then the folloing

p1 <* try p2

is not the same as

try (p1 <* p2) <|> p1

I don't understand why

TODO: Ask upstream

BinderDavid commented 4 years ago

Auf welchem Input verhalten Sie sich denn verschieden?

StillerHarpo commented 4 years ago

Ich hab das oben angepasst das some sollte da nicht stehen. In folgendem Programm hab ich die beiden Fälle als lexer1 und lexer2 definiert.

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TupleSections     #-}

module Test2 where

import Control.Applicative hiding (some)
import Control.Monad (void)
import Data.Text (Text)
import Data.Void
import Text.Megaparsec
import Text.Megaparsec.Char
import qualified Text.Megaparsec.Char.Lexer as L

type Parser = Parsec Void Text

scn :: Parser ()
scn = L.space space1 empty empty

sc :: Parser ()
sc = L.space (void $ some (char ' ' <|> char '\t')) empty empty

lexeme :: Parser a -> Parser a
lexeme = L.lexeme sc

pItem :: Parser String
pItem = lexeme (some alphaNumChar)

lexer1 :: Parser a -> Parser b -> Parser a
lexer1 p sc' = p <* try sc'

lexer2 :: Parser a -> Parser b -> Parser a
lexer2 p sc' = try (p <* sc') <|> p

pComplexItem ::(Parser String -> Parser () -> Parser String) -> Parser (String, [String])
pComplexItem lexer = L.indentBlock scn p
  where
    p = do
      header <- pItem
      return (L.IndentMany Nothing (return . (header, )) (pLineFold lexer))

pLineFold :: (Parser String -> Parser () -> Parser String) -> Parser String
pLineFold p = L.lineFold scn $ \sc' ->
  let ps = some $ p (some $ alphaNumChar <|> char '-') sc'
  in unwords <$> ps <* scn -- (1)
parseTest (pComplexItem lexer1) "a\n  a\na"

Scheitert mit folgendem Fehler

3:1:
  |
3 | a
  | ^
incorrect indentation (got 1, should be greater than 3)
parseTest (pComplexItem lexer2) "a\n  a\na"

liefert

("a",["a"])