language-rust-0.1.0.0: Parsing and pretty printing of Rust code

Copyright(c) Alec Theriault 2017-2018
LicenseBSD-style
Maintaineralec.theriault@gmail.com
Stabilityexperimental
PortabilityGHC
Safe HaskellNone
LanguageHaskell2010

Language.Rust.Parser

Contents

Description

Selecting the right parser may require adding an annotation or using -XTypeApplications to avoid an "Ambiguous type variable" error.

Using void (as in the examples below) uses the fact that most AST nodes are instances of Functor to discard the Span annotation that is attached to most parsed AST nodes. Conversely, if you wish to extract the Span annotation, the Located typeclass provides a spanOf method.

The examples below assume the following GHCi flags and imports:

>>> :set -XTypeApplications -XOverloadedStrings
>>> import Language.Rust.Syntax.AST
>>> import Control.Monad ( void )
>>> import System.IO

Synopsis

Parsing

parse :: Parse a => InputStream -> Either ParseFail a Source #

Parse something from an input stream (it is assumed the initial position is initPos).

>>> fmap void $ parse @(Expr Span) "x + 1"
Right (Binary [] AddOp (PathExpr [] Nothing (Path False [PathSegment "x" Nothing ()] ()) ())
                       (Lit [] (Int Dec 1 Unsuffixed ()) ())
                       ())
