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

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

拉斐尔。

4

2 回答 2

1

基本上,您不能(开箱即用)创建使用 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 这样的语言就超出了它的范围。

于 2014-07-16T20:24:46.560 回答
0

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

until规则或可能的否定( )规则的问题!是,它们会导致与#define指令之间的空白字符发生冲突,因此无法轻易解决。

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

PREPROCESSOR_DEFINE_TYPE: '#define' instruction=Content 
;

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

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

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

于 2011-07-14T09:40:09.630 回答