2

C ++ソースファイルを反復処理し、変数タイプの後に正しいC ++変数名を検索するだけの場合、変数の欠落や誤った変数が発生し、適切なパーサーを克服する必要がありますか?

単純なテストケースはすべてのプリミティブを正しく取得しましたが、考慮していない無関係なケースが多数ある場合は、あまり時間をかけたくありません。これまでのところ、私は単にキーワードを探し、次の単語を取得し、名前の妥当性をチェックしています。変数名の有効性を確認する以外は正規表現を使用していません。正規表現は解析に十分ではないことを理解しています。

私のプログラムはJavaで書かれています。このプログラムのJavaターゲットバージョンを実行し、JavaParserを使用しました。これは正常に機能しました。ANTLRなどは、ソース内のプリミティブ変数を見つけるだけではやり過ぎだと思います。

4

3 に答える 3

3

1行で宣言された複数の変数を試しましたか?

int i, *j, k[2];

関数のパラメータ宣言はどうですか?

int func(int i, int j);

typedefはどうですか?

typedef int Integer;
Integer i;

適切なパーサー (および非常に複雑なパーサー) を使用せずに C++ を解析するのは困難です。

于 2013-01-10T18:06:59.883 に答える
2

基本的な C++ 宣言構文は、単純な左から右への構文ではありません<type> <identifier>

これが C++ の構文である場合、たとえば、int の配列を宣言すると、型のint[]後に識別子が続きます。

int[] foo

関数を宣言するということは、次のような関数型を記述し、int()その後に識別子を付けることを意味します。

int() foo;

代わりに、C から継承された C++ の構文は、「宣言は使用を模倣する」と呼ばれるスタイルです。

<type_identifier> <expression>;

宣言内の式は、宣言されたエンティティを使用する方法のように見え、その使用法によって指定された型が生成されます。

例:

int i;      // now the expression i has the type int
int (ii);   // now the expression (ii) has the type int, and so ii has the same type
int j();    // now the expression j() has type int, and therefore j has a function type
int k[3];   // now the expression k[3] has type int, and therefore k has an array type
int (*l)(); // the expression (*l)() has type int, and therefore (*l) has a function type, therefore l has a pointer-to-function type.

などなど、配列のインデックス演算子、関数呼び出し演算子、括弧、逆参照演算子、ビットごとの AND 演算子、そしておそらく私が覚えていないいくつかの演算子を含む任意の複雑さがあります。さらに、さまざまなポイントで const と volatile を投入できます。

さらに悪いことに、宣言構文は初期化子の構文と奇妙な相互作用をする可能性があります。たとえば、「最も厄介な解析」は、初期化子の括弧が関数型の宣言に関係する括弧と混同されている状況です。括弧が型式の一部なのかイニシャライザの一部なのかは、内部で使用されている名前によって異なります。

struct bar {};
int baz() { return 1; }

int foo(bar());  // declaration of function (most vexing parse)
int foo2(baz()); // declaration of variable (initialized with baz())

もちろん、他の人が言及した問題もあります。typedef/type エイリアス、マクロ、ネストされた宣言、複数の宣言など。

于 2013-01-10T22:15:26.603 に答える
2

関数のパラメーター、同じ行で宣言された複数の変数、別の行の型と変数名などについてはどうですか?

于 2013-01-10T18:06:29.590 に答える