将PreProcessing层添加到ANTLR4而不删除令牌的偏移量

时间:2017-05-20 01:24:38

标签: c# antlr4 preprocessor antlr4cs

我目前正尝试将预处理器实现为ANTLR4 for c#,并且在查找有关此问题的任何信息时遇到了很多麻烦。 我通过C#项目的GitHub源代码挖掘并不是真的成功了......

我的目标是保留令牌偏移量(以便预处理流不会抛出列和行) 示例粗略解释:

 #define foo(bar) foobar(bar + bar * bar / 0.2)
 int smthng = 2;
 smthng += foo(12); //the ; should be at the same spot like the macro was a function

希望您能指出正确的文档或在某处提供简单的示例解决方案

亲切地问,Marco

PS 要注意:我不寻求一种解决方案,我将已经预处理的流传递给ANTLR4,因为它会摆脱代码的偏移。

2 个答案:

答案 0 :(得分:1)

预处理程序指令解析有两种策略:

  • 一步处理
  • 两步处理

第二种方式不适合您,因为宏扩展导致文本位置损坏。

使用第一种方法,您可以在单个公共词法分析器中对预处理程序指令进行标记,从而保存正确的文本位置。

请参阅“在Objective-C中解析预处理程序指令”一文中的Objective-C grammarOne-step Processing部分:

  

一步处理涉及同时解析主要语言的指令和令牌。 ANTLR引入了一个按其类型隔离令牌的通道系统。例如,主要语言的标记和隐藏标记(空格和注释)。可以将指令令牌添加到单独的命名通道中。

在某些情况下,指令令牌也可以包含在公共频道中。它更方便。请参阅令牌NS_OPTIONS和规则enumSpecifier,例如:

enumSpecifier
    : 'enum' (identifier? ':' typeName)? (identifier ('{' enumeratorList '}')? | '{' enumeratorList '}')
    | ('NS_OPTIONS' | 'NS_ENUM') LP typeName ',' identifier RP '{' enumeratorList '}'
    ;

您还可以将预处理程序指令解析为简单字符串,并在以后解析它: DEFINE: '#define' ~[\r\n]*

Swiftify,Objective-C到Swift转换器,我们使用一步处理方法。我将很快更新Objective-C语法。

答案 1 :(得分:0)

取决于您如何预处理流。如果您使用换行符替换所有预处理器行(以及由于#ifdef等而不可见的那些行),您的整个行号将不会被搞砸。实际上我甚至建议在正常的解析运行之外进行预处理(例如输入流就已经这样做了)。

多年前I wrote a Windows .rc file parser。这些资源文件在很多方面都像C头文件一样,所以你需要一个预处理器,带有字符串化和charizing支持的宏处理以及更多的东西。我为ANTLR 2.7编写了它(现在你看到如何旧的:-))。但我仍然相信这是一个很好的例子,如何使预处理工作(包括#include)。