I’m having an issue where my parser is failing and not trying the next alternative branch.
module TestParser where
import Prelude
import Control.Plus ((<|>))
import Data.Array (many)
import Data.Either (Either)
import Data.Int (fromString)
import Data.Maybe (Maybe(..))
import Data.String.CodeUnits (fromCharArray)
import Text.Parsing.Parser (ParseError, Parser, fail, runParser)
import Text.Parsing.Parser.String (string, whiteSpace)
import Text.Parsing.Parser.Token (digit)
parseCommand :: String -> Either ParseError String
parseCommand strCommand = runParser strCommand commandParser
commandParser :: Parser String String
commandParser = twoArgCommandParser <|> oneArgCommandParser
twoArgCommandParser :: Parser String String
twoArgCommandParser = do
parsedRef1 <- refParser
parsedRef2 <- refParser
command <- twoArgCommandNameParser
pure (command <> parsedRef1 <> parsedRef2)
oneArgCommandParser :: Parser String String
oneArgCommandParser = do
parsedRef <- refParser
command <- oneArgCommandNameParser
pure (command <> parsedRef)
oneArgCommandNameParser :: Parser String String
oneArgCommandNameParser = whiteSpace *> string "dd" *> pure "DirectDerivation"
twoArgCommandNameParser :: Parser String String
twoArgCommandNameParser = whiteSpace *> string "mp" *> pure "ModusPonens"
refParser :: Parser String String
refParser = whiteSpace *> (lineRef <|> premiseRef)
lineRef :: Parser String String
lineRef = decimalParser >>= \num -> pure (show num)
premiseRef :: Parser String String
premiseRef = string "pr" *> decimalParser >>= \num -> pure ("premise" <> show num)
decimalParser :: Parser String Int
decimalParser =
many digit
>>= \digits -> case fromString (fromCharArray digits) of
Just number -> pure number
Nothing -> fail "Failed to parse number"
If you do parseCommand “2 dd” it should work and return 2DirectDerivation but instead it fails while running twoArgCommandParser and never tries the second branch. What am I doing wrong here?