>>> fmap void $ parse @(Expr Span) "x + "
Left (parse failure at 1:4 (Syntax error: unexpected `<EOF>' (expected an expression)))

parse' :: Parse a => InputStream -> a Source #

Same as parse, but throws a ParseFail exception if it cannot parse. This function is intended for situations in which you are already stuck catching exceptions - otherwise you should prefer parse.

>>> void $ parse' @(Expr Span) "x + 1"
Binary [] AddOp (PathExpr [] Nothing (Path False [PathSegment "x" Nothing ()] ()) ())
                (Lit [] (Int Dec 1 Unsuffixed ()) ())
                ()
>>> void $ parse' @(Expr Span) "x + "
*** Exception: parse failure at 1:4 (Syntax error: unexpected `<EOF>' (expected an expression))

readSourceFile :: Handle -> IO (SourceFile Span) Source #

Given a handle to a Rust source file, read that file and parse it into a SourceFile

>>> writeFile "empty_main.rs" "fn main() { }"
>>> fmap void $ withFile "empty_main.rs" ReadMode readSourceFile
SourceFile Nothing [] [Fn [] InheritedV "main"
                          (FnDecl [] Nothing False ())
                          Normal NotConst Rust
                          (Generics [] [] (WhereClause [] ()) ())
                          (Block [] Normal ()) ()]

readTokens :: Handle -> IO [Spanned Token] Source #

Given a path pointing to a Rust source file, read that file and lex it (ignoring whitespace)

>>> writeFile "empty_main.rs" "fn main() { }"
>>> withFile "empty_main.rs" ReadMode readTokens
[fn,main,(,),{,}]

class Parse a where Source #

Describes things that can be parsed

Minimal complete definition

parser

Methods

parser :: P a Source #

Complete parser (fails if not all of the input is consumed)

data P a Source #

Parsing and lexing monad. A value of type P a represents a parser that can be run (using execParser) to possibly produce a value of type a.

Instances

Monad P Source # 

Methods

(>>=) :: P a -> (a -> P b) -> P b #

(>>) :: P a -> P b -> P b #

return :: a -> P a #

fail :: String -> P a #

Functor P Source # 

Methods

fmap :: (a -> b) -> P a -> P b #

(<$) :: a -> P b -> P a #

Applicative P Source # 

Methods

pure :: a -> P a #

(<*>) :: P (a -> b) -> P a -> P b #

(*>) :: P a -> P b -> P b #

(<*) :: P a -> P b -> P a #

execParser :: P a -> InputStream -> Position -> Either ParseFail a Source #

Execute the given parser on the supplied input stream at the given start position, returning either the position of an error and the error message, or the value parsed.

execParserTokens :: P a -> [Spanned Token] -> Position -> Either ParseFail a Source #

Same as execParser, but working from a list of tokens instead of an InputStream.

initPos :: Position Source #

Starting position in a file.

data Span Source #

Spans represent a contiguous region of code, delimited by two Positions. The endpoints are inclusive. Analogous to the information encoded in a selection.

Instances

Eq Span Source # 

Methods

(==) :: Span -> Span -> Bool #

(/=) :: Span -> Span -> Bool #

Data Span Source # 

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Span -> c Span #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Span #

toConstr :: Span -> Constr #

dataTypeOf :: Span -> DataType #

dataCast1 :: Typeable (* -> *) t => (forall d. Data d => c (t d)) -> Maybe (c Span) #

dataCast2 :: Typeable (* -> * -> *) t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Span) #

gmapT :: (forall b. Data b => b -> b) -> Span -> Span #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Span -> r #

gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Span -> r #

gmapQ :: (forall d. Data d => d -> u) -> Span -> [u] #

gmapQi :: Int -> (forall d. Data d => d -> u) -> Span -> u #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> Span -> m Span #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Span -> m Span #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Span -> m Span #

Ord Span Source # 

Methods

compare :: Span -> Span -> Ordering #

(<) :: Span -> Span -> Bool #

(<=) :: Span -> Span -> Bool #

(>) :: Span -> Span -> Bool #

(>=) :: Span -> Span -> Bool #

max :: Span -> Span -> Span #

min :: Span -> Span -> Span #

Show Span Source #

Field names are not shown

Methods

showsPrec :: Int -> Span -> ShowS #

show :: Span -> String #

showList :: [Span] -> ShowS #

Generic Span Source # 

Associated Types

type Rep Span :: * -> * #

Methods

from :: Span -> Rep Span x #

to :: Rep Span x -> Span #

Semigroup Span Source #

smallest covering Span

Methods

(<>) :: Span -> Span -> Span #

sconcat :: NonEmpty Span -> Span #

stimes :: Integral b => b -> Span -> Span #

Monoid Span Source # 

Methods

mempty :: Span #

mappend :: Span -> Span -> Span #

mconcat :: [Span] -> Span #

NFData Span Source # 

Methods

rnf :: Span -> () #

Located Span Source # 

Methods

spanOf :: Span -> Span Source #

Pretty Span Source # 
Parse (WhereClause Span) Source # 
Parse (TyParam Span) Source # 

Methods

parser :: P (TyParam Span) Source #

Parse (Ty Span) Source # 

Methods

parser :: P (Ty Span) Source #

Parse (TraitItem Span) Source # 
Parse (Stmt Span) Source # 

Methods

parser :: P (Stmt Span) Source #

Parse (Pat Span) Source # 

Methods

parser :: P (Pat Span) Source #

Parse (Lit Span) Source # 

Methods

parser :: P (Lit Span) Source #

Parse (SourceFile Span) Source # 
Parse (LifetimeDef Span) Source # 
Parse (Item Span) Source # 

Methods

parser :: P (Item Span) Source #

Parse (ImplItem Span) Source # 
Parse (Generics Span) Source # 
Parse (Expr Span) Source # 

Methods

parser :: P (Expr Span) Source #

Parse (Block Span) Source # 

Methods

parser :: P (Block Span) Source #

Parse (Attribute Span) Source # 
type Rep Span Source # 
type Rep Span = D1 (MetaData "Span" "Language.Rust.Data.Position" "language-rust-0.1.0.0-1eCZRQHreljBZIFWrl4lEQ" False) (C1 (MetaCons "Span" PrefixI True) ((:*:) (S1 (MetaSel (Just Symbol "lo") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 Position)) (S1 (MetaSel (Just Symbol "hi") NoSourceUnpackedness SourceStrict DecidedStrict) (Rec0 Position))))

Lexing

lexToken :: P (Spanned Token) Source #

Lexer for one Token. The only token this cannot produce is Interpolated.

lexNonSpace :: P (Spanned Token) Source #

Lexer for one non-whitespace Token. The only tokens this cannot produce are Interpolated and Space (which includes comments that aren't doc comments).

lexTokens :: P (Spanned Token) -> P [Spanned Token] Source #

Apply the given lexer repeatedly until (but not including) the Eof token. Meant for debugging purposes - in general this defeats the point of a threaded lexer.

translateLit :: LitTok -> Suffix -> a -> Lit a Source #

Parse a valid LitTok into a Lit.

Input stream

readInputStream :: FilePath -> IO InputStream Source #

Read an encoded file into an InputStream

Error reporting

lexicalError :: P a Source #

Signal a lexical error.

parseError :: Show b => b -> P a Source #

Signal a syntax error.