gdritter repos s-cargot / 28bfb96
Merge pull request #7 from ckoparkar/master Add support for source locations G. D. Ritter authored 7 years ago GitHub committed 7 years ago
3 changed file(s) with 51 addition(s) and 1 deletion(s). Collapse all Expand all
2525 -- ** Numeric Literals for Arbitrary Bases
2626 , commonLispNumberAnyBase
2727 , gnuM4NumberAnyBase
28 -- ** Source locations
29 , Location(..), Located(..), located
2830 ) where
2931
3032 #if !MIN_VERSION_base(4,8,0)
332334 signedHexNumber :: Parser Integer
333335 signedHexNumber = ($) <$> sign <*> hexNumber
334336
337
338 -- |
339 data Location = Span !SourcePos !SourcePos
340 deriving (Eq, Ord, Show)
341
342 -- | Add support for source locations while parsing S-expressions, as described in this
343 -- <https://www.reddit.com/r/haskell/comments/4x22f9/labelling_ast_nodes_with_locations/d6cmdy9/ Reddit>
344 -- thread.
345 data Located a = At !Location a
346 deriving (Eq, Ord, Show)
347
348 -- | Adds a source span to a parser.
349 located :: Parser a -> Parser (Located a)
350 located parser = do
351 begin <- getPosition
352 result <- parser
353 end <- getPosition
354 return $ At (Span begin end) result
355
356
335357 {- $intro
336358
337359 This module contains a selection of parsers for different kinds of
55 -- $descr
66 basicParser
77 , basicPrinter
8 , locatedBasicParser
89 ) where
910
1011 import Control.Applicative ((<$>))
1112 import Data.Char (isAlphaNum)
1213 import Text.Parsec (many1, satisfy)
1314 import Data.Text (Text, pack)
15 import Data.Functor.Identity (Identity)
16 import Text.Parsec.Prim (ParsecT)
1417
18 import Data.SCargot.Common (Located, located)
1519 import Data.SCargot.Repr.Basic (SExpr)
1620 import Data.SCargot ( SExprParser
1721 , SExprPrinter
2428 || c == '-' || c == '*' || c == '/'
2529 || c == '+' || c == '<' || c == '>'
2630 || c == '=' || c == '!' || c == '?'
31
32 pToken :: ParsecT Text a Identity Text
33 pToken = pack <$> many1 (satisfy isAtomChar)
2734
2835 -- $descr
2936 -- The 'basicSpec' describes S-expressions whose atoms are simply
4350 -- Right [SCons (SAtom "1") (SCons (SAtom "elephant") SNil)]
4451 basicParser :: SExprParser Text (SExpr Text)
4552 basicParser = mkParser pToken
46 where pToken = pack <$> many1 (satisfy isAtomChar)
53
54 -- | A 'basicParser' which produces 'Located' values
55 --
56 -- >>> decode locatedBasicParser $ pack "(1 elephant)"
57 -- Right [SCons (SAtom (At (Span (line 1, column 2) (line 1, column 3)) "1")) (SCons (SAtom (At (Span (line 1, column 4) (line 1, column 12)) "elephant")) SNil)]
58 --
59 -- >>> decode locatedBasicParser $ pack "(let ((x 1))\n x)"
60 -- Right [SCons (SAtom (At (Span (line 1, column 2) (line 1, column 5)) "let")) (SCons (SCons (SCons (SAtom (At (Span (line 1, column 8) (line 1, column 9)) "x")) (SCons (SAtom (At (Span (line 1, column 10) (line 1, column 11)) "1")) SNil)) SNil) (SCons (SAtom (At (Span (line 2, column 3) (line 2, column 4)) "x")) SNil))]
61 locatedBasicParser :: SExprParser (Located Text) (SExpr (Located Text))
62 locatedBasicParser = mkParser $ located pToken
4763
4864 -- | A 'SExprPrinter' that prints textual atoms directly (without quoting
4965 -- or any other processing) onto a single line.
99 , parseHaskellString
1010 , parseHaskellFloat
1111 , parseHaskellInt
12 , locatedHaskLikeParser
1213 ) where
1314
1415 #if !MIN_VERSION_base(4,8,0)
157158 haskLikeParser :: SExprParser HaskLikeAtom (SExpr HaskLikeAtom)
158159 haskLikeParser = mkParser pHaskLikeAtom
159160
161 -- | A 'haskLikeParser' which produces 'Located' values
162 --
163 -- >>> decode locatedHaskLikeParser $ pack "(0x01 \"\\x65lephant\")"
164 -- Right [SCons (SAtom (At (Span (line 1, column 2) (line 1, column 6)) (HSInt 1))) (SCons (SAtom (At (Span (line 1, column 7) (line 1, column 20)) (HSString "elephant"))) SNil)]
165 --
166 -- >>> decode locatedHaskLikeParser $ pack "(1 elephant)"
167 -- Right [SCons (SAtom (At (Span (line 1, column 2) (line 1, column 3)) (HSInt 1))) (SCons (SAtom (At (Span (line 1, column 4) (line 1, column 12)) (HSIdent "elephant"))) SNil)]
168 locatedHaskLikeParser :: SExprParser (Located HaskLikeAtom) (SExpr (Located HaskLikeAtom))
169 locatedHaskLikeParser = mkParser $ located pHaskLikeAtom
170
171
160172 -- | This 'SExprPrinter' emits s-expressions that contain Scheme-like
161173 -- tokens as well as string literals, integer literals, and floating-point
162174 -- literals, which will be emitted as the literals produced by Haskell's