最近、Cの語彙および意味エラーの例を示す必要がありました。次の例を示しました。
以下は字句エラーだと思いましたが、
int a#;
そして、セマンティックエラーについては、次の例を示しました。
int a[10];
a=100;
しかし今、私は両方が実際に構文エラーであるかどうか少し混乱しています。これらのエラーについてのアイデアを教えてください。
最近、Cの語彙および意味エラーの例を示す必要がありました。次の例を示しました。
以下は字句エラーだと思いましたが、
int a#;
そして、セマンティックエラーについては、次の例を示しました。
int a[10];
a=100;
しかし今、私は両方が実際に構文エラーであるかどうか少し混乱しています。これらのエラーについてのアイデアを教えてください。
まず、エラーの分類 (語彙、構文、意味、語用として) は、細部において何らかの形で恣意的です。
lexerによって検出されたエラーとして字句エラーを定義すると、不正な数値が 1 になる可能性があります12q4z5
。または禁止文字を含む名前$
構文エラーは、構文解析時に検出されたエラーとして定義できます。ただし、C は厳密には文脈自由言語ではなく、そのパーサーは文脈情報を保持します (たとえば、シンボル テーブル)。
a
#
とはすべて;
有効な語彙素でa#;
あるため、字句エラーではありません。
実際#
には、前処理時に最も役立ちます。解析されるのは、実際には前処理された形式であり、ユーザーが指定したソース コードではありません!
多くのセマンティック エラーは、整数引数がないなどの未定義の動作の概念に関連しています。printf("%d")
または、あなたの場合、境界外アクセスprintf("%d\n", a[1234]);
一部の (すべてではない) セマンティック エラーまたはプラグマティック エラーは、静的分析ツールを使用して見つけることができます。最新のコンパイラ (すべての警告が有効になっている場合) は、いくつかのことを行うとさえ言えます。あなたの例a=100;
は型付けエラーです(これは、 Cコンパイラが構文解析時にそれを検出するため、構文として、またコンテキストフリープロパティではない型に関連するため、セマンティックとして任意に呼び出すことができます)。また、 Frama-Cなどのより特化した静的解析ツールがあり、GCC コンパイラを拡張またはカスタマイズして (たとえば、ドメイン固有言語MELTを使用して) 自分のものを追加することができます (たとえばTALPO など)。
hereのように巨大なローカル変数を宣言することは、実用的なエラーである可能性があります。おそらく、1T バイトの RAM メモリが一般的になるとき、スタックは何ギガバイトもあるでしょうから、その例は実行できますが、今日では実行できません。