Safe Haskell | None |
---|---|
Language | Haskell2010 |
Language.C.Types.Parse
Contents
Description
A parser for C99 declarations. Currently, the parser has the following limitations:
- Array sizes can only be
*
,n
(where n is a positive integer),x
(wherex
is a C identifier). In C99 they can be arbitrary expressions. See the
data type.ArrayType
_Bool
,_Complex
, and_Imaginary
are not present.- Untyped parameter lists (pre-K&R C) are not allowed.
The parser is incremental and generic (see CParser
). Pretty
and Arbitrary
instances are provided for all the data types.
The entry point if you want to parse C declarations is
.parameter_declaration
- type TypeNames = HashSet CIdentifier
- data CParserContext i = CParserContext {
- cpcIdentName :: String
- cpcTypeNames :: TypeNames
- cpcParseIdent :: forall m. CParser i m => m i
- cpcIdentToString :: i -> String
- data CIdentifier
- unCIdentifier :: CIdentifier -> String
- cIdentifierFromString :: String -> Either String CIdentifier
- cCParserContext :: TypeNames -> CParserContext CIdentifier
- type CParser i m = (Monad m, Functor m, Applicative m, MonadPlus m, Parsing m, CharParsing m, TokenParsing m, LookAheadParsing m, MonadReader (CParserContext i) m, Hashable i)
- runCParser :: Stream s Identity Char => CParserContext i -> String -> s -> ReaderT (CParserContext i) (Parsec s ()) a -> Either ParseError a
- quickCParser :: CParserContext i -> String -> ReaderT (CParserContext i) (Parsec String ()) a -> a
- quickCParser_ :: String -> ReaderT (CParserContext CIdentifier) (Parsec String ()) a -> a
- identifier_no_lex :: CParser i m => m i
- data DeclarationSpecifier
- declaration_specifiers :: CParser i m => m [DeclarationSpecifier]
- data StorageClassSpecifier
- storage_class_specifier :: CParser i m => m StorageClassSpecifier
- data TypeSpecifier
- = VOID
- | CHAR
- | SHORT
- | INT
- | LONG
- | FLOAT
- | DOUBLE
- | SIGNED
- | UNSIGNED
- | Struct CIdentifier
- | Enum CIdentifier
- | TypeName CIdentifier
- type_specifier :: CParser i m => m TypeSpecifier
- data TypeQualifier
- type_qualifier :: CParser i m => m TypeQualifier
- data FunctionSpecifier = INLINE
- function_specifier :: CParser i m => m FunctionSpecifier
- data Declarator i = Declarator {}
- declarator :: CParser i m => m (Declarator i)
- data DirectDeclarator i
- = DeclaratorRoot i
- | ArrayOrProto (DirectDeclarator i) (ArrayOrProto i)
- | DeclaratorParens (Declarator i)
- direct_declarator :: CParser i m => m (DirectDeclarator i)
- data ArrayOrProto i
- = Array (ArrayType i)
- | Proto [ParameterDeclaration i]
- array_or_proto :: CParser i m => m (ArrayOrProto i)
- data ArrayType i
- array_type :: CParser i m => m (ArrayType i)
- data Pointer = Pointer [TypeQualifier]
- pointer :: CParser i m => m Pointer
- data ParameterDeclaration i = ParameterDeclaration {}
- data DeclaratorOrAbstractDeclarator i
- parameter_declaration :: CParser i m => m (ParameterDeclaration i)
- parameter_list :: CParser i m => m [ParameterDeclaration i]
- data AbstractDeclarator i = AbstractDeclarator {}
- abstract_declarator :: CParser i m => m (AbstractDeclarator i)
- data DirectAbstractDeclarator i
- direct_abstract_declarator :: CParser i m => m (DirectAbstractDeclarator i)
- cIdentStart :: [Char]
- cIdentLetter :: [Char]
- cReservedWords :: HashSet String
- data ParameterDeclarationWithTypeNames i = ParameterDeclarationWithTypeNames {}
- arbitraryParameterDeclarationWithTypeNames :: (Arbitrary i, Hashable i) => (i -> String) -> Gen (ParameterDeclarationWithTypeNames i)
Parser configuration
type TypeNames = HashSet CIdentifier Source
A collection of named types (typedefs)
data CParserContext i Source
Constructors
CParserContext | |
Fields
|
Default configuration
data CIdentifier Source
A type for C identifiers.
unCIdentifier :: CIdentifier -> String Source
Parser type
type CParser i m = (Monad m, Functor m, Applicative m, MonadPlus m, Parsing m, CharParsing m, TokenParsing m, LookAheadParsing m, MonadReader (CParserContext i) m, Hashable i) Source
All the parsing is done using the type classes provided by the
parsers
package. You can use the parsing routines with any of the parsers
that implement the classes, such as parsec
or trifecta
.
We parametrize the parsing by the type of the variable identifiers,
i
. We do so because we use this parser to implement anti-quoters
referring to Haskell variables, and thus we need to parse Haskell
identifiers in certain positions.
Arguments
:: Stream s Identity Char | |
=> CParserContext i | |
-> String | Source name. |
-> s | String to parse. |
-> ReaderT (CParserContext i) (Parsec s ()) a | Parser. Anything with type |
-> Either ParseError a |
Runs a
using CParser
parsec
.
Arguments
:: CParserContext i | |
-> String | String to parse. |
-> ReaderT (CParserContext i) (Parsec String ()) a | Parser. Anything with type |
-> a |
Useful for quick testing. Uses "quickCParser"
as source name, and throws
an error
if parsing fails.
Arguments
:: String | String to parse. |
-> ReaderT (CParserContext CIdentifier) (Parsec String ()) a | Parser. Anything with type |
-> a |
Like quickCParser
, but uses
as
cCParserContext
(const
False
)CParserContext
.
Types and parsing
identifier_no_lex :: CParser i m => m i Source
declaration_specifiers :: CParser i m => m [DeclarationSpecifier] Source
storage_class_specifier :: CParser i m => m StorageClassSpecifier Source
data TypeSpecifier Source
Constructors
VOID | |
CHAR | |
SHORT | |
INT | |
LONG | |
FLOAT | |
DOUBLE | |
SIGNED | |
UNSIGNED | |
Struct CIdentifier | |
Enum CIdentifier | |
TypeName CIdentifier |
Instances
type_specifier :: CParser i m => m TypeSpecifier Source
data TypeQualifier Source
type_qualifier :: CParser i m => m TypeQualifier Source
data FunctionSpecifier Source
Constructors
INLINE |
function_specifier :: CParser i m => m FunctionSpecifier Source
data Declarator i Source
Constructors
Declarator | |
Fields |
Instances
Functor Declarator | |
Foldable Declarator | |
Traversable Declarator | |
Eq i => Eq (Declarator i) | |
Show i => Show (Declarator i) | |
Pretty i => Pretty (Declarator i) | |
Typeable (* -> *) Declarator |
declarator :: CParser i m => m (Declarator i) Source
data DirectDeclarator i Source
Constructors
DeclaratorRoot i | |
ArrayOrProto (DirectDeclarator i) (ArrayOrProto i) | |
DeclaratorParens (Declarator i) |
Instances
Functor DirectDeclarator | |
Foldable DirectDeclarator | |
Traversable DirectDeclarator | |
Eq i => Eq (DirectDeclarator i) | |
Show i => Show (DirectDeclarator i) | |
Pretty i => Pretty (DirectDeclarator i) | |
Typeable (* -> *) DirectDeclarator |
direct_declarator :: CParser i m => m (DirectDeclarator i) Source
data ArrayOrProto i Source
Constructors
Array (ArrayType i) | |
Proto [ParameterDeclaration i] |
Instances
Functor ArrayOrProto | |
Foldable ArrayOrProto | |
Traversable ArrayOrProto | |
Eq i => Eq (ArrayOrProto i) | |
Show i => Show (ArrayOrProto i) | |
Pretty i => Pretty (ArrayOrProto i) | |
Typeable (* -> *) ArrayOrProto |
array_or_proto :: CParser i m => m (ArrayOrProto i) Source
Constructors
VariablySized | |
Unsized | |
SizedByInteger Integer | |
SizedByIdentifier i |
array_type :: CParser i m => m (ArrayType i) Source
Constructors
Pointer [TypeQualifier] |
data ParameterDeclaration i Source
Constructors
ParameterDeclaration | |
Instances
Functor ParameterDeclaration | |
Foldable ParameterDeclaration | |
Traversable ParameterDeclaration | |
Eq i => Eq (ParameterDeclaration i) | |
Show i => Show (ParameterDeclaration i) | |
Pretty i => Pretty (ParameterDeclaration i) | |
Typeable (* -> *) ParameterDeclaration |
data DeclaratorOrAbstractDeclarator i Source
Constructors
IsDeclarator (Declarator i) | |
IsAbstractDeclarator (AbstractDeclarator i) |
parameter_declaration :: CParser i m => m (ParameterDeclaration i) Source
parameter_list :: CParser i m => m [ParameterDeclaration i] Source
data AbstractDeclarator i Source
Constructors
AbstractDeclarator | |
Fields |
Instances
Functor AbstractDeclarator | |
Foldable AbstractDeclarator | |
Traversable AbstractDeclarator | |
Eq i => Eq (AbstractDeclarator i) | |
Show i => Show (AbstractDeclarator i) | |
Pretty i => Pretty (AbstractDeclarator i) | |
Typeable (* -> *) AbstractDeclarator |
abstract_declarator :: CParser i m => m (AbstractDeclarator i) Source
data DirectAbstractDeclarator i Source
Constructors
ArrayOrProtoHere (ArrayOrProto i) | |
ArrayOrProtoThere (DirectAbstractDeclarator i) (ArrayOrProto i) | |
AbstractDeclaratorParens (AbstractDeclarator i) |
Instances
direct_abstract_declarator :: CParser i m => m (DirectAbstractDeclarator i) Source
YACC grammar
The parser above is derived from a modification of the YACC grammar for C99 found at http://www.quut.com/c/ANSI-C-grammar-y-1999.html, reproduced below.
%token IDENTIFIER TYPE_NAME INTEGER %token TYPEDEF EXTERN STATIC AUTO REGISTER INLINE RESTRICT %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID %token BOOL COMPLEX IMAGINARY %token STRUCT UNION ENUM %start parameter_list %% declaration_specifiers : storage_class_specifier | storage_class_specifier declaration_specifiers | type_specifier | type_specifier declaration_specifiers | type_qualifier | type_qualifier declaration_specifiers | function_specifier | function_specifier declaration_specifiers ; storage_class_specifier : TYPEDEF | EXTERN | STATIC | AUTO | REGISTER ; type_specifier : VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | BOOL | COMPLEX | IMAGINARY | STRUCT IDENTIFIER | UNION IDENTIFIER | ENUM IDENTIFIER | TYPE_NAME ; type_qualifier : CONST | RESTRICT | VOLATILE ; function_specifier : INLINE ; declarator : pointer direct_declarator | direct_declarator ; direct_declarator : IDENTIFIER | '(' declarator ')' | direct_declarator '[' type_qualifier_list ']' | direct_declarator '[' type_qualifier_list*
']' | direct_declarator '['*
']' | direct_declarator '[' IDENTIFIER ']' | direct_declarator '[' INTEGER ']' | direct_declarator '[' ']' | direct_declarator '(' parameter_list ')' | direct_declarator '(' ')' ; pointer :*
|*
type_qualifier_list |*
pointer |*
type_qualifier_list pointer ; type_qualifier_list : type_qualifier | type_qualifier_list type_qualifier ; parameter_list : parameter_declaration | parameter_list ',' parameter_declaration ; parameter_declaration : declaration_specifiers declarator | declaration_specifiers abstract_declarator | declaration_specifiers ; abstract_declarator : pointer | direct_abstract_declarator | pointer direct_abstract_declarator ; direct_abstract_declarator : '(' abstract_declarator ')' | '[' ']' | direct_abstract_declarator '[' ']' | '['*
']' | direct_abstract_declarator '['*
']' | '[' IDENTIFIER ']' | direct_abstract_declarator '[' IDENTIFIER ']' | '[' INTEGER ']' | direct_abstract_declarator '[' INTEGER ']' | '(' ')' | '(' parameter_list ')' | direct_abstract_declarator '(' ')' | direct_abstract_declarator '(' parameter_list ')' ; %% #include <stdio.h> extern char yytext[]; extern int column; void yyerror(char const *s) { fflush(stdout); printf("n%*sn%*sn", column, "^", column, s); }
Testing utilities
cIdentStart :: [Char] Source
cIdentLetter :: [Char] Source
data ParameterDeclarationWithTypeNames i Source
Type used to generate an Arbitrary
ParameterDeclaration
with
arbitrary allowed type names.
Constructors
ParameterDeclarationWithTypeNames | |
Instances
Eq i => Eq (ParameterDeclarationWithTypeNames i) | |
Show i => Show (ParameterDeclarationWithTypeNames i) | |
Typeable (* -> *) ParameterDeclarationWithTypeNames |
arbitraryParameterDeclarationWithTypeNames :: (Arbitrary i, Hashable i) => (i -> String) -> Gen (ParameterDeclarationWithTypeNames i) Source