XTEXT:预处理器指令的规则

发布于 2024-11-19 15:36:51 字数 1031 浏览 3 评论 0原文

我正在尝试为 XText 中的预处理器指令编写规则。目前我是这样实现的:

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';

我不太喜欢这个解决方案,但它是我尝试过的所有解决方案中唯一有效的解决方案。有没有更聪明的方法来编写预处理器指令的规则?

我如何拆分 PREPROCESSOR_DEFINE_TYPE 规则以将预处理器指令类型(#define)与其值分开?

非常感谢

编辑

我想用这些规则捕获的是典型的预处理器指令。例如:

#include "fileName"
#import <fileName>

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

#undef IDENTIFIER

#else
#endif

在所有不同的情况下,最好将预处理器类型与其值分开

Raffaello。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心头的小情儿 2024-11-26 15:36:51

基本上,您无法(开箱即用)创建使用 XText 进行预处理的语言。 XText 生成一种语法的代码。预处理需要 2 个拟合语法。

这是挑战
http://www.eclipse.org/forums/ index.php/mv/msg/366839/894493/#msg_894493

想想看:

a = 1 
#ifdef something
    +1
#endif
;

原来如此用一种语法来表达所有这些是非常低效的,因此在 xtext 中是不切实际的。因此,如果不支持多步,像 C、make 这样的语言就超出了它的范围。

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.

ヅ她的身影、若隐若现 2024-11-26 15:36:51

如果我理解您的问题,您需要一个用于定义规则的 AST 节点,该节点具有包含规则其余部分的属性,但不包含 #define 关键字。

until 规则或可能的否定 (!) 规则的问题是,它们会导致与 #define 和指令,所以不能轻易解决。

但是,您可以定义一个新终端,例如以字母或 _ 开头,以换行符结尾,可以将其添加到您的语言中,如下所示:

PREPROCESSOR_DEFINE_TYPE: '#define' instruction=Content 
;

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

我没有测试该解决方案,但它在我的 Xtext 编辑器中没有抛出任何错误,并且与 Terminals.xtext 中 ID 参数的定义非常相似,所以我相信它应该接近您所需要的。

此外,我认为您不必将所有预处理器类型定义为终端,因为这样它们就会变得更加低级构造;我会尽可能多地定义非终结规则。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文