purescript-contrib/purescript-string-parsers

Strange error using alphaNum

Closed this issue · 4 comments

Getting a strange error using alphaNum:

> import Text.Parsing.StringParser
> import Text.Parsing.StringParser.String 
> runParser alphaNum "A"
Left (Expected a lower case character but found 'A')

Attached my bower_components folder so you can see what dependencies I have installed, renamed to a .zip because Github being a diva:

bower_components.tar.gz.zip

Great library, good API btw

Strange... I have this parser:

parseArg :: Parser Arg                                   
parseArg = fix $ \_ -> (StringArg <$> parseStringLiteral)
                   <|> (ExprArg <$> parseExpr)           
                   <|> (NameArg <$> parseName)           

The above works, and NameArg is never reached in my test. However, if I move ExprArg (which IS reached) to the end, like such:

parseArg :: Parser Arg                                   
parseArg = fix $ \_ -> (StringArg <$> parseStringLiteral)
                   <|> (NameArg <$> parseName)           
                   <|> (ExprArg <$> parseExpr)           

It fails.

Do parseName and parseExpr overlap on any prefixes?

No, ie, there's no string where both parseName and parseExpr would accept a prefix.

parseExpr :: Parser Expr                                    
parseExpr = between (char '(') (char ')') $ do              
    skipSpaces                                              
    func <- parseName                                       
    skipSpace1                                              
    args <- sepBy parseArg skipSpace1                       
    skipSpaces                                              
    pure $ Expr func $ fromList args                        
  where                                                     
    skipSpace1 = char ' ' $> skipSpaces                     


myAlphaNum :: Parser Char                                   
myAlphaNum = satisfy $ \c -> c >= 'a' && c <= 'z'           
                          || c >= 'A' && c <= 'Z'           
                          || c >= '0' && c <= '9'           


parseName :: Parser Name                                    
parseName = do                                              
    a <- lowerCaseChar                                      
    rest <- many myAlphaNum                                 
    (pure $ Name $ fromCharArray $ a : fromList rest)       


parseStringLiteral :: Parser String                         
parseStringLiteral =                                        
    let str = many $ satisfy $ (not <<< (=='"'))            
        lit = between (char '"') (char '"') str             
    in fromCharArray <<< fromList <$> lit                   


parseArg :: Parser Arg                                      
parseArg = fix $ \_ -> (StringArg <$> parseStringLiteral)   
                   <|> (ExprArg <$> parseExpr)              
                   <|> (NameArg <$> parseName)