on master help sign in
Clean up literal parsing code
commit7f0733cd6e5f0c3ef1bd3a75f5405f3e68628d5f authorEvan Czaplicki <info@elm-lang.org> dateThu 27 Nov 2014, 02:37 (12 years ago) parent91953b6
1 file changed+56−33
src/Parse/Literal.hs+56−33
src/Parse/Literal.hs+56−33
@@ -1,49 +1,72 @@
11module Parse.Literal (literal) where
22
3+import Prelude hiding (exponent)
34import Control.Applicative ((<$>))
4−import Text.Parsec hiding (newline,spaces)
5+import Text.Parsec ((<|>), (<?>), digit, hexDigit, lookAhead, many1, oneOf, option, string, try)
56import Parse.Helpers (IParser, chr, str)
67import qualified AST.Literal as L
78
9+
810literal :: IParser L.Literal
9−literal = num <|> (L.Str <$> str) <|> (L.Chr <$> chr) <?> "literal"
11+literal =
12+ num <|> (L.Str <$> str) <|> (L.Chr <$> chr) <?> "literal"
13+
1014
1115num :: IParser L.Literal
12−num = toLit <$> (number <?> "number")
13− where
14− toLit n
15− | 'x' `elem` n = L.IntNum (read n)
16− | any (`elem` ".eE") n = L.FloatNum (read n)
17− | otherwise = L.IntNum (read n)
18−
19− number = concat <$> sequence
20− [ option "" minus
21− , hexNum <|> decNum ]
22−
23− decNum = concat <$> sequence
24− [ many1 digit
25− , option "" decimals
26− , option "" exponent ]
27−
28− hexNum = do
29− try $ lookAhead (string "0x" >> hexDigit)
30− string "0x"
31− n <- many1 hexDigit
32− return $ "0x" ++ n
33−
34− minus = try $ do
35− string "-"
36− lookAhead digit
37− return "-"
38−
39− decimals = do
40− try $ lookAhead (string "." >> digit)
16+num =
17+ toLiteral <$> (rawNumber <?> "number")
18+
19+
20+toLiteral :: String -> L.Literal
21+toLiteral n
22+ | 'x' `elem` n = L.IntNum (read n)
23+ | any (`elem` ".eE") n = L.FloatNum (read n)
24+ | otherwise = L.IntNum (read n)
25+
26+
27+rawNumber :: IParser String
28+rawNumber =
29+ concat <$> sequence
30+ [ option "" minus
31+ , base16 <|> base10
32+ ]
33+
34+
35+base16 :: IParser String
36+base16 =
37+ do try (string "0x")
38+ digits <- many1 hexDigit
39+ return ("0x" ++ digits)
40+
41+
42+base10 :: IParser String
43+base10 =
44+ concat <$> sequence
45+ [ many1 digit
46+ , option "" decimals
47+ , option "" exponent
48+ ]
49+
50+
51+minus :: IParser String
52+minus =
53+ try $ do
54+ string "-"
55+ lookAhead digit
56+ return "-"
57+
58+
59+decimals :: IParser String
60+decimals =
61+ do try $ lookAhead (string "." >> digit)
4162 string "."
4263 n <- many1 digit
4364 return ('.' : n)
4465
45− exponent = do
46− string "e" <|> string "E"
66+
67+exponent :: IParser String
68+exponent =
69+ do string "e" <|> string "E"
4770 op <- option "" (string "+" <|> string "-")
4871 n <- many1 digit
4972 return ('e' : op ++ n)