レクサーは通常、非インラインステートメントをどのように処理しますか。指定されたステートメント区切り文字で終了しないステートメント。制御フローステートメントなど?
私は字句解析をかなりよく理解していると思います。レクサー/パーサーを理解するための探求に進むことができます。ただし、レクサーの処理方法は理解しています 1複数行のステートメント。
プログラミング言語構文の比較 に関するWikipediaの記事を読んだ後、すべての言語に共通していることは、非常に特殊なステートメント区切りがあることです。セミコロン(;
)をステートメントの区切り文字として使用するものもあれば、空白(\ws
)を使用するものもあれば、ピリオド(.
)を使用するものもあります。
この方法を使用すると、これらのプログラミング言語が複数の行にまたがるfunctions\class\controlフローを持つ方法を確認できません。私が間違っている場合は修正してください。ただし、ほとんどの一般的なプログラミング言語(Python、Java、C、C++、C#、Javascriptなど)は、関数の最後にステートメント区切り文字を使用しないでください。 、またはクラス(C++のクラスはそこにセミコロンを使用することを知っていますが、それはポイントのほかにです)、または制御フローです。
これは、次のいずれかを意味します。A:レクサーは、複数行にわたるステートメントに対して特別な例外を作成します。またはB:字句解析プログラムは複数行のステートメントを通常のステートメントとして扱うだけであり、それらを理解するのはパーサーの仕事です。
たとえば、次の擬似プログラムをC++で取り上げます。
int exampleVar; //<-- inline statement. Delimited with a semicolon
void exampleFunc() { //<-- multi-line statement. This statement is the start of a block.
// do things
} //<-- this is where the statement that was started above, should end?
明らかに、最初のステートメントをどこで終了すればよいかは簡単にわかります。セミコロンで終わります。しかし、2番目のステートメントはどのように扱われますか?ステートメントは、閉じ中括弧までのすべてを含むように拡張されていますか?
または、私は自分の考えで誤って見過ごされる可能性もあります。レクサーは絶対に何の関係もないかもしれません 1複数行のステートメント。これはパーサーの仕事ですか?つまり、意味を理解するのはパーサーの仕事ですか 1複数行のステートメント?
可能な限り明確にするために、私の質問は次のとおりです。どのように(そもそもそれらが必要な場合)、レクサーがインラインではなく、まるでそれらがあるかのように終了できないステートメントを処理する必要があります。レクサーは通常、非インラインステートメントをどのように処理しますか。指定されたステートメント区切り文字で終了しないステートメント。制御フローステートメントなど?
1明確にするために、行を継続するという意味で、複数行のステートメントを意味するわけではありません。ブロックから始まるステートメントの意味でそれらを意味します。関数宣言など。関数を定義するときは、特定のブロック区切り文字までの関数定義に続くステートメントも知っておく必要があります。したがって、定義の後にステートメントを単に終了させることはできません。
すでに推測したように、これはレクサーの仕事ではありません。ステートメント、宣言、定義の面では取引されませんが、tokensと呼ばれるより低レベルのエンティティで取引されます。
たとえば、次のC関数の場合、
static int
sum_plus_42(const int a, const int b)
{
int result = a + b + 42;
return result;
}
レクサーは次のトークンのシーケンスを生成します。
static
int
sum_plus_42
const
int
a
const
int
b
int
result
=
a
+
b
+
return
result
コード内に構文エラーがあった場合(括弧の不一致など)、レクサーはとにかく喜んでトークン化します。ただし、数値リテラル内の無効な文字などの字句エラーを検出します(123wrong456
など)。
ソースコードがトークン化された後、パーサーはトークンシーケンスから構文ツリーを構築します。
字句解析と構文解析はどちらも、正式な文法の仕様に基づいて行われ、これらを1つに統合できなかった理論的な理由はありません。ただし、実際には、2つのステップを分離することにより、よりクリーンで優れた構造化コードが作成されます。字句解析の文法は通常、はるかに単純でregularですが、言語の構文を記述するために使用される文法はcontext-freeです。実際には、文法はそれほどクリーンではないことが多く、通常の文脈自由文法の正式な規則の外に多かれ少なかれ特殊なケースがあります。
これが明確でない場合、構文解析の文法で使用される終端記号は、レクサーによって生成されるトークンであり、これは非終端です。 =独自の文法の記号。