0

最近、Cの語彙および意味エラーの例を示す必要がありました。次の例を示しました。

以下は字句エラーだと思いましたが、

int a#;

そして、セマンティックエラーについては、次の例を示しました。

int a[10];
a=100;

しかし今、私は両方が実際に構文エラーであるかどうか少し混乱しています。これらのエラーについてのアイデアを教えてください。

4

1 に答える 1

4

まず、エラーの分類 (語彙、構文、意味、語用として) は、細部において何らかの形で恣意的です。

lexerによって検出されたエラーとして字句エラーを定義すると、不正な数値が 1 になる可能性があります12q4z5。または禁止文字を含む名前$

構文エラーは、構文解析時に検出されたエラーとして定義できます。ただし、C は厳密には文脈自由言語ではなくそのパーサーは文脈情報を保持します (たとえば、シンボル テーブル)。

a #とはすべて;有効な語彙素でa#;あるため、字句エラーではありません。

実際#には、前処理時に最も役立ちます。解析されるのは、実際には前処理された形式であり、ユーザーが指定したソース コードではありません!

多くのセマンティック エラーは、整数引数がないなどの未定義の動作の概念に関連しています。printf("%d")または、あなたの場合、境界外アクセスprintf("%d\n", a[1234]);

一部の (すべてではない) セマンティック エラーまたはプラグマティック エラーは、静的分析ツールを使用して見つけることができます。最新のコンパイラ (すべての警告が有効になっている場合) は、いくつかのことを行うとさえ言えます。あなたの例a=100;型付けエラーです(これは、 Cコンパイラが構文解析時にそれを検出するため、構文として、またコンテキストフリープロパティではない型に関連するため、セマンティックとして任意に呼び出すことができます)。また、 Frama-Cなどのより特化した静的解析ツールがあり、GCC コンパイラを拡張またはカスタマイズして (たとえば、ドメイン固有言語MELTを使用して) 自分のものを追加することができます (たとえばTALPO など)。

hereのように巨大なローカル変数を宣言することは、実用的なエラーである可能性があります。おそらく、1T バイトの RAM メモリが一般的になるとき、スタックは何ギガバイトもあるでしょうから、その例は実行できますが、今日では実行できません。

于 2013-03-22T12:43:01.560 に答える