Related articles |
---|
Complete macro expansion with cpp peter.mathes@gmx.de (2005-02-12) |
Re: Complete macro expansion with cpp RLake@oxfam.org.uk (Rici Lake) (2005-02-13) |
Re: Complete macro expansion with cpp skandgoe@gwdg.de (Skandinavisches Seminar) (2005-02-13) |
Re: Complete macro expansion with cpp codeworker@free.fr (2005-02-16) |
Re: Complete macro expansion with cpp codeworker@free.fr (2005-02-16) |
Re: Complete macro expansion with cpp peter.mathes@gmx.de (peter.mathes@gmx.de) (2005-02-16) |
From: | codeworker@free.fr (Cedric LEMAIRE) |
Newsgroups: | comp.compilers |
Date: | 16 Feb 2005 20:50:07 -0500 |
Organization: | http://groups.google.com |
References: | 05-02-059 |
Keywords: | C, macros |
Posted-Date: | 16 Feb 2005 20:50:07 EST |
I propose you to use CodeWorker, a parsing tool and a source code
generator, and to run it as a program transformer. CodeWorker is
distributed under LGPL and is available at
"http://www.codeworker.org".
I wrote you the program transformation script for what you are
expecting.
Type:
codeworker -translate macro_expansion.cwp myFile.c myFile.c
with "macro_expansion.cwp" being:
// what you parse is what you write to the output
#implicitCopy
substitute_define ::=
// ignore C/C++-like comments and whitespaces
// between BNF terminals and non-terminals
#ignore(C++)
// look for every '#define' in the C file
[
->[
// be careful! a constant string might
// have '#define ...' inside!
#readCString
|
'#'
#readIdentifier:"define"
// here we are
#readIdentifier:sDefine
// do not ignore comments and
// whitespaces anymore
#!ignore
[
// do not handle
// parameterized macros
'('
// jump to the end of line
// (filtering '\\\n')
->['\\' ['\r']? '\n' #nextStep >heck(false) | '\n']
|
handle_define(sDefine)
]
]
]*
// copy the rest of the file
->#empty
;
// explore the value, modify it if needed and register it
handle_define(sDefine : value) ::=
// jump to the first non-whitespace character
[' ' | '\t']*
=> local iStart = getOutputLocation();
[
// is the token an identifier?
#explicitCopy // do not copy what is parsed
#readIdentifier:sValue
[
// is this identifier a preproc definition?
>heck(this.macros.findElement(sValue))
// yes, substitute (template-based script)!
=> { @@this.macros[sValue]@@ }
|
// no, write the word
=> { @@sValue@@ }
]
|
// backslash before and end-of-line: continue!
'\\' ['\r']? '\n'
|
// continue while not a regular end-of-line
~[['\r']? '\n']
]*
// register the macro, after aventual changes
=> local sValue = getLastWrittenChars($getOutputLocation() -
iStart$);
// if no value, default is 1
=> if !sValue sValue = 1;
=> insert this.macros[sDefine] = sValue;
['\r']? '\n' // consume the end-of-line
;
If you want to explore '#include "myInclude.h"' recursively, then
insert the follwing piece of code at line 32:
|
#explicitCopy
'#'
// recursive call into include files
#readIdentifier:"include"
#readCString:sFilename
// do we find the file amongst include paths?
>heck(sFilename.existFile())
// this include was already explored?
>heck(!this.includes.findElement(sFilename))
// no! register it as visited, and expand it
=> insert this.includes[sFilename];
// for the rest of the sequence, change
// the file to parse
#parsedFile(sFilename)
#implicitCopy
substitute_define
#implicitCopy
Note: the first time the include file is encountered, it is expanded.
peter.mathes@gmx.de wrote in message news:05-02-059...
> Hallo!
> I need to get all macro #definitions output to stdout or some file.
> The problem is:
> When I pre-process the following lines
>
> #define MACRO1 (1)
> #define MACRO2 (MACRO1)
>
> using cpp with the option '-dM' it outputs the same lines:
>
> #define MACRO1 (1)
> #define MACRO2 (MACRO1)
>
> But I need an output with the macros expanded completely. Something
> like this:
>
> #define MACRO1 (1)
> #define MACRO2 ((1))
>
> Any idea how to get this done?
Return to the
comp.compilers page.
Search the
comp.compilers archives again.