Am Freitag, 31. März 2006 15:24 schrieb Daniel Fischer: > Hi, > > probably somebody else has already come up with something better, but > still... > > I surmise that you have two kinds of infix-operators, > 1. dot-like operators, made up entirely of symbols (^!$%&/\,.:;#+-~* ...) > 2. LaTeX-command-like operators, starting with a backslash and then > followed by a nonempty sequence of letters (or possibly alphanumeric > characters). > > Then the following helps: > > import Data.Char (isAlpha) > > lexer = lexer0{P.reservedOp = rOp} > where > lexer0 = P.makeTokenParser testdef > resOp0 = P.reservedOp lexer0 > resOp1 name = > case name of > ('\\':cs@(_:_)) > > | all isAlpha cs -> do string name > > notFollowedBy letter <?> > ("end of " ++ show name) > _ -> fail (show name ++ " no good reservedOp") > rOp name = lexeme $ try $ resOp0 name <|> resOp1 name > lexeme p = do { x <- p; P.whiteSpace lexer0; return x }
Noho, that's not right, that parses "a\inn" as InfixExpr OP_In (Ident "a") (Ident "n"), because resOp1 is never used, which we don't want, so: lexer = lexer0{P.reservedOp = rOp} where lexer0 = P.makeTokenParser testdef resOp0 = P.reservedOp lexer0 resOp1 name = do string name notFollowedBy letter <?> ("end of " ++ show name) rOp name = lexeme $ try $ case name of ('\\':cs@(_:_)) | all isAlpha cs -> resOp1 name _ -> resOp0 name lexeme p = do { x <- p; P.whiteSpace lexer0; return x } Now: [EMAIL PROTECTED]:~/Documents/haskell/Reto> cat input a.n [EMAIL PROTECTED]:~/Documents/haskell/Reto> reto input InfixExpr OP_Dot (Ident "a") (Ident "n") [EMAIL PROTECTED]:~/Documents/haskell/Reto> cat input a\inn [EMAIL PROTECTED]:~/Documents/haskell/Reto> reto input Ident "a" [EMAIL PROTECTED]:~/Documents/haskell/Reto> cat input a\in n [EMAIL PROTECTED]:~/Documents/haskell/Reto> reto input InfixExpr OP_In (Ident "a") (Ident "n") That's better. > > testdef = emptyDef > { P.identStart = letter <|> char '_' > , P.identLetter = alphaNum <|> char '_' > , P.opStart = oneOf $ nub $ > map (\s -> head s) $ P.reservedOpNames testdef > -- , P.opLetter = oneOf (concat (P.reservedOpNames testdef)) > , P.opLetter = oneOf symbs > , P.reservedOpNames = [ ".", "\\in" ] } > where > symbs = filter (not . isAlpha) . concat $ P.reservedOpNames testdef > --------------------------------------------------------------------- > [EMAIL PROTECTED]:~/Documents/haskell/Reto> cat input > a.n > [EMAIL PROTECTED]:~/Documents/haskell/Reto> reto input > InfixExpr OP_Dot (Ident "a") (Ident "n") > > If you have more complicated infix operators (e.g. \foo#bar:, :ouch:), > it won't be so easy, anyway, you have to change the definition of > reservedOp. > > Cheers, > Daniel -- "In My Egotistical Opinion, most people's C programs should be indented six feet downward and covered with dirt." -- Blair P. Houghton _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe