解析前に置き換えてはならないマクロに依存するコードを解析したいと思います。
解析後、次のことを行います。
- コードをきれいに印刷する
- いくつかの情報を抽出する
したがって、文法を満たすためにマクロを拡張しながら、何らかの形でマクロを「保持」する方法が必要になると考えました。
私が必要とするものに似たいくつかのサンプルコード:
SomeFile には、いくつかのマクロが定義されています。
// other code...
// macro definitions look like this:
// a bunch of #define statements inside {}
// So every "{" start a macro scope (except inside strings of course)
{
#define ASSERT if ((
#define IS_TRUE )==true) throw new AssertionFailed();
#define IS_FALSE )==false) throw new AssertionFailed();
#define MULTI_LINE_MACRO they \
always end in \
backslashes except the last line
}
// other code...
解析したいファイルで:
// similar to "#include" in C
import SomeFile, SomeOtherFile ;
function Myfunction : void
ASSERT 1 == 1 IS_TRUE
end_function
たとえば、次のようなものに変換したいと思います。
import SomeFile, SomeOtherFile ;
function Myfunction : void
ASSERT
1 == 1
IS_TRUE
end_function
また、マクロが正しく使用されているかどうかも確認したいと思います (いくつかの「既知の」マクロについて):
import SomeFile, SomeOtherFile ;
function Myfunction : void
// this should not be considered ok although it will compile fine
// It should be checked that ASSERT is followed by an expression followed by IS_TRUE
ASSERT 1 == 1 ));
// ^
// error should be here
end_function
理想的には、制限が適用されるマクロ定義ソース ファイルで構成可能にする必要があるため、チェックを動的に行うことができれば有利です。
{
#define ASSERT if ((
#define IS_TRUE )==true) throw new AssertionFailed();
#define IS_FALSE )==false) throw new AssertionFailed();
// ideally I could define some semantic constraints here:
//@@rule:: assertion : ASSERT expression (IS_TRUE|IS_FALSE) => statements
//this should place the "assertion" rule in the statements section of the grammar
}
// other code...