0 | module Protocol.SExp.Parser
4 | import Parser.Lexer.Common
5 | import Libraries.Text.Token
6 | import Libraries.Text.Lexer.Tokenizer
7 | import Libraries.Text.Parser
8 | import Libraries.Text.PrettyPrint.Prettyprinter.Symbols
9 | import Libraries.Text.PrettyPrint.Prettyprinter.Util
10 | import Libraries.Text.PrettyPrint.Prettyprinter.Doc
12 | import Parser.Support.Escaping
24 | | IntegerLit Integer
33 | Show SExpToken where
35 | show (IntegerLit x) = "literal " ++ show x
37 | show (StringBegin hashtag) = "string begin"
38 | show StringEnd = "string end"
39 | show (StringLit x) = "string " ++ show x
41 | show (Ident x) = "identifier " ++ x
42 | show (Symbol x) = "symbol " ++ x
43 | show Whitespace = " "
44 | show EndInput = "end of input"
47 | Pretty Void SExpToken where
49 | pretty (IntegerLit x) = pretty "literal" <++> pretty (show x)
51 | pretty (StringBegin hashtag) = reflow "string begin"
52 | pretty StringEnd = reflow "string end"
53 | pretty (StringLit x) = pretty "string" <++> dquotes (pretty x)
55 | pretty (Ident x) = pretty "identifier" <++> pretty x
56 | pretty (Symbol x) = pretty "symbol" <++> pretty x
58 | pretty Whitespace = pretty "space"
59 | pretty EndInput = reflow "end of input"
61 | SExpRule : Type -> Type
62 | SExpRule = Grammar () SExpToken True
64 | EmptySExpRule : Type -> Type
65 | EmptySExpRule = Grammar () SExpToken False
67 | symbols : List String
68 | symbols = ["(", ":", ")"]
70 | symbol : String -> SExpRule ()
72 | = terminal ("Expected '" ++ req ++ "'") $
74 | Symbol s => guard (s == req)
78 | space = terminal ("Expected a space") $
80 | Whitespace => Just ()
83 | exactIdent : String -> SExpRule ()
85 | = terminal ("Expected " ++ req) $
87 | Ident s => guard (s == req)
90 | simpleStrLit : SExpRule String
92 | = terminal "Expected string literal" $
94 | StringLit s => unescape 0 s
97 | strBegin : SExpRule Nat
98 | strBegin = terminal "Expected string begin" $
100 | StringBegin hashtag => Just hashtag
103 | strEnd : SExpRule ()
104 | strEnd = terminal "Expected string end" $
106 | StringEnd => Just ()
109 | simpleStr : SExpRule String
110 | simpleStr = strBegin *> commit *> (option "" simpleStrLit) <* strEnd
112 | stringTokens : Tokenizer SExpToken
114 | = match (someUntil (is '"') (escape (is '\\') any <|> any)) StringLit
116 | ideTokens : Tokenizer SExpToken
118 | match (choice $
exact <$> symbols) Symbol
119 | <|> match digits (IntegerLit . cast)
120 | <|> compose (is '"')
121 | (const $
StringBegin 0)
123 | (const stringTokens)
126 | <|> match (some $
pred isSpace) (const Whitespace)
127 | <|> match identAllowDashes Ident
129 | notWhitespace : WithBounds SExpToken -> Bool
130 | notWhitespace btok = case btok.val of
131 | Whitespace => False
135 | Either (StopReason, Int, Int, String)
136 | (List (WithBounds SExpToken))
137 | idelex str = case lex ideTokens str of
140 | (tok, (EndInput, l, c, _)) => Right (filter notWhitespace tok ++
141 | [MkBounded EndInput False (MkBounds l c l c)])
142 | (_, fail) => Left fail
145 | identifierSExp : SExpRule String
147 | = terminal "Expected name" $
149 | Ident str => Just str
152 | intLit : SExpRule Integer
154 | = terminal "Expected integer literal" $
156 | IntegerLit i => Just i
160 | eoi : EmptySExpRule ()
161 | eoi = ignore $
nextIs "Expected end of input" isEOI
163 | isEOI : SExpToken -> Bool
164 | isEOI EndInput = True
168 | sexp : SExpRule SExp
170 | = do symbol ":";
exactIdent "True"
171 | pure (BoolAtom True)
172 | <|> do symbol ":";
exactIdent "False"
173 | pure (BoolAtom False)
175 | pure (IntegerAtom i)
176 | <|> do str <- simpleStr
177 | pure (StringAtom str)
178 | <|> do symbol ":";
x <- identifierSExp
179 | pure (SymbolAtom x)
180 | <|> do Parser.symbol "("
187 | LexError (StopReason, Int, Int, String)
188 | | ParseErrors (List1 $
ParsingError SExpToken)
190 | ideParser : {e : _} ->
191 | String -> Grammar () SExpToken e ty -> Either SExpError ty
193 | = do toks <- mapFst LexError $
idelex str
194 | (_, _, (parsed, _)) <- mapFst ParseErrors $
parseWith p toks
199 | parseSExp : String -> Either SExpError SExp
201 | = ideParser inp (do c <- sexp;
eoi;
pure c)