3 Parsing and Reading C
Each of the parsing operations takes three optional keyword arguments. The #:typedef
argument takes a list of type names to bind as though by typedef in the parser’s initial
environment. The #:source argument is used to identify the source of the input in the
source location information. The #:offset argument is used as the base offset of
source location information. This is useful for parsing source extracted from the middle of
a file or input port. If this argument is ommitted or #f, the parsed text is assumed to
appear at the beginning of the input source.
3.1 Parsing
Parses a C program (‹TranslationUnit›).
Parses a C declaration (‹ExternalDeclaration›).
Parses a C statement (‹Statement›).
Parses a C expression (‹Expression›).
Parses a C type expression (‹TypeName›).
3.2 Embedding C in Scheme
See Scribble: Racket Documentation Tool for more information about Scribble.
This library includes macros for embedding C source in Scheme to be
parsed at compile time. These macros are designed to work with the
Scribble @-reader
to make this embedding convenient.
The following example defines a list of C declaration nodes, parsed
at compile time and bound at runtime to decls:
#lang at-exp scheme/base |
; ... |
(define decls |
@program[#:typedef (word)]{ |
struct tm { |
word tm_sec; |
word tm_min; |
word tm_hour; |
word tm_mday; |
word tm_mon; |
word tm_year; |
word tm_wday; |
word tm_yday; |
word tm_isdst; |
}; |
}) |
Notice the use of the at-exp
language to add @-reader support to the specified scheme/base language.
3.2.1 Scribble Reader
The Scribble @-reader does not itself recognize C syntax;
it simply treats free-form text enclosed between { }
pairs as string literals. It does match delimiters such as braces, parentheses
and brackets, however, which works well with the syntax of C.
The special forms defined in this library work in conjunction with the
Scribble reader to allow embedding C as string literals. The reader simply
determines the end of the input, and parsing occurs as part of macro expansion.
The forms defined in this library accept only string literals, so in particular nested
@-expressions are disallowed.
Since the syntax of C requires parsers to maintain a type environment to distinguish
variable names and type names (as bound by typedef), all type names must be declared
before they are used. For convenience, each of the special forms in this library accepts
an optional #:typedef argument to pre-declare type names.
3.2.2 Avoid Using Here Strings
Technically, it is possible to use the special forms in this library without the
Scribble reader by using
here strings
instead. However, the library is unable to extract accurate source location information with
here strings, so this is not recommended.
3.2.3 Embedding C
(program #:typedef (type-id ...) src-string ...+) |
(program src-string ...+) |
Parses the concatenated
src-string fragments with
parse-program
and expands into a list of
decl nodes.
Parses the concatenated
src-string fragments with
parse-statement
and expands into a
stmt node.
3.3 Including C Externally
Produces a procedure that reads an entire input port as a C program.
The resulting procedure is suitable for use as the expansion-time argument
to
include/reader.
Using include/reader, this makes it relatively convenient to include C source
code from an external file:
Notice that the relevant bindings must be available in the transformer environment in order
to apply make-program-reader in the expansion-time argument to include/reader.