This library provides parsers for the C programming language and its preprocessor as described in Annex A of SO/IEC 9899:2017.
This library uses package-local nicknames. It has been tested in SBCL.
This section discusses different modules provided by the library:
- *The Interface Package
- This module provides a high-level interface consisting of convenience functions for parsing and evaluating CPP or C inputs or doing multiple of those things at once.
- *The Preprocessor Language
- This module provides a parser, a meta-model and an evaluator for the C preprocessor language.
- *The C Language
- This module provides a parser and a meta-model.
The ability to parse the C preprocessor language is provided by
the language.c.cpp.parser
systems.
After loading that system, a inputs such as strings and files can
be parsed using the parse
generic function:
(language.c.cpp.parser:parse "#define foo 1 + 2" 'list)
(:GROUP (:PART (((:DEFINE NIL :NAME (:IDENTIFIER NIL :NAME "foo" :BOUNDS (8 . 11)) :REPLACEMENT ((:NUMBER NIL :VALUE "1" :BOUNDS (12 . 13)) (:PUNCTUATOR NIL :WHICH :+ :BOUNDS (14 . 16)) (:NUMBER NIL :VALUE "2" :BOUNDS (16 . 17))) :BOUNDS (1 . 17))))) :BOUNDS (0 . 17)) NIL T
The second argument is a “builder” which controls the construction
of the parse result (The “builder” concept, related protocols and
their implementation can be found in the
architecture.builder-protocol system). In the example above, the
list
builder has been used to produce a simple list-based
representation of the parse tree.
Another possibility is producing a parse tree consisting of
instances of classes defined in the language.c.cpp.model
package:
(language.c.cpp.parser:parse "#define foo 1 + 2"
(make-instance 'language.c.cpp.model:builder))
#<LANGUAGE.C.CPP.MODEL:GROUP {10023739B3}> NIL T
(let ((ast (language.c.cpp.parser:parse
(format nil "#ifdef foo~@
#define foo 1~@
foo bar~@
baz fez~@
#endif~@
")
(make-instance 'language.c.cpp.model:builder)))
((environment (make-instance 'language.c.cpp.evaluator::environment))))
(let ()
(language.c.cpp.evaluator::evalute ast e *standard-output*)
e))