Distribution.Parsec.Parser

Cabal-2.2.0.1: A framework for packaging Haskell software

License | BSD3
Maintainer | cabal-devel@haskell.org
Portability | portable
Safe Haskell | None
Language | Haskell2010

Distribution.Parsec.Parser

Contents

- Types
- Grammar and parsing

Description

Synopsis

- data Field ann
  - = Field !(Name ann) [FieldLine ann]
  - | Section !(Name ann) [SectionArg ann] [Field ann]
- data Name ann = Name !ann !FieldName
- data FieldLine ann = FieldLine !ann !ByteString
- data SectionArg ann
  - = SecArgName !ann !ByteString
  - | SecArgStr !ann !ByteString
  - | SecArgOther !ann !ByteString
- readFields :: ByteString -> Either ParseError [Field Position]
- readFields' :: ByteString -> Either ParseError ([Field Position], [LexWarning])

# Types

data Field ann Source #

A Cabal-like file consists of a series of fields (`foo: bar`) and sections (`library ...`).

Constructors

Field !(Name ann) [FieldLine ann] |
Section !(Name ann) [SectionArg ann] [Field ann] |

Instances

Functor Field Source # |
Instance details Defined in Distribution.Parsec.Field Methods fmap :: (a -> b) -> Field a -> Field b Source # (<$) :: a -> Field b -> Field a Source #
Eq ann => Eq (Field ann) Source # |
Instance details Defined in Distribution.Parsec.Field Methods (==) :: Field ann -> Field ann -> Bool # (/=) :: Field ann -> Field ann -> Bool #
Show ann => Show (Field ann) Source # |
Instance details Defined in Distribution.Parsec.Field Methods showsPrec :: Int -> Field ann -> ShowS Source # show :: Field ann -> String Source # showList :: [Field ann] -> ShowS Source #

data Name ann Source #

A field name.

Invariant: `ByteString` is lower-case ASCII.

Constructors

Name !ann !FieldName |

Instances

Functor Name Source # |
Instance details Defined in Distribution.Parsec.Field Methods fmap :: (a -> b) -> Name a -> Name b Source # (<$) :: a -> Name b -> Name a Source #
Eq ann => Eq (Name ann) Source # |
Instance details Defined in Distribution.Parsec.Field Methods (==) :: Name ann -> Name ann -> Bool # (/=) :: Name ann -> Name ann -> Bool #
Show ann => Show (Name ann) Source # |
Instance details Defined in Distribution.Parsec.Field Methods showsPrec :: Int -> Name ann -> ShowS Source # show :: Name ann -> String Source # showList :: [Name ann] -> ShowS Source #

data FieldLine ann Source #

A line of text representing the value of a field from a Cabal file. A field may contain multiple lines.

Invariant: `ByteString` has no newlines.

Constructors

FieldLine !ann !ByteString |

Instances

Functor FieldLine Source # |
Instance details Defined in Distribution.Parsec.Field Methods fmap :: (a -> b) -> FieldLine a -> FieldLine b Source # (<$) :: a -> FieldLine b -> FieldLine a Source #
Eq ann => Eq (FieldLine ann) Source # |
Instance details Defined in Distribution.Parsec.Field Methods (==) :: FieldLine ann -> FieldLine ann -> Bool # (/=) :: FieldLine ann -> FieldLine ann -> Bool #
Show ann => Show (FieldLine ann) Source # |
Instance details Defined in Distribution.Parsec.Field Methods showsPrec :: Int -> FieldLine ann -> ShowS Source # show :: FieldLine ann -> String Source # showList :: [FieldLine ann] -> ShowS Source #

data SectionArg ann Source #

Section arguments, e.g. name of the library

Constructors

SecArgName !ann !ByteString | identifier, or omething which loos like number. Also many dot numbers, i.e. "7.6.3"
SecArgStr !ann !ByteString | quoted string
SecArgOther !ann !ByteString | everything else, mm. operators (e.g. in if-section conditionals)

Instances

Functor SectionArg Source # |
Instance details Defined in Distribution.Parsec.Field Methods fmap :: (a -> b) -> SectionArg a -> SectionArg b Source # (<$) :: a -> SectionArg b -> SectionArg a Source #
Eq ann => Eq (SectionArg ann) Source # |
Instance details Defined in Distribution.Parsec.Field Methods (==) :: SectionArg ann -> SectionArg ann -> Bool # (/=) :: SectionArg ann -> SectionArg ann -> Bool #
Show ann => Show (SectionArg ann) Source # |
Instance details Defined in Distribution.Parsec.Field Methods showsPrec :: Int -> SectionArg ann -> ShowS Source # show :: SectionArg ann -> String Source # showList :: [SectionArg ann] -> ShowS Source #

# Grammar and parsing

    CabalStyleFile ::= SecElems

    SecElems       ::= SecElem* '\n'?
    SecElem        ::= '\n' SecElemLayout | SecElemBraces
    SecElemLayout  ::= FieldLayout | FieldBraces | SectionLayout | SectionBraces
    SecElemBraces  ::= FieldInline | FieldBraces |                 SectionBraces
    FieldLayout    ::= name : line? ('\n' line)*
    FieldBraces    ::= name : '\n'? '{' content '}'
    FieldInline    ::= name : content
    SectionLayout  ::= name arg* SecElems
    SectionBraces  ::= name arg* '\n'? '{' SecElems '}'

and the same thing but left factored...

    SecElems              ::= SecElem*
    SecElem               ::= '\n' name SecElemLayout
                            |      name SecElemBraces
    SecElemLayout         ::= :   FieldLayoutOrBraces
                            | arg*  SectionLayoutOrBraces
    FieldLayoutOrBraces   ::= '\n'? '{' content '}'
                            | line? ('\n' line)*
    SectionLayoutOrBraces ::= '\n'? '{' SecElems '\n'? '}'
                            | SecElems
    SecElemBraces         ::= : FieldInlineOrBraces
                            | arg* '\n'? '{' SecElems '\n'? '}'
    FieldInlineOrBraces   ::= '\n'? '{' content '}'
                            | content

Note how we have several productions with the sequence:

    '\n'? '{'

That is, an optional newline (and indent) followed by a `{` token. In the `SectionLayoutOrBraces` case you can see that this makes it not fully left factored (because `SecElems` can start with a `n`). Fully left factoring here would be ugly, and though we could use a lookahead of two tokens to resolve the alternatives, we can't conveniently use Parsec's `try` here to get a lookahead of only two. So instead we deal with this case in the lexer by making a line where the first non-space is `{` lex as just the `{` token, without the usual indent token. Then in the parser we can resolve everything with just one token of lookahead and so without using `try`.

readFields :: ByteString -> Either ParseError [Field Position] Source #

Parse cabal style `ByteString` into list of `Field`s, i.e. the cabal AST.

readFields' :: ByteString -> Either ParseError ([Field Position], [LexWarning]) Source #

Like `readFields` but also return lexer warnings