ParsecでPHPのパーサを書こう

ということで書いていきます。Parsec/Haskellで。何故PHPかと言ったら使ってるからです。何故Haskellかといったら好きだからです。
では先ずはIntとDouble。
+-符号を考慮して、Intは8進法と16進法を考慮して。
PHPにNumber型とか多分無いですが、IntとDoubleを合わせたものと定義してます。

import Text.ParserCombinators.Parsec

typeInteger :: Parser String
typeInteger = do
    f <- lookAhead anyChar
    case f of
        c | (c=='+')||(c=='-')  ->  -- 符号有り
                do
                s  <- anyChar
                skipMany space
                cs <- typeInteger
                return (s:cs)
          | otherwise           ->  -- 符号無し
                do  -- 10進数
                d <- oneOf "123456789"
                ds <- many digit
                return (d:ds)
            <|> do  -- 16進数
                try (string "0x")
                cs <- many1 (digit <|> oneOf "abcdefABCDEF")
                return ("0x"++cs)
            <|> do  -- 8進数
                char '0'
                cs <- many (oneOf "01234567")
                return ("0"++cs)

typeDouble :: Parser String
typeDouble = do
    f <- lookAhead anyChar
    case f of
        c | (c=='+')||(c=='-')  ->
                do
                s  <- anyChar
                skipMany space
                cs <- typeDouble
                return (s:cs)
          | otherwise           ->
                do
                ds <- many (oneOf "0123456789")
                char '.'
                ds' <- many1 (oneOf "0123456789")
                return (ds++['.']++ds')

typeNumber :: Parser String
typeNumber = do
        n <- (try(typeDouble) <|> typeInteger)
        return n

演算子は本当は全部別個に書くべきなのだろうな。優先度考慮しつつ。
次にString型書こうとしたら分からなくて困った。
2文字ずつくらい先読みすれば出来そうだけど。