Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-dev] Re: Parsing code under inactive #if or #ifdef

Thanks everybody for this dicussion. At least, I know that I'm not
alone who wants this feature :-)
I also agree with 3rd aprroach (maybe with some small difference).

Chris,
I've seen that IBM is commited to start this task after Ganymede? Is
it still valid?

Well, I beg you pardon me for the thoughts below since I'm new for
this AST/DOM world and absolutely not a compiler/parser expert. So,
probaly, I just can't see underwater rocks. Nevertheless, let me share
those ideas.

I feel (yes, just feel, with no proves yet), that everything a litle
bit complicated.
Let's take a look at some simple case:

#ifdef MY_COOL_FEATURE
  void foo(int a, void * b, char c);
#else
  void foo(int a, char b);
#endif

I suppose current implementation should be enough for such a case.
Parser should just create 2 different declarations. Am I wrong?

Here is more complex example:
void foo(int a,
#ifdef MY_COOL_FEATURE
   void * b,
#endif
char c);

>From the end-user perspective there still 2 declarations. So, let's
just generate them. It may be a problem with current implementation.
But I suppose we just need some small modifications in parser and preprocessor.
It seems that having those conditional directives creates a binary
tree for each of them (empty or absent #else is also a path). How can
we parse it?
On my mind it would be great to have some kind of "unwinding" for a
lexer/preprocessor: when it encounters a conditional directive, it
stores current context (defined macro, etc.) and continues to positive
branch. At the end of it, it restores the context (thus deleting new
defined macro). Parser should be able to detect that context
restoration and trigger new parsing procedure on negative branch
starting from the same place. Thus it will create a new declaration or
definition.
I have to say few words about "same place". On my mind, this should be
some kind of the beginning of nearest previous declaration (in terms
of GNUCSourceParser.translationUnit() ).
So the algorithm will be:
  1) get new declaration.
  2) if parser has encountered a branch and there still not parsed
branches inside it, get new declaration again

void foo(int a,
#ifdef MY_COOL_FEATURE
   void * b,
#ifdef MY_SECOND_FEATURE
   float d,
#endif
#endif
char c);

For this example, parser
  1) creates a declaration of foo for all positive branches. They are
marked by preprocessor as parsed
  2) creates a declaration of foo for innermost negative and others
positive branches
  3) creates a declaration of foo for all negative branches

I even do not see any need to significally modify the AST structures.
The conditionals that affect the AST node can be figured out even
later. Namely, all the OVERLAPPING directives are affecting the
declaration/definition. Thus, if you have offset and length of the
node, you can find all the directives that overlaps it.

Dmitry



2008/9/11 Dmitry Smirnov <divis1969@xxxxxxxxx>:
> Hi,
>
> I'm trying to use AST/PDOM for parsing a project in goal to build
> browsable view of the code (outside of Eclipse, some set of WEB
> pages).
>
> For this purpose I would like to have inactive code to be parsed too.
> As I can see, now this is prevented by CPreprocessor class. Method
> executeIfdef() and other similar methods call
> skipOverConditionalCode().
>
> I would like to propose some enchancement for this. I believe some
> scanner options could be added that changes default behaviour. If this
> option is active, CPreprocessor will not call
> skipOverConditionalCode() thus making parser to handle all the code.
>
> I suppose, some methods should also be changed (like values of macro
> defined inside active/inactive branches).
>
> What do you think about such feature? Perhaps, CDT already have some
> plans for similar enchancement?
>
> I'm going to test this approach with CDT 5.0. If you have some
> thoughts that could help me with it, please let me know.
>
> Dmitry
>


Back to the top