License | BSD3 |
---|---|
Maintainer | cabal-devel@haskell.org |
Portability | portable |
Safe Haskell | None |
Language | Haskell2010 |
Synopsis
- data 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
A Cabal-like file consists of a series of fields (foo: bar
) and sections (library ...
).
A field name.
Invariant: ByteString
is lower-case ASCII.
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.
FieldLine !ann !ByteString |
data SectionArg ann #
Section arguments, e.g. name of the library
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 # | |
fmap :: (a -> b) -> SectionArg a -> SectionArg b # (<$) :: a -> SectionArg b -> SectionArg a # | |
Eq ann => Eq (SectionArg ann) # | |
(==) :: SectionArg ann -> SectionArg ann -> Bool # (/=) :: SectionArg ann -> SectionArg ann -> Bool # | |
Show ann => Show (SectionArg ann) # | |
showsPrec :: Int -> SectionArg ann -> ShowS # show :: SectionArg ann -> String # showList :: [SectionArg ann] -> ShowS # |
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] #
Parse cabal style ByteString
into list of Field
s, i.e. the cabal AST.
readFields' :: ByteString -> Either ParseError ([Field Position], [LexWarning]) #
Like readFields
but also return lexer warnings