Cabal-3.2.1.0: A framework for packaging Haskell software
License BSD3
Maintainer cabal-devel@haskell.org
Portability portable
Safe Haskell None
Language Haskell2010

Distribution.Fields.Parser

Description

Synopsis

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

Instances details
Functor Field Source #
Instance details

Defined in Distribution.Fields.Field

Foldable Field Source #
Instance details

Defined in Distribution.Fields.Field

Traversable Field Source #
Instance details

Defined in Distribution.Fields.Field

Eq ann => Eq ( Field ann) Source #
Instance details

Defined in Distribution.Fields.Field

Show ann => Show ( Field ann) Source #
Instance details

Defined in Distribution.Fields.Field

data Name ann Source #

A field name.

Invariant : ByteString is lower-case ASCII.

Constructors

Name !ann ! FieldName

Instances

Instances details
Functor Name Source #
Instance details

Defined in Distribution.Fields.Field

Foldable Name Source #
Instance details

Defined in Distribution.Fields.Field

Traversable Name Source #
Instance details

Defined in Distribution.Fields.Field

Eq ann => Eq ( Name ann) Source #
Instance details

Defined in Distribution.Fields.Field

Show ann => Show ( Name ann) Source #
Instance details

Defined in Distribution.Fields.Field

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

Instances details
Functor FieldLine Source #
Instance details

Defined in Distribution.Fields.Field

Foldable FieldLine Source #
Instance details

Defined in Distribution.Fields.Field

Traversable FieldLine Source #
Instance details

Defined in Distribution.Fields.Field

Eq ann => Eq ( FieldLine ann) Source #
Instance details

Defined in Distribution.Fields.Field

Show ann => Show ( FieldLine ann) Source #
Instance details

Defined in Distribution.Fields.Field

data SectionArg ann Source #

Section arguments, e.g. name of the library

Constructors

SecArgName !ann ! ByteString

identifier, or something which looks 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

Instances details
Functor SectionArg Source #
Instance details

Defined in Distribution.Fields.Field

Foldable SectionArg Source #
Instance details

Defined in Distribution.Fields.Field

Traversable SectionArg Source #
Instance details

Defined in Distribution.Fields.Field

Eq ann => Eq ( SectionArg ann) Source #
Instance details

Defined in Distribution.Fields.Field

Show ann => Show ( SectionArg ann) Source #
Instance details

Defined in Distribution.Fields.Field

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 .