コンパイラ - 有限オートマトンと正規表現

コンパイラの字句解析は有限オートマトン(有限オートマトン)と正規表現(正規表現)に基づいています。

アルファベット: 有限の記号セット アルファベット: 有限記号のコレクション 文字列
: 指定されたアルファベットからの記号のシーケンス 文字列: 指定のアルファベットからの記号のシーケンス 言語
: 文字列のセット 文字列の集合

たとえば、x12 = 32; トークンがあります
x12 識別子
= 割り当て
32 unsigned int
; ステートメントの終わり

ここでの 4 つのトークンは実際には 4 つの言語とみなすことができ、各言語には独自の文字構成があります。 

文字列 (またはトークン) を有限オートマトンまたは正規表現に渡すと、これが正当なトークンであるか、その言語に属するトークンではないことが返されます。 

有限オートマトンと言語を識別するツールとしての正規表現は正規言語(標準言語)しか認識できません

DFA は比較的厳密で、考えられるすべての出力には 1 つのみの出力があります。

L = {w | w には部分文字列として 101 が含まれます}

DFA (決定論的有限オートマトン) (決定論的有限オートマトン) L 用 

DFA の遷移テーブル:

コード

switch(state)
    case q0:
        if sym == 0 go to q0
        if sym == 1 go to q1
    case q1:
        if sym == 0 go to q1
        if sym == 1 go to q2

すべての DFA は NFA でもありますが、すべての NFA が DFA であるわけではありません

 NFA (非決定的有限オートマトン) (非決定的有限オートマトン) L 用


NFAの遷移表 

 NFA to DFA 方式: サブセット構築サブセット構築方式

コードで実装する場合、DFA と NFA のどちらが実装しやすいのでしょうか?
答えは DFA です。通常、字句解析のプロセスで DFA が構築されます。

L = {w | w には部分文字列 101 または部分文字列 111 が含まれます}

NFA:

L = {w | w には部分文字列 101 が含まれるか、部分文字列 111 で終わります。}

 NFA:

正規表現 (正規表現)

Thompson の 構築: 正規表現を NFA に変換する方法
 NFA から DFA へ: サブセット構築 サブセット構築方法

正規表現は私たち人間にとって最も理解しやすい方法です。まず正規表現を NFA に変換し、次にサブセット構築方法を通じて最終的な DFA に変換する必要があります。DFA に変換して初めて、直感的にコードを書くことができます

これらの変換を行うのに役立つ flex というツールがあり、正規表現を入力するだけで、ツールは C 言語コードを返します。

L = { w | w は部分文字列として 101 を含む} の正規表現は次のとおりです。

(0 U 1)* 101 (0 U 1)*
または ∑* 101 ∑* と書くこともできます //ここで ∑* はすべての可能な入力を表します

正規表現の例をさらに 2 つ示します。

L = {w | w は偶数の長さ} // 偶数の長さ

(∑∑)*

L = {w | w の長さは奇数です} //長さは奇数です

∑(∑∑)*

 unsigned int の正規表現
: [0 - 9]* 先頭に 0 を許可し、空の文字列を許可します
                                                                 0 U [1 - 9][0 - 9]* 先頭に 0 を許可しません

 0 U [1 - 9][0 - 9]* 的NFA:

変数の命名規則とその正規表現 (_ U [a - z]) ([az] U [0 - 9] U _)*その NFA
:

おすすめ

転載: blog.csdn.net/weixin_43754049/article/details/126184144