hara
hara

Reputation: 3374

XTEXT: rule for preprocessor instructions

i'm trying to write a rule for preprocessor instructions in XText. currently i implemented it like this way:

preproc:
    type=PREPROCESSOR_INCLUDE_TYPE val=(STRING | PREPROCESSOR_INCLUDE_VAL)| 
    type=PREPROCESSOR_DEFINE_TYPE | 
    type=PREPROCESSOR_SINGLE_PARAM_TYPE val=ID|
    type=PREPROCESSOR_NONE_PARAM_TYPE
;


terminal PREPROCESSOR_INCLUDE_TYPE: '#include'| '#import';

terminal PREPROCESSOR_INCLUDE_VAL: ' '+ '<'->'>';

terminal PREPROCESSOR_DEFINE_TYPE: '#define' -> '\n';

terminal PREPROCESSOR_SINGLE_PARAM_TYPE: '#undef' |'#ifdef' |'#ifndef' |'#pragma';

terminal PREPROCESSOR_NONE_PARAM_TYPE: '#else' | '#endif';

I do not really like this solution, but it is the only one that works of all the ones I tried. There is a smarter way to write a rule for preprocessor instructions?

How could i split the PREPROCESSOR_DEFINE_TYPE rule to separate the preprocessor instruction type(#define) from its value?

thanks a lot

EDIT

what I want to capture with these rules are the typical preprocessor instructions. For example:

#include "fileName"
#import <fileName>

#define IDENTIFIER
#define IDENTIFIER WHATEVER + YOU - WANT !

#undef IDENTIFIER

#else
#endif

What would be nice to have is to split the preprocessor type from its value in all the different cases

Raffaello.

Upvotes: 0

Views: 849

Answers (2)

Aykut Kllic
Aykut Kllic

Reputation: 927

Basically you can't (out of the box) create languages that do pre-processing with XText. XText generates it's code for one grammar. Preprocessing requires 2 fitting grammars.

Here are the challenges http://www.eclipse.org/forums/index.php/mv/msg/366839/894493/#msg_894493

Just think for the case:

a = 1 
#ifdef something
    +1
#endif
;

So it is very inefficient to express all these in one grammar, hence makes it impractical in xtext. So without its support for multi-step, languages like C, make are out of its scope.

Upvotes: 1

Zolt&#225;n Ujhelyi
Zolt&#225;n Ujhelyi

Reputation: 13858

If I understand your question, you want an AST node for define rules, that has an attribute with the rest of the rule, but does not contain the #define keyword.

The problem with the until rule or the possible negation (!) rules are, that they cause conflicts with the whitespace characters between the #define and the instruction, so that could not be solved easily.

However, you could define a new terminal, that starts e.g. with a letter or _, and ends with a newline, that could be added to your language, something as follows:

PREPROCESSOR_DEFINE_TYPE: '#define' instruction=Content 
;

terminal Content:
    ('a'..'z'|'A'..'Z'|'_') -> '\n'
;

I did not test the solution, but it throws no errors in my Xtext editor, and is quite similar to the definition of ID parameters from Terminals.xtext, so I believe it should be close to what you need.

Additionally, I don't think you have to define all the preprocessor types as terminals, as this way they become much more low-level constructs; I'd define as much as them as non-terminal rules as possible.

Upvotes: 0

Related Questions