構文とセマンティクスの違いは何ですか?


87

私は常に、言語の構文を参照することは、言語のセマンティクスを参照することと同じだと考えてきました。しかし、どうやらそうではないことを知らされました。違いは何ですか?



6
「無色の緑のアイデアは猛烈に眠る」は構文的には問題ありませんが、意味的な意味はありません。en.wikipedia.org/wiki/Colorless_green_ideas_sleep_furiouslyを
CesarGon

この質問をするための+1。私は同じことを疑問に思っていて、これをインターネットで検索するのが面倒で、明らかに決して尋ねませんでした。
KK。

多かれ少なかれ、セマンティクスはインスタンスのタイプ、他のインスタンスとの関係、およびインスタンス間に存在する保証です。構文は、文字列を介してこれらのことを宣言する方法です。多かれ少なかれ。
デボップ

回答:


106

セマンティクス〜意味

構文〜シンボリック表現

したがって、異なる言語で記述された2つのプログラムは同じことを行うことができますが(セマンティクス)、プログラムの記述に使用されるシンボルは異なります(構文)。

コンパイラーは構文をチェックし(コンパイル時エラー)、言語規則からセマンティクスを導き出します(構文を機械語命令にマッピングします)が、すべてのセマンティクスエラーを見つけません(実行時エラー、計算など)コードにはadd 2ではなくadd 1と表示されるため、間違った結果になります。


2
エラーチェックは、構文とセマンティクスを区別するための基準ではありません。コンパイラは、構文エラー(セミコロンの欠落など)とセマンティックエラー(これらのオペランドにx + y適切な+演算子がない場合など)の両方を診断できます。2ではなく1を追加することを論理エラーと呼びます。
キーストンプソン

3
@Keith-ただし、ロジック(「論理エラー」など)はセマンティクスです。コンパイラはいくつかのセマンティックチェック、特に型チェックを行うことができます。そのため、コンパイラは構文エラーを見つけるだけではなく、クリスは「すべてのセマンティックエラーを見つけられないだけ言いました。「」を見つけます
Steve314

1
@ Steve314:同意した。しかし、コンパイラが検出する必要のあるエラーと検出する必要のないエラーを明確に区別したい場合、「セマンティック」対「論理」はその区別を表す良い方法だと思います。
キーストンプソン

4
@KeithThompson実際には、理論上、十分に強力で強力な(つまり、依存する)型システムを持つ言語のコンパイラーまたはインタープリターは、コードの任意のプロパティ(該当する場合は停止問題を修正)をチェックできるため、セマンティックエラーを「checkable」と「uncheckable」は、一般的には意味がありません。
プサリアンの炎

@ Ptharien'sFlame私はあなたの声明の「理論上の」部分を強調することによって、この議論を少しの間雲から引き離すつもりです。実際には、コードにセマンティクスを適用するには、コンパイラーに機能に関する手がかりを与えるための追加の構文が必要です。追加のセマンティックチェックはコスト(複雑さ/読みやすさ)として発生します。言語がすべてのセマンティックエラーをチェックするのに十分強力であると述べることは、法律システムがすべての犯罪を防ぐのに十分に完璧であると言うようなものです。個人的には、私は安全よりも自由を好みますが、それがこれを「宗教的な」トピックにしているのです。
エヴァンプライス

35

実際には、2つのレベルではなく、3つのレベルがあります。

  • 字句レベル:文字要素を組み合わせて言語要素を生成する方法(iおよびをf生成するif
  • 構文レベル:どの言語要素は、(言語表現を生成するために結合されif(42==answerおよび)条件文を生成します)
  • 意味レベル:意味を形成するために言語式をCPU命令に変換する方法(条件ステートメントは、ブール式の結果に応じて1つのブランチまたは他のブランチを実行できます)

10
字句解析段階と構文解析段階の分離は完全に人為的なものであり、最適化にすぎません。また、語彙素の有限なフラットセットが定義されていない言語もありますが、それでも、明確に定義された構文があります。したがって、構文の一部として語彙素を定義したいのですが、これは独立したエンティティではありません。
SKロジック

@ SK-logic:多くの言語では、変数名を形成する許可または禁止された語彙素のリストが指定されています。したがって、分離は理にかなっています。
mouviciel

5
@mouviciel、それは最適化としてのみ意味があります-そうでなければ、あなたはただのValidIdentifierようなものとして定義できる端末を持っているでしょう![AnyKeyword] [Identifier](私はここでPEGのような表記法を使用しています)。そのような言語に別の字句解析パスは必要ありません。たとえば、GLRベースのC ++パーサーを参照してください。
SKロジック

2
@EvanPlaice、あなたは何について話しているのですか?私のポイントは、構文解析ではなく、字句解析が不要であり(実際に言語が制限される)ことです。
SKロジック

1
@ SK-logicあなたのコメントは、あなたが意図したものの反対を意味するものだと思います。レクサーだけが必要な場合について話していると思います-純粋に「通常の」または「コンテキストのない」言語のように。高レベルの言語では、レクサーは必要ないかもしれませんが、単一パスの構文検証を実行するための迅速な方法を提供します。レクサーステージをオフにするか完全に削除することが有益な場合が多いことに完全に同意します。
エヴァンプライス

18

言語の簡単な例を使って説明しますENGLISH

The glass drank Ben

構文的に正しいステートメントです。名詞、動詞などがあります。

しかし、この文には考えられるまたは正しい意味がないため、意味的に間違っています。


15

セマンティクスは、プログラミング言語の論理エンティティとその相互作用を記述します。構文は、これらが文字で表現される方法を定義します。

たとえば、ポインター演算の概念はCのセマンティクスの一部です。+and -演算子を使用してポインター操作を表現する方法は、その構文の一部です。

2つの言語のセマンティクスの一部を共有する場合もありますが、構文は大きく異なります(たとえば、C#とVB.NET-両方とも値型と参照型を使用しますが、それらを定義するために入力する文字は異なります)。それ以外の場合、2つの言語は構文的には似ていますが、セマンティクスは一致しません(JavaとJavaScriptを検討してください。類似性は初心者を混乱させることがよくあります)。


それでは、「パラダイム」はセマンティクスに関連していますか?パラダイムは、相互に関連するセマンティクスのセットですか?
グルシャン

1
@Gulshan、パラダイムは、セマンティクスなどの形式化されたものよりもはるかに広い概念です。パラダイムにはセマンティクスが含まれる場合がありますが、それはより多くの方法論、さらには哲学です。
SKロジック

6

構文は、言語のトークンを配置する方法です。セマンティクスは、それらのトークンが意味するものです(通常、トークンの特定の配置が意味するもの)。


5

プログラミング言語のみを参照するのか、プログラミングで使用される一般言語を参照するのかを指定しなかったため、私の答えはデータ言語(XML、RDF、データ型システムなど)についてです。

ブライアンL.ミークは、言語に依存しない標準(1995年)を作成するための7つのゴールデンルールの中で「ある言語の構文は別の言語のセマンティクスになり得る」と書いています。彼は、データの説明で使用されている「構文」と「意味」という言葉に言及しています。したがって、何らかのデータ形式の仕様でこれらの言葉に出くわした場合は、両方の単語を「Potrzebie」に置き換えて、解決する必要があることを明確にする必要があります自分にとっての意味。

少なくとも正確に指定されたデータでは、構文とセマンティクスの関係は、「エンコード」という用語で説明できます。セマンティックは構文でエンコードされます。録音はネストできるため、ある言語の構文は別の言語のセマンティクスです。データの領域を超えると、Umberto Ecoによって「無制限の記号化」と呼ばれるように、このネストは事実上無限になります。

例を挙げると:

  • XML構文(これらすべての括弧で囲まれたもの)は、セマンティクスとしてXMLインフォセット(抽象ツリー)を持つ構文です。
  • 構文としてのXMLインフォセットは、セマンティックとして、たとえばRDFグラフをエンコードするRDF / XMLドキュメントなどのXMLデータ形式でレコードを表現できます。
  • 構文としてのRDFグラフ(URI参照のあるもの)は、抽象リソースのグラフをセマンティックとしてエンコードします。
  • 構文としての抽象リソースのグラフは、概念モデルをセマンティックとしてエンコードします。

人々は通常、あるレベルで停止し、それをセマンティックと見なしますが、最終的には、人間が心の中でデータを解釈しない限り、最終的なセマンティックはありません。データの形式でセマンティックを表現しようとするとすぐに、構文になります。


4

BNF(Backus-Naur Form)または同様のもので記述できる場合、それは構文です。それができない場合、そうではありません。

一方、セマンティクスは、プログラム(またはソースコードの他のチャンク)の意味に関するものです。

また、2つの間の線がぼやけることもあります。

区別を理解する1つの方法は、プログラムの構文またはセマンティクスが正しくない場合に発生するエラーの種類を調べることです。

構文エラーとは、ソースコードが言語の文法に一致しないことです。たとえば、必要な場所にセミコロンがありません。

セマンティックエラーは、他の言語要件(たとえば、Cが「制約」と呼ぶもの)を満たさないことです。例では、書き込みをされる可能性がありますx + yどこxy互換性のないタイプがあります。言語の文法では、加算はのようsomething + somethingに見えますが、左右のオペランドの型に関する要件を表現するには十分ではありません。

(2が正しい場合に1を使用するなどの論理エラーは一般にコンパイラーによって検出されませんが、場合によってはコンパイラーが疑わしいコードについて警告することができます。)


0

構文は、(字句)記号の意味です。セマンティクスは、それらが意味するものです。

考慮してください:

C#:condition ? true_value : false_value
VB.NET:If(condition, true_value, false_value)
-異なる構文、同じセマンティクス。

C#:left_value / right_value
VB.NET:left_value / right_value
-同じ構文、異なるセマンティクス(整数用)。


0

構文は、文中の単語の文法的な配列、つまり単語の順序です。

(英語) ' cat dog boy 'および(プログラミング) ' hi.5 'は構文的に正しくありません

(英語) ' cat hugs boy 'および(プログラミング) '* 3.2 * 5 *'は構文的に有効です。

静的セマンティクスは、構文的に有効なステートメントに意味があるかどうかです。

(英語) ' I are big '(プログラミング)(python) ' 3 +' hi ' 'は構文的には正しいが、静的なセマンティックエラーがあります。

セマンティクスは、静的なセマンティックエラーのない、構文的に正しいシンボルの文字列に関連付けられた意味です。つまり、文は構文的にも意味的にも正しいですが、その意味は意図したものではない場合があります。

(英語)「飛行する飛行機は危険である可能性があります」には2つの意味があります。つまり、飛行機の飛行は危険であり、飛行している飛行機は危険です。

(プログラミング) 'コンピューターはエラーメッセージを生成しませんが、ユーザーが指示したことを実行しません。それは何か他のことをするでしょう。」

ソース:MIT 6.00.1


-2
  1. 構文は、言語の有効なステートメントの構築を管理する正式な規則を指します。セマンティクスは、ステートメントの意味を与える一連のルールを指します。

  2. プログラミング言語のルールが違反または誤用されると、プログラムに構文によるエラーが発生します。文に意味がない場合、プログラムでセマンティクスによるエラーが発生します。

  3. 語順は構文の基本原則であり、書かれていることを理解しようとする人は、語順の構文上の手がかりを使用して、文の構造と意味を提供します。セマンティクスは、事前の知識に基づいた「文」の意味の個人自身の解釈です。したがって、構文的に意味をなさないように見える文は、セマンティックキューを使用するときに意味を持つことができます。

  4. 構文は、言語的および文法的に正しいものにのみ関係します。セマンティクスには、言語固有のものをはるかに超える事前知識がすべて必要です。

  5. 「Baby milk drinks」という文には構文的な意味はありませんが、セマンティクスを通じて、ほとんどの人は「Baby drinks milk」を意味すると解釈します。キーワード。


1
最後の1つ(ポイント5)を除くすべてに賛成票を投じる
nawfal

-2

構文とセマンティクスは、戦略と戦術、または左右に似ています。

それらは本当に独立した普遍的な概念ではなく、特定の文脈にいるときに反対の方向を示す関連する単語のペアです。しかし、ある規模での戦略と同じことは、別の規模での戦術です。

したがって、言語でコードを記述している場合、構文は使用している言語であり、望ましい動作はセマンティクスです。しかし、その言語のコンパイラを実装または議論している場合、構文は文法であり、おそらく型システムとそれに基づいて構築されたセマンティクスです。等々。


4
どんな難解なBSですか?左右が好きですか?戦略と戦術が好きですか?陰と陽、神と悪魔、ハリーとヴォルデモートのように?
JensG 14

-3

構文はコンピューターが理解するものであり、意味論は人間が理解するものです。

コンパイラー/インタープリターは設計について気にしません。また、マシンレベルにコンパイルされたコードでは、設計を推測するのに苦労します。優れた設計とは、複雑な動作や相互作用を抽象化することで複雑さを軽減することであり、さまざまな種類の問題がさまざまなセマンティクスに役立つため、開発者は設計を重視します。言語の選択は、主に、使用するセマンティクスをその構文でどれだけ簡単かつ効率的に表現できるかに関するものです。


「構文はコンピューターが理解するものであり、意味論は人間が理解するものである」は非常に単純化されすぎています。人間も構文を理解し、コンピューターはある種のセマンティクスを理解します。
-CesarGon

4
明らかに間違っています。同じ構文で完全に異なるセマンティクスを持つ言語(たとえば、同じ言語の熱心なバージョンと怠zyなバージョン)があり、実質的に構文がなく、非常に豊富で可変のセマンティクスを持つ言語(たとえばForthとLisp)があります。セマンティクスは、コンパイラが言語を解釈する方法です。人間はそれについて何も知らなくても、まだ言語を使用することができます。
SKロジック

@ SK-logic、あなたは自分自身に矛盾しています。異なるセマンティクスを同じシンタックスで表現できる場合、セマンティクスはシンタックスに含まれているのではなく、使用方法に含まれていることは明らかです。ただし、コンパイラには、使用する構文のみがあります。セマンティクスを解釈するのではなく、構文を解釈します。開発者の意図に基づいて同じ構文をコンパイルするのではなく、入力した内容のみに基づいてコンパイルします。セマンティクスは開発者によって提供され、開発者にとってのみ意味があります。
キルベン

3
@kylben、私は自分自身と矛盾していません。構文とセマンティクスが接続されているとさえ言ったことがないからです。そして、コンパイラは構文解析段階の直後に構文で何もしていません-コンパイラはセマンティクスを実装しています。用語の解釈が間違っていることは明らかです。手始めに
SK-logic

3
あなたはプログラムの意味について話している。それは言語学者によって定義された「意味論」である。しかし、コンピューターサイエンスでは、セマンティクスは特定のプログラムではなく言語の意味です。
SKロジック

-3

「プレーンc」を使用した非常に短い例:

void main()
{
  int a = 10;
  int x = a - 1;
  int y = - 1;

  printf("x = %i", x);
  printf("y = %i", y);
    getch();
}

この例では、「-」トークンの構文は同じですが、使用場所に応じて異なる意味(「意味」)を持ちます。

「x」割り当てでは、「-」は「減算」演算を意味します。「y」割り当てでは、「-」は「負符号」演算を意味します。


3
間違っています。2 -事業者は同じですトークンが、彼らはしている構文的に、彼らは別のコンテキストで使用しているため、異なります。 0 - 1構文規則additive-expression: additive-expression - multiplicative-expressionに一致しますが、構文規則に- 1一致しますunary-expression: unary-operator cast-expression(参照:C99標準)。
キーストンプソン

@キーストンプソン:あなたはポイントを逃しました。C標準の質問ではなく、セマンティクスまたは構文の質問です。標準は正しいのですが、私の答えは、文字通り標準に従うのではなく、概念を説明することに向けられました。これは、「カーク船長」対「スポック博士」の質問のようなものです。乾杯;-)
umlcat 14

同意しません。2つの-演算子の違いは、意味だけではなく構文です(ただし、意味は異なります)。構文は言語文法によって定義され、2つの演算子は文法の異なるセクションで指定されます。N1570ドラフトの単項演算子についてはセクション6.5.3、加算演算子については6.5.6を参照してください。;あなたがCの例を使用するつもりなら(ところで、それはおそらく正しいはずvoid main()であるべきint main(void)、とあなたは行方不明だ#include <stdio.h>とどんなヘッダで宣言getch
キース・トンプソン

ポイントを明確にするために、構文はトークンのシーケンスだけでなく、それらのトークンがより大きな構造を構築する方法に関するものです。コンパイラは通常、字句解析器(トークン化機能)とパーサーを個別のコンポーネントとして備えています。どちらも構文を扱います。
キーストンプソン14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.