2017-05-20 4 views
2

私は現在、C#のANTLR4にプリプロセッサを実装しようとしていますが、これに関する情報を見つけるのにかなりの手間があります。 私はC#プロジェクトのGitHubのソースを掘りすると、本当に悲しいことに成功していたしませんでした...トークンのオフセットを除去せずにANTLR4に前処理レイヤーを追加する

私の目標は、トークン・オフセットを保持することである(したがって、その列と行は、前処理ストリームでのスローされません) おおよその例を説明:あなたは正しいドキュメントに私を指すか、簡単な例ソリューションどこか

親切によろしくを提供することができます

#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 

希望、マルコ

PSそれに注意してください:私は、ANTLR4に既にプリプロセスされたストリームを渡すソリューションを探しません。

答えて

0

ストリームをどのようにプリプロセスするかによって異なります。すべてのプリプロセッサ行(および#ifdefなどで表示されない行)を改行で置き換えると、全体の行番号が乱されることはありません。実際には、通常の解析実行の外で前処理を実行することをお勧めします(例えば、入力ストリームは既にそれを行います)。

年前I wrote a Windows .rc file parser。これらのリソースファイルは、Cヘッダファイルのように多くの面にあります。したがって、プリプロセッサ、文字列化とチャージングサポートによるマクロ処理、さらにいくつかのことが必要になります。私はANTLR 2.7のためにそれを書いた(現在はと表示されています)どのくらい古いです:-))。しかし、私はそれが良い例であると信じています(#includeを含む)前処理作業を行う方法。

+0

それはマクロを展開するときにテキストの場所を変更する – X39

1

解析するプリプロセッサディレクティブの2つの戦略があります。

  • ワンステップ処理
  • ツーステップ処理

は、第二の方法が原因による台無しテキストの場所のあなたのために適切ではありませんマクロに拡大する。

最初の方法では、プリプロセッサディレクティブを単一の共通レクサーでトークン化して、正しいテキストの場所を保存することができます。

Objective-C grammarと記事「Objective-Cでは解析プリプロセッサディレクティブ」でOne-step Processingを参照してください:

ワンステップの処理は、第一言語の指示とトークンの同時解析を含みます。 ANTLRは、タイプによってトークンを分離するチャネルのシステムを導入しています。たとえば、第1言語のトークンと隠れたトークン(空白とコメント)。ディレクティブトークンは別の名前付きチャネルに追加できます。

場合によっては、ディレクティブトークンを共通チャネルに含めることもできます。もっと便利です。例えばトークンNS_OPTIONSとルールenumSpecifierを参照してください。

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

また、単純な文字列としてプリプロセッサディレクティブを解析し、後でそれを解析することができます: DEFINE: '#define' ~[\r\n]*を。

Objective-C to SwiftコンバータのSwiftifyでは、ワンステップ処理手法を使用しています。私はすぐにObjective-C文法を更新するつもりです。

+0

X39は私の答えのための有効なポイントを提起しました:どのように複数行のマクロ展開を扱いますか?そのような場合に元の行番号を維持する方法を説明する単語をここに追加できますか? –

関連する問題