#lang scribble/doc @begin[(require scribble/manual) (require scribble/eval) (require scribble/basic) (require scribblings/icons) (require scheme/list) (require (for-label (except-in scheme/base exn:fail:syntax struct:exn:fail:syntax make-exn:fail:syntax exn:fail:syntax?))) (require (for-label scheme/contract)) (require (for-label parser-tools/lex)) (require (for-label "../syntax.ss")) (require "abnf.ss" "utils.ss")] @title[#:tag "parsing"]{Parsing and Reading C} @;XXX: is there a better name for this module? parse.ss? @defmodule/this-package[syntax] @section[#:tag "parse"]{Parsing} @;defproc[(parse-decl [in (or/c input-port? string? path?)]) decl?]{Parses a C declaration.} @;defproc[(parse-decls [in (or/c input-port? string? path?)]) (listof decl?)]{Parses a sequence of C declarations.} @section[#:tag "embedding"]{Embedding C in Scheme} @margin-note{@finger See @other-manual['(lib "scribblings/scribble/scribble.scrbl")] 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 @seclink["reader" #:doc '(lib "scribblings/scribble/scribble.scrbl")]{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 @schemeid[decls]: @schememod[ at-exp scheme/base @code:comment{ ...} (define decls #, @schemekeywordfont|{@}|#, @scheme[declaration-list]#, @schemeparenfont|{[}|#, @scheme[#:typedef (word)]#, @schemeparenfont|{]}|#, @schemeparenfont|{{}| #, @schemefont|{ struct tm {}| #, @schemefont|{ word tm_sec;}| #, @schemefont|{ word tm_min;}| #, @schemefont|{ word tm_hour;}| #, @schemefont|{ word tm_mday;}| #, @schemefont|{ word tm_mon;}| #, @schemefont|{ word tm_year;}| #, @schemefont|{ word tm_wday;}| #, @schemefont|{ word tm_yday;}| #, @schemefont|{ word tm_isdst;}| #, @schemefont|{ };}| #, @schemeparenfont|{}}|)] Notice the use of the @seclink["at-exp-lang" #:doc '(lib "scribblings/scribble/scribble.scrbl")]{@schememodname[at-exp]} language to add @"@"-reader support to the specified @scheme[scheme/base] language. @subsection[#:tag "scribble"]{Scribble Reader} The Scribble @"@"-reader does not itself recognize C syntax; it simply treats free-form text enclosed between @schemeparenfont["{"] @schemeparenfont["}"] 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 @tt{typedef}), all type names must be declared before they are used. For convenience, each of the special forms in this library accepts an optional @scheme[#:typedef] argument to pre-declare type names. @subsection[#:tag "here"]{Here Strings} Technically, it is possible to use the special forms in this library without the Scribble reader by using @seclink["parse-string" #:doc '(lib "scribblings/reference/reference.scrbl")]{here strings} instead. However, it is not possible to extract accurate source location information with here strings, so this is not recommended. @subsection[#:tag "embedding_forms"]{Embedding C} @defform*[[(declaration-list #:typedef (type-id ...) src-string ...+) (declaration-list src-string ...+)]]{ Parses the concatenated @scheme[src-string] fragments as a C program and expands into a list of C declaration nodes.} @defform*[[(declaration #:typedef (type-id ...) src-string ...+) (declaration src-string ...+)]]{ Parses the concatenated @scheme[src-string] fragments as a single C declaration and expands into a C declaration node.} @section[#:tag "include"]{Including C Externally} @;XXX: document include-c @section[#:tag "pseudo-c"]{S-Expression Syntax} For now, this library only provides a few convenience forms for constructing AST nodes. Eventually I intend to create a ``Parenthetical C'' language with an S-Expression-based alternative syntax for the whole of C. @deftogether[[ @defform/subs[#:id typedef (typedef type alias-id) ([type struct type-id])] @defform*/subs[#:id struct [(struct tag-id) (struct tag-id (struct-field ...)) (struct (struct-field ...))] [(struct-field [type field-id] field-id)]] @defform*/subs[#:id union [(union tag-id) (union tag-id (union-variant ...)) (union (union-variant ...))] [(union-variant [type variant-id] variant-id)]] @defform*/subs[#:id enum [(enum tag-id) (enum tag-id (enum-variant ...)) (enum (enum-variant ...))] [(enum-variant [variant-id expr] variant-id)]] ]] @defproc[(array [type type?] [size expr?]) type:array?]{} @defproc[(pointer [type type?]) type:pointer?]{}