About Ravi
Premiers pas avec Ravi
Scheme Tutorial
Objets Scheme
Le shell ravi
Starting Ravi
Le module trace
Les ports d'E/S
The C Parser
load, require, modules
Système d'interruptions
Scheme compiler
C++ mode
Generating C++ Modules
La déclaration struct
Le type "C-object"
More information


The C Parser

The C-parser transforms transforms a character stream with legal C code into syntax trees. There are several functions to call the parser, according to the C code sniplet you expect, and to how the character character stream is presented, there are several different functions to use.

The most useful function to analyze a C program is c-parse-one . A call to this function reads one toplevel expression of C code from the current input port. Such an expression usually a declaration of a function or variable, or a definition. Note that the C syntax for declarations and definitions is very close: definitions contain the body for a function, an initial value for a variable.

Related information: input ports error handling

You can parse an entire file of C code:

  (trad-file sourcefile destfile)
The result in destfile is pretty-printed.

Parsing string sniplets with c++pat

Code sniplets - small pieces of code - often come along as strings. There are several functions to analyze string sniplets. Let's illustrate with two examples:

  :> (c++pat "float x;")
  =  (c-declare #f x float)
The argument of c++pat is a declaration, definition, or expression. The result is the corrresponding abstract representation. There is an optional first argument:

  :>(c++pat "<class ps>"  "ps a,*b=&a;")
  = ((c-declare #f a ps) (c-declare #f b (* ps) (& a)))
The first argument, inspired from template arguments, declares types used in the expression.

There are several variants of c++pat to analyze strings containing sniplets that are not declarations or expressions:

  • c++patl for a list of declarations or expressions.
  • c++pati for a statement (instruction).
  • c++paty for a type.
A more sophisticated example analyzing a function type:

:>(c++paty "<class ps,class complex>"  "void (*func)(ps,complex)")
= (c-dcl #f func (* (-> ((c-dcl #f () ps) (c-dcl #f () complex)) void)))

ATTENTION c++pat is a macro function that works only for constant strings!

If the sniplet string is the value of a variable - which always is the case when analyzing user input - then you use the more general function cpp-pattern

(cpp-pattern c hd s) Arguments:

  • s is the string to analyse
  • c indicates what to expect
    • e - expression or declaration, as for c++pat and for c-parse-one
    • l - a list of these
    • i - a statement (instruction)
    • t - a type, as for c++paty
    • ee - an expression that is not a declaration. This is for annoying ambiguities.
  • hd is the "head" for type declarations.
Example: (cpp-pattern 't "<class complex>" "complex*tp[]")

Abstract format access functions

  • dcl-name
  • dcl-type
  • dcl-ivalue?
  • dcl-storage-class
  • function-type?
  • qual-type?

Unparsing: translating abstract syntax to text

When a metaprogram has constructed the abstract tree of a synthesized program, the you usually want to output it in text form, ready for compilation.

Main functions - all these functions have 2 arguments; the first argument is the expression to print, the second argument is the current indentation - you will usually use 0.

  • (d-decl-sc x c)
  • (d-expr x c)
  • (d-compound l c)
  • (d-if x c),
  • d-for, d-while, d-switch, ...