11module Parse.String exposing
22 ( Error (..)
33 , char
4+ , string
45 )
56
67
@@ -21,67 +22,94 @@ char : Parser c Error Char
2122char =
2223 Parser.succeed identity
2324 |> Parser.skip (Parser.symbol charQuote)
24- |> Parser.keep
25- (Parser.oneOf
26- [ Parser.chompIf (\c -> c == '\\') ExpectedChar
27- |> Parser.andThen
28- (\_ ->
29- Parser.oneOf
30- [ Parser.chompIf (\c -> c == 'n') ExpectedChar
31- |> Parser.map (\_ -> '\n')
32- , Parser.chompIf (\c -> c == 'r') ExpectedChar
33- |> Parser.map (\_ -> '\r')
34- , Parser.chompIf (\c -> c == 't') ExpectedChar
35- |> Parser.map (\_ -> '\t')
36- , Parser.chompIf (\c -> c == '\\') ExpectedChar
37- |> Parser.map (\_ -> '\\')
38- , Parser.chompIf (\c -> c == '\'') ExpectedChar
39- |> Parser.map (\_ -> '\'')
40- , Parser.chompIf (\c -> c == '\"') ExpectedChar
41- |> Parser.map (\_ -> '\"')
42- , Parser.succeed identity
43- |> Parser.skip (Parser.symbol unicodeOpening)
44- |> Parser.keep (Number.hexParser ExpectedValidUnicode)
45- |> Parser.skip (Parser.chompIf (\c -> c == '}') ExpectedUnicodeClosing)
46- |> Parser.andThen
47- (\num ->
48- let
49- character =
50- Char.fromCode num
51- in
52- -- Check if char is valid (replacement character)
53- if character == '\u{FFFD}' then
54- Parser.problem ExpectedValidUnicode
55-
56- else
57- Parser.succeed character
58- )
59- , Parser.chompIf (\_ -> True) ExpectedChar
60- |> Parser.getChompedString
61- |> Parser.andThen (Parser.problem << ExpectedEscapeChar)
62- ]
63- )
64- , Parser.chompIf (\_ -> True) ExpectedChar
65- |> Parser.getChompedString
66- |> Parser.andThen
67- (\str ->
68- when String.popFirst str is
69- Nothing ->
70- Parser.problem ExpectedChar
71-
72- Just { first = c } ->
73- Parser.succeed c
74- )
75- ]
76- )
25+ |> Parser.keep coreParser
7726 |> Parser.skip (Parser.symbol charQuote)
7827
7928
29+ coreParser : Parser c Error Char
30+ coreParser =
31+ Parser.oneOf
32+ [ Parser.chompIf (\c -> c == '\\') ExpectedChar
33+ |> Parser.andThen
34+ (\_ ->
35+ Parser.oneOf
36+ [ Parser.chompIf (\c -> c == 'n') ExpectedChar
37+ |> Parser.map (\_ -> '\n')
38+ , Parser.chompIf (\c -> c == 'r') ExpectedChar
39+ |> Parser.map (\_ -> '\r')
40+ , Parser.chompIf (\c -> c == 't') ExpectedChar
41+ |> Parser.map (\_ -> '\t')
42+ , Parser.chompIf (\c -> c == '\\') ExpectedChar
43+ |> Parser.map (\_ -> '\\')
44+ , Parser.chompIf (\c -> c == '\'') ExpectedChar
45+ |> Parser.map (\_ -> '\'')
46+ , Parser.chompIf (\c -> c == '\"') ExpectedChar
47+ |> Parser.map (\_ -> '\"')
48+ , Parser.succeed identity
49+ |> Parser.skip (Parser.symbol unicodeOpening)
50+ |> Parser.keep (Number.hexParser ExpectedValidUnicode)
51+ |> Parser.skip (Parser.chompIf (\c -> c == '}') ExpectedUnicodeClosing)
52+ |> Parser.andThen
53+ (\num ->
54+ let
55+ character =
56+ Char.fromCode num
57+ in
58+ -- Check if char is valid (replacement character)
59+ if character == '\u{FFFD}' then
60+ Parser.problem ExpectedValidUnicode
61+
62+ else
63+ Parser.succeed character
64+ )
65+ , Parser.chompIf (\_ -> True) ExpectedChar
66+ |> Parser.getChompedString
67+ |> Parser.andThen (Parser.problem << ExpectedEscapeChar)
68+ ]
69+ )
70+ , Parser.chompIf (\_ -> True) ExpectedChar
71+ |> Parser.getChompedString
72+ |> Parser.andThen
73+ (\str ->
74+ when String.popFirst str is
75+ Nothing ->
76+ Parser.problem ExpectedChar
77+
78+ Just { first = c } ->
79+ Parser.succeed c
80+ )
81+ ]
82+
83+
8084charQuote : Parser.Token Error
8185charQuote =
8286 Parser.Token { str = "\'", expecting = ExpectedQuote }
8387
8488
89+ strQuote : Parser.Token Error
90+ strQuote =
91+ Parser.Token { str = "\"", expecting = ExpectedQuote }
92+
93+
8594unicodeOpening : Parser.Token Error
8695unicodeOpening =
8796 Parser.Token { str = "u{", expecting = ExpectedUnicodeOpening }
97+
98+
99+
100+ string : Parser c Error String
101+ string =
102+ Parser.succeed identity
103+ |> Parser.skip (Parser.symbol strQuote)
104+ |> Parser.keep (Parser.loop "" stringHelp)
105+
106+
107+ stringHelp : String -> Parser c Error (Parser.Step String String)
108+ stringHelp str =
109+ Parser.oneOf
110+ [ Parser.succeed {}
111+ |> Parser.skip (Parser.symbol strQuote)
112+ |> Parser.map (\_ -> Parser.Done str)
113+ , Parser.succeed (\chr -> Parser.Loop (String.pushLast chr str))
114+ |> Parser.keep coreParser
115+ ]
0 commit comments