Ubah ekspresi reguler menjadi mesin status non-deterministik. Analisis leksikal

Dibutuhkan oleh mesin keadaan non-deterministik M = (Q, T, D, q 0 , F) membangun mesin keadaan terbatas deterministik M = (Q", T, D", q" 0 , F"). Keadaan awal untuk otomat yang sedang dibangun adalah -penutupan keadaan awal otomat awal. -penutupan - satu set negara bagian yang dapat dicapai dari yang diberikan dengan transisi sepanjang . Selanjutnya, sementara ada keadaan yang transisinya belum dibangun (transisi dibuat dengan simbol, transisi yang melaluinya ada dalam otomaton asli), untuk setiap simbol, -penutupan himpunan keadaan yang dapat dicapai dari keadaan yang dipertimbangkan dengan transisi melalui simbol yang dipertimbangkan dihitung. Jika keadaan yang sesuai dengan himpunan yang ditemukan sudah ada, maka transisi ditambahkan di sana. Jika tidak, status penerimaan baru ditambahkan.

Contoh

inisialisasi

Status yang sesuai dengan -penutupan status awal ditandai. Negara-negara ini akan sesuai dengan negara A DKA masa depan.


Iterasi pertama

Ada transisi dari penutupan ke status NCA 3 dan 10 (menurut sebuah dan c, masing-masing). Untuk keadaan 3, -penutupan adalah himpunan keadaan (3, 4, 6), untuk keadaan 10 - (10). Mari kita tentukan status DFA baru yang sesuai dengan set ini sebagai B dan C.

negara bagian DKASet status NFA
sebuah b c
A{1, 2, 9} B - C
B{3, 4, 6} - - -
C{10} - - -


Iterasi kedua

Dari himpunan status NFA (3, 4, 6) yang sesuai dengan status DFA B ada dua transisi - untuk menyatakan 5 (oleh b) dan 7 (oleh c). Penutupan mereka berpotongan, tetapi himpunan itu sendiri berbeda, sehingga mereka diberi dua status DFA baru - D dan E. Dari status NFA yang sesuai dengan status DFA C, tidak ada transisi.

negara bagian DKASet status NFAKarakter yang dapat dilompati
sebuah b c
A{1, 2, 9} B - C
B{3, 4, 6} - DE
C{10} - - -
D{2, 5, 8, 9} - - -
E{2, 7, 8, 9} - - -


Iterasi ketiga

Dari set status NFA yang sesuai dengan status DFA D dan E transisi dibuat ke himpunan keadaan yang sesuai dengan keadaan yang ada (dari himpunan (2, 5, 8, 9) yang sesuai dengan keadaan D, pada sebuah transisi ke keadaan 3 milik himpunan (3, 4, 6) sesuai dengan keadaan DFA B, pada c- transisi ke keadaan 10 sesuai dengan keadaan C; sama untuk set yang sesuai dengan status DFA E). Proses pembuatan tabel status dan transisi DFA telah selesai.

negara bagian DKASet status NFAKarakter yang dapat dilompati
sebuah b c
A{1, 2, 9} B - C
B{3, 4, 6} - DE
C{10} - - -
D{2, 5, 8, 9} B - C
E{2, 7, 8, 9} B - C


Hasil:

Membangun tata bahasa linier kanan dari robot yang terbatas

Setiap state diasosiasikan dengan non-terminal. Jika ada transisi keadaan X menjadi negara kamu pada sebuah, tambahkan aturan Xay. Untuk status akhir, tambahkan aturan X→ e. Untuk -transisi - Xkamu.

Contoh 1 (mesin keadaan deterministik)

  • A → sebuah b | c C
  • B → b D | c E
  • C → e
  • D → sebuah b | c C
  • E → sebuah b | c C

Contoh 2 (mesin keadaan non-deterministik)

  • 1 → 2 | 9
  • 2 → sebuah 3
  • 3 → 4 | 6
  • 4 → b 5
  • 5 → 8
  • 6 → c 7
  • 7 → 8
  • 8 → 2 | 9
  • 9 → c 10
  • 10 →

Pembangunan DFA oleh RV

Mari kita memiliki ekspresi reguler r. Berdasarkan ekspresi reguler ini, perlu untuk membangun otomat hingga deterministik D seperti yang L(D) = L(r).

Modifikasi ekspresi reguler

Mari tambahkan simbol untuk itu, yang berarti akhir dari RV - "#". Hasilnya, kami mendapatkan ekspresi reguler ( r)#.

Membangun pohon

Mari kita bayangkan ekspresi reguler sebagai pohon, yang daunnya adalah karakter terminal, dan simpul internal adalah operasi penggabungan ".", union "∪" dan iterasi "*". Kami menetapkan nomor unik untuk setiap daun pohon (kecuali untuk daun ) dan menyebutnya, di satu sisi, sebagai posisi di pohon dan, di sisi lain, sebagai posisi simbol yang sesuai dengan daun.

Perhitungan fungsi nullable, firstpos, lastpos

Sekarang, melintasi pohon T dari bawah ke atas dari kiri ke kanan, kami menghitung tiga fungsi: tidak dapat dibatalkan, pos pertama, dan pos terakhir. Fungsi tidak dapat dibatalkan, pos pertama dan pos terakhir didefinisikan pada node pohon. Nilai semua fungsi kecuali tidak dapat dibatalkan, adalah himpunan posisi. Fungsi pos pertama(n) untuk setiap simpul n dari pohon sintaksis regex memberikan himpunan posisi yang cocok dengan karakter pertama dalam substring yang dihasilkan oleh subekspresi yang berakhiran n. Juga, pos terakhir(n) memberikan set posisi yang sesuai dengan karakter terakhir dalam substring yang dihasilkan oleh subekspresi dengan top n. Untuk node n, yang subpohonnya (yaitu, pohon yang simpulnya n adalah root) dapat menghasilkan kata kosong, kami mendefinisikan tidak dapat dibatalkan(n) = BENAR, dan untuk node lainnya Salah. Tabel untuk menghitung tidak dapat dibatalkan, pos pertama, pos terakhir:

simpul n tidak dapat dibatalkan(n) pos pertama(n) pos terakhir(n)
ε BENAR
saya ≠ ε Salah {saya} {saya}
kamu vtidak dapat dibatalkan(kamu) atau tidak dapat dibatalkan(v) pos pertama(kamu) ∪ pos pertama(v) pos terakhir(kamu) ∪ pos terakhir(v)
kamu vtidak dapat dibatalkan(kamu) dan tidak dapat dibatalkan(v) jika tidak dapat dibatalkan(kamu) kemudian pos pertama(kamu) ∪ pos pertama(v) lain pos pertama(kamu) jika tidak dapat dibatalkan(v) kemudian pos terakhir(kamu) ∪ pos terakhir(v) lain pos terakhir(v)
v*BENAR pos pertama(v) pos terakhir(v)

Membangun tindak lanjut

Fungsi mengikuti dihitung melalui tidak dapat dibatalkan, pos pertama dan pos terakhir. Fungsi mengikuti ditentukan pada beberapa posisi. Berarti mengikuti adalah sekumpulan posisi. Jika sebuah saya- posisi, maka mengikuti(saya) ada banyak posisi j sehingga ada beberapa string ... CD... termasuk dalam bahasa yang dijelaskan oleh RW, sehingga saya cocok dengan entri ini c, sebuah j- masuk d. Fungsi mengikuti juga dapat dihitung dalam satu lintasan pohon menurut dua aturan berikut:

  1. Biarlah n- simpul internal dengan "." (rangkaian); sebuah, b- keturunannya. Kemudian untuk setiap posisi saya termasuk dalam pos terakhir(sebuah mengikuti(saya) sekelompok pos pertama(b).
  2. Biarlah n- simpul internal dengan operasi "*" (iterasi), sebuah- keturunannya. Kemudian untuk setiap posisi saya termasuk dalam pos terakhir(sebuah), tambahkan ke himpunan nilai mengikuti(saya) sekelompok pos pertama(sebuah).

Contoh

Hitung nilai fungsi mengikuti untuk ekspresi reguler ( sebuah(b|c))*c.

PosisiBerarti mengikuti
1: (sebuah (b|c))*c {2, 3}
2: (sebuah(b |c))*c {1, 4}
3: (sebuah(b|c ))*c {1, 4}
4: (sebuah(b|c))*c {5}

Membangun DFA

DFA adalah satu set negara bagian dan satu set transisi di antara mereka. Status DFA adalah sekumpulan posisi. Konstruksi DFA terdiri dari penambahan bertahap status yang diperlukan dan konstruksi transisi untuknya. Awalnya, ada satu negara pos pertama(akar) (akar- akar pohon), yang tidak memiliki transisi. Transisi dilakukan oleh karakter dari ekspresi reguler. Setiap karakter sesuai dengan satu set posisi ( p saya). Menyatukan semua mengikuti(x) adalah keadaan yang harus dituju, di mana x adalah posisi yang ada baik di antara posisi keadaan maupun di antara posisi simbol dari RE, tempat transisi dibuat. Jika tidak ada negara seperti itu, maka itu harus ditambahkan. Proses harus diulang sampai semua transisi untuk semua status dibangun. Semua status yang berisi posisi simbol # yang ditambahkan ke akhir RE dinyatakan final.

DFA diperoleh dari RV ( sebuah(b|c))*c

Contoh

Bangun DFA dengan ekspresi reguler ( sebuah(b|c))*c.

negara bagian DKASimbol
a(1)b(2)c(3, 4)
A(1, 4)B(2, 3) - C(5)
B(2, 3) - A(1, 4)A(1, 4)
C(5) - - -

Membangun DFA dengan jumlah minimum negara bagian

DFA dengan jumlah status minimum dibangun untuk DFA yang ditentukan di mana-mana, mis. seperti yang . Untuk DFA apa pun, ada DFA yang ditentukan di mana-mana yang setara dengannya.

Konstruksi DFA yang ditentukan di mana-mana

Perkenalkan status baru dan definisikan set status baru .

Mari kita definisikan fungsi transisi baru seperti ini:

Membangun partisi (secara formal)

Mari kita buat partisi awal P set negara menjadi dua kelompok: negara akhir F dan lain-lain S/F, yaitu P = {F, T\F}.

Terapkan ke setiap grup GP prosedur berikut. menghancurkan G menjadi subkelompok sehingga negara bagian s dan t dari G berakhir di grup yang sama jika dan hanya jika untuk setiap simbol input sebuah menyatakan s dan t memiliki transisi sebuah ke negara bagian dari grup yang sama di P.

Subgrup yang dihasilkan ditambahkan ke partisi baru P baru.

Menerima P = P baru dan ulangi konstruksi partisi hingga stabilisasi, yaitu hingga partisi berhenti berubah.

Membangun partisi (algoritma)

Untuk membangun partisi, ada algoritma berikut. Kami membangun tabel transisi untuk otomat asli, membangun partisi awal.

Kami menetapkan pengenal untuk setiap grup dari partisi (untuk partisi awal, misalnya, 0 dan 1).

Setiap negara bagian (setiap baris tabel) diberi string dalam bentuk "a.bcd...xyz", di mana pengidentifikasi grup tempat negara bagian itu berasal [kolom pertama (dari mana kita pergi), yang kedua kolom (di mana kita pergi dengan karakter pertama), ..., kolom terakhir (di mana kita pergi dengan karakter terakhir)].

Kami membangun grup baru sesuai dengan kebetulan string, yaitu, sehingga status dengan string yang sama masuk ke dalam satu grup.

Kemudian, iterasi baru. Kami menetapkan pengidentifikasi baru ke grup yang dihasilkan, misalnya (0, 1, ..., n). Dan kami ulangi konstruksi partisi hingga stabilisasi.

Perhatikan bahwa ketika hanya ada satu status yang tersisa di grup, pada tahap selanjutnya dari pembuatan partisi, Anda tidak dapat lagi menulis string pengidentifikasi untuk status ini, karena string ini akan menjadi unik dalam hal apa pun karena karakter pertama dari tali. Dengan kata lain, saat membelah, tidak akan terjadi apa-apa pada grup dari satu negara bagian - grup tersebut dipindahkan ke pemisahan baru apa adanya.

Konstruksi otomat yang dikurangi

Setiap grup yang dihasilkan menjadi status DFA baru. Jika grup berisi status awal (akhir) dari otomat asli, grup ini menjadi status awal (masing-masing final) dari DFA baru. Transisi dibangun dengan cara yang jelas: transisi ke keadaan dari grup dianggap sebagai transisi ke grup.

Kami membawa mesin. Kami pertama-tama menghapus non-generating (steril, "mati"), kemudian status yang tidak dapat dijangkau (definisi diberikan untuk simbol, tetapi dengan cara yang jelas mereka ditransfer ke status otomat).

Secara umum, menghapus keadaan mati mengubah DFA menjadi NFA, karena dalam DFA semua transisi harus didefinisikan. Namun, dalam Buku Naga, penyimpangan seperti itu dari definisi formal masih dianggap dapat diterima.

Contoh

Untuk membuat DFA dengan jumlah minimum status untuk DFA dengan bentuk berikut:

  • Pemisahan awal: (C) ( keadaan akhir), (A, B, D, E) ( semua negara bagian lainnya).
  • (C)( tanpa perubahan), (A, D, E), (B), ( karena kita lewat dari A, D, E masing-masing sepanjang a, c ke B dan C).
  • Kita tidak bisa melakukan split lagi.

Misalkan grup (C) sesuai dengan state C, grup (A, D, E) untuk state A, dan grup (B) untuk state B. Kemudian kita memperoleh DFA dengan jumlah state minimum:

Contoh (algoritma untuk membangun partisi)

Tabel transisi untuk DFA yang didefinisikan di mana saja (status Z ditambahkan) yang sesuai dengan RV (ab|ε)a*|abb|b*a. Dari soal-soal ujian 2012.

sebuahbsaya 0saya 1
→A*BC0.01 0.12
B*DE0.00 1.01
CFC1.01
D*DZ0.01 0.04
E*DZ0.00 1.03
F*ZZ0.11
ZZZ1.11

Iterasi:

  • Saya 0: ABCDEF(0), CZ(1).
  • I 1: AD(0), BE(1), C(2), F(3), Z(4).
  • I 2: A, B, C, D, E, F, Z.

Hasil: mesin sudah memiliki jumlah status minimum :-)

DFA yang memungkinkan penyelesaian bahasa

Algoritma untuk membangun DFA yang menerima komplemen dari bahasa L (L̅) terdiri dari dua langkah:

  • Membangun DFA yang lengkap
  • Konstruksi otomat yang diinginkan darinya

Faktanya, tidak ada DFA yang lengkap. Di bawah DKA penuh beberapa guru memahami otomat, di tabel transisi yang tidak ada sel kosong. Namun, menurut definisi DFA - : Q × → Q - tidak boleh ada sel kosong dalam hal apa pun. Namun, otomat "dengan sel kosong", memenuhi definisi NFA. Dalam proses penyelesaian, tidak jarang mendapatkan NFA seperti itu, yang hanya kekurangan transisi sebelum DFA.

Untuk mengisinya kembali, cukup dengan menambahkan status baru X, dan "alih-alih" transisi yang tidak ada menambahkan transisi ke status baru ini. Jangan lupa untuk menambahkan transisi dari X di X. Sangat mudah untuk melihat bahwa di mana otomat asli tidak menerima beberapa rantai karena tidak adanya transisi, otomat baru akan masuk ke status X dan terpaku padanya. Karena status baru bukanlah status penerimaan (final), otomat baru juga tidak akan menerima rantai ini.

Sekarang, untuk membangun otomat yang diinginkan, hanya perlu mengubah peran status penerima dan non-penerima. Dengan kata lain, F" = Q\F.

Membangun penganalisis LL(k)

Transformasi tata bahasa

Tidak setiap tata bahasa adalah LL(k)-parsable. Tata bahasa bebas konteks termasuk dalam kelas LL(1) jika tidak memiliki konflik FIRST-FIRST (rekursi kiri adalah kasus khusus dari konflik tersebut) dan FIRST-FOLLOW.

Terkadang dimungkinkan untuk mengubah tata bahasa non-LL(1) sehingga menjadi LL(1). Beberapa (lebih tepatnya, yang dipertimbangkan dalam kursus) transformasi diberikan di bawah ini.

Menghapus rekursi kiri

Misalkan kita memiliki aturan bentuk (selanjutnya di bagian ini, huruf kapital - simbol non-terminal, huruf kecil - rantai karakter apa pun):

  • A→A sebuah| A b| … | A k | m | n | … | z

Itu tidak dapat diterima untuk analisis yang tidak ambigu, jadi itu harus dikonversi.

Sangat mudah untuk menunjukkan bahwa aturan ini setara dengan pasangan aturan berikut:

  • A → m b | n b | … | z B
  • B → sebuah b | b b | … | k b |

Faktorisasi kiri

Inti dari prosedur ini adalah menghilangkan ambiguitas dalam pemilihan aturan untuk simbol kiri. Untuk melakukan ini, awalan kiri yang sama ditemukan dan apa yang dapat mengikutinya diambil dalam aturan baru (huruf kecil - rantai karakter apa pun)

Contoh
  • A → sebuah c | sebuah df | sebuah dg | b

Dikonversi ke

  • A → sebuah b | b
  • B → c | d f | d g

yang pada gilirannya menjadi

  • A → sebuah b | b
  • B → c | d Dengan
  • C → f | g

Contoh Konversi Tata Bahasa

G= ((S, A, B), (a, b, c), P, S)

  • S→SAbB | sebuah
  • A→ab | aa |
  • B → c |

Menghapus rekursi kiri untuk S:

  • S → as 1
  • S 1 → AbBS 1 |

Faktorisasi kiri untuk A:

  • A → aA 1 |
  • A 1 → b | sebuah

Tata bahasa akhir:

  • S → as 1
  • S 1 → AbBS 1 |
  • A → aA 1 |
  • A 1 → b | sebuah
  • B → c |

Membangun PERTAMA dan IKUTI

PERTAMA(α), di mana (N T)* adalah himpunan terminal dari mana dapat dimulai. Jika , maka PERTAMA(α). Dengan demikian, nilai FOLLOW( A) untuk non-terminal A- banyak terminal yang dapat muncul segera setelahnya A dalam beberapa bentuk sentimental. Jika sebuah A mungkin karakter paling kanan dalam beberapa bentuk kalimat, maka $ token terakhir juga milik FOLLOW( A)

perhitungan PERTAMA

Untuk terminal
  • Untuk terminal apa pun x, xT, PERTAMA( x) = {x}
Untuk non-terminal
  • Jika sebuah X adalah non-terminal, maka kami menempatkan PERTAMA( X) = {∅}
  • Jika tata bahasa memiliki aturan X→ , lalu tambahkan ke PERTAMA( X)
  • Untuk setiap non-terminal X dan untuk setiap aturan inferensi Xkamu 1 …kamu k tambahkan ke PERTAMA( X) himpunan PERTAMA dari semua simbol di sisi kanan aturan hingga yang pertama dari mana tidak diturunkan, termasuk
Untuk rantai
  • Untuk string karakter X 1 …X k FIRST adalah gabungan karakter FIRST yang disertakan dalam string hingga yang pertama, yang memiliki FIRST, termasuk di dalamnya.
Contoh
  • S → as 1
  • S 1 → AbBS 1 |
  • A → aA 1 |
  • A 1 → b | sebuah
  • B → c |

Non-terminal PERTAMA dalam urutan resolusi ketergantungan:

  • PERTAMA(S) = (a)
  • PERTAMA(A) = (a, )
  • PERTAMA(A 1) = (b, a)
  • PERTAMA(B) = (c, )
  • PERTAMA(S 1) = (a, b, )

PERTAMA untuk aturan inferensi:

  • PERTAMA(aS 1) = (a)
  • PERTAMA(AbBS 1) = (a, b)
  • PERTAMA(ε) = (ε)
  • PERTAMA(aA 1) = (a)
  • PERTAMA(a) = (a)
  • PERTAMA(b) = (b)
  • PERTAMA(c) = (c)

IKUTI perhitungan

Menghitung fungsi FOLLOW untuk karakter X:

  • Biarkan IKUTI(X) = (∅)
  • Jika X adalah aksioma tata bahasa, tambahkan penanda $ ke FOLLOW
  • Untuk semua aturan bentuk A → X tambahkan FIRST(β)\(ε) ke FOLLOW(X) (X dapat diikuti oleh karakter yang dimulai dengan )
  • Untuk semua aturan bentuk A → X dan A → Xβ, FIRST(β), tambahkan FOLLOW(A) ke FOLLOW(X) (yaitu, X dapat diikuti oleh semua karakter yang dapat mengikuti A, jika dalam aturan inferensi, X mungkin berada di paling kanan)
  • Ulangi dua paragraf sebelumnya selama mungkin untuk menambahkan karakter ke set
Contoh
  • S → as 1
  • S 1 → AbBS 1 |
  • A → aA 1 |
  • A 1 → b | sebuah
  • B → c |

Hasil:

  • IKUTI(S) = ($)
  • FOLLOW(S 1) = ($) (S 1 adalah karakter paling kanan dalam aturan S → aS 1)
  • IKUTI(A) = (b) (A dalam aturan S 1 → AbBS 1 diikuti oleh b)
  • FOLLOW(A 1) = (b) (A 1 adalah karakter paling kanan dalam aturan A → aA 1 , maka tambahkan FOLLOW(A) ke FOLLOW(A 1))
  • FOLLOW(B) = (a, b, $) (tambah FIRST(S 1)\(ε) (mengikuti aturan S 1 → AbBS 1), FOLLOW(S 1) (karena ada S 1 → ))

Menyusun tabel

Meja M untuk pasangan non-terminal-terminal (dalam sel M[A, sebuah]) menentukan aturan di mana kata input harus dikurangi. Tabel diisi sebagai berikut: untuk setiap aturan inferensi dari tata bahasa yang diberikan A → (di mana dipahami sebagai rantai di sisi kanan aturan), tindakan berikut dilakukan:

  1. Untuk setiap terminal sebuah PERTAMA(α) tambahkan aturan Aα ke M[A, sebuah]
  2. Jika PERTAMA(α), maka untuk setiap b IKUTI ( A) Menambahkan Aα ke M[A, b]
  3. PERTAMA(α) dan $ IKUTI( A), Menambahkan Aα ke M[A, $]
  4. Semua sel kosong adalah kesalahan dalam kata input

Contoh

Buat tabel untuk tata bahasa

  • S → as 1
  • S 1 → AbBS 1 |
  • A → aA 1 |
  • A 1 → b | sebuah
  • B → c |

Hasil:

sebuahbc $
S S → as 1 (Aturan pertama, inferensi S → aS 1 , a FIRST(aS 1)) kesalahan (Aturan keempat) kesalahan (Aturan keempat) kesalahan (Aturan keempat)
S1 S 1 → AbBS 1 (Aturan pertama, keluaran S 1 → AbBS 1 , a FIRST(AbBS 1)) S 1 → AbBS 1 (Aturan pertama, keluaran S 1 → AbBS 1 , b FIRST(AbBS 1)) kesalahan (Aturan keempat) S 1 → (Aturan ketiga, inferensi S 1 → , FIRST(ε), $ FOLLOW(S 1))
A A → aA 1 (Aturan pertama, keluaran A → aA 1 , a PERTAMA(aA 1)) A→ε (Aturan kedua, keluaran A 1 → , b FOLLOW(A 1)) kesalahan (Aturan keempat) kesalahan (Aturan keempat)
1 A 1 → a (Aturan pertama, keluaran A 1 → a, a PERTAMA(a)) A 1 → b (Aturan pertama, keluaran A 1 → b, b PERTAMA(b)) kesalahan (Aturan keempat) kesalahan (Aturan keempat)
B B→ε B→ε (Aturan kedua, inferensi B → , a FOLLOW(B)) B → c (Aturan pertama, keluaran B → c, c PERTAMA(c)) B→ε (Aturan ketiga, inferensi B → , $ FOLLOW(B))

Penguraian string

Proses penguraian string cukup sederhana. Esensinya adalah sebagai berikut: pada setiap langkah, simbol teratas dibaca v c rantai masukan.

  • Jika sebuah v- simbol terminal
    • Jika sebuah v bertepatan dengan dengan, lalu keduanya hancur, ada pergeseran
    • Jika sebuah v tidak cocok dengan dengan, maka kesalahan penguraian ditandai
  • Jika sebuah v- simbol non-terminal, c kembali ke awal baris alih-alih v sisi kanan aturan, yang diambil dari sel tabel, dikembalikan ke tumpukan M[v, c]

Proses berakhir ketika string dan tumpukan telah mencapai penanda akhir (#).

Contoh

Mari kita urai string "aabbaabcb":

tumpukangaristindakan
S# sebuah abbaabcb$S → as 1
sebuah S1#sebuah abbaabcb$menggeser
S1# sebuah bababcb$S 1 → AbBS 1
A bb 1#sebuah bababcb$A → aA 1
sebuah A 1 bBS 1 #sebuah bababcb$menggeser
1 bb 1#b baabcb$A 1 → b
b bb 1#b baabcb$menggeser
b BS 1#b aabcb$menggeser
B S1#sebuah abcb$B→ε
S1# sebuah abcb$S 1 → AbBS 1
A bb 1#sebuah abcb$A → aA 1
A bb 1#sebuah abcb$A → aA 1
sebuah A 1 bBS 1 #sebuah abcb$menggeser
1 bb 1#sebuah bcb$A 1 → a
sebuah bb 1#sebuah bcb$menggeser
b BS 1#b cb$menggeser
B S1#c b$B → c
c S1#c b$menggeser
S1# b$ S 1 → AbBS 1
A bb 1#b$ A→ε
b BS 1#b$ menggeser
B S1#$ B→ε
S1# $ S 1 →
# $ siap

Membangun penganalisis LR(k)

Menghitung k dalam LR(k)

Tidak ada algoritma yang memungkinkan, dalam kasus umum, untuk menghitung k untuk tata bahasa arbitrer. Biasanya ada baiknya mencoba membuat parser LR(1). Jika memiliki paling banyak satu operasi per set (Shift, Reduce, atau Accept), maka tata bahasanya adalah LR(0). Namun, jika konflik dan tabrakan terjadi saat membangun parser LR(1), maka tata bahasa ini bukan LR(1) dan patut dicoba untuk membangun LR(2). Jika gagal membangunnya, maka LR(3) dan seterusnya.

Tata bahasa selesai

Mari tambahkan aturan baru S" → S, dan jadikan S" sebagai aksioma tata bahasa. Aturan tambahan ini diperlukan untuk menentukan kapan penganalisis berakhir dan rantai input diizinkan. Penerimaan terjadi jika dan hanya jika dimungkinkan untuk melakukan konvolusi menurut aturan S → S".

Konstruksi sistem kanonik dari kumpulan situasi LR(1) yang dapat diterima

Pada awalnya, ada himpunan I 0 dengan konfigurasi analyzer S" → .S, $. Kemudian, operasi penutupan diterapkan pada konfigurasi ini hingga, sebagai hasil penerapannya, tidak ada konfigurasi baru yang ditambahkan. Selanjutnya , transisi ke himpunan baru dibangun dengan menggeser titik satu karakter ke kanan (lompatan dilakukan oleh karakter yang berada setelah titik sebelum lompat dan sebelum setelah lompat), dan konfigurasi yang diperoleh dari yang sudah ada dengan cara ini ditambahkan ke set ini.Operasi penutupan juga diterapkan pada mereka, dan seluruh proses diulang sampai tidak ada lagi set baru yang muncul.

Contoh

Membangun sistem kanonik dari set LR(1)-situasi yang dapat diterima untuk tata bahasa yang ditentukan:

  • S" → S
  • S → ABA
  • A → Aa |
  • B → cBc | d

Keputusan:

  • Kami membuat penutupan untuk konfigurasi S" → .S, $:
    • S → .ABA,$
  • Untuk konfigurasi yang dihasilkan (S → .ABA, $) kami juga membuat penutupan:
    • A → .Aa, c
    • A → .Aa, d
    • A → .,c
    • A → ., d
  • Untuk konfigurasi yang dihasilkan (A → .Aa, c; A → .Aa, d) kami juga membuat penutupan:
    • A → .Aa, a
    • A → ., a
  • Tidak ada lagi konfigurasi dalam status I 0 yang dapat dibuat - penutupan dibuat
  • Dari I 0, Anda dapat membuat transisi di sepanjang S dan A dan mendapatkan satu set konfigurasi I 1 dan I 2, yang terdiri dari elemen-elemen berikut:
    • I 1 = (S" → S., $)
    • I 2 = (S → A.BA, $; A → A.a, c; A → A.a, d; A → A.a, a)
  • I 1 tidak memerlukan penutupan
  • Mari kita buat penutupan I 2:
    • B → .cBc, a
    • B → .cBc, $
    • B → .d, a
    • B → .d, $
  • Semua set lainnya dibangun dengan cara yang sama.

Membangun tabel parser

Langkah terakhir dalam membangun parser LR(1) adalah membuat tabel Tindakan dan pergi ke. Meja Tindakan dibangun untuk karakter string input, yaitu untuk terminal dan penanda akhir baris $, tabel pergi ke dibangun untuk simbol tata bahasa, yaitu untuk terminal dan non-terminal.

Membangun Meja Goto

Tabel Goto menunjukkan status mana yang harus dituju ketika simbol tata bahasa berikutnya ditemukan. Oleh karena itu, jika dalam sistem kanonik himpunan terdapat transisi dari saya saya di Aku j dengan simbol A, lalu di Goto( Saya saya, A) kami menempatkan negara Saya j. Setelah mengisi tabel, kami berasumsi bahwa di semua sel kosong Goto( Saya saya, A) = Kesalahan

Membangun tabel Tindakan

  • Jika ada transisi pada terminal a dari state I i ke state I j , maka Action(I i , a) = Shift(I j)
  • Jika A S" dan ada konfigurasi A → ., a, maka Aksi(I i , a) = Reduce(A → )
  • Untuk state I i yang memiliki konfigurasi S" → S., $, Action(I i , $) = Accept
  • Untuk semua sel kosong Action(I i , a) = Error

Contoh

Bangun tabel Action dan Goto untuk tata bahasa

  • S" → S
  • S → ABA
  • A → Aa |
  • B → cBc | d

Keputusan:

Tindakanpergi ke
sebuahcd$ SS"ABsebuahcd
saya 0Kurangi(A → )Kurangi(A → )Kurangi(A → ) saya 1 saya 2
saya 1 Menerima
saya 2Shift(I 6)Shift(I 4)Shift(I 5) saya 3saya 6saya 4saya 5
saya 3Kurangi(A → ) Kurangi(A → ) saya 13
saya 4 Pergeseran (I 8)Pergeseran (I 9) saya 7 saya 8saya 9
saya 5Kurangi (B → d) Kurangi (B → d)
saya 6Kurangi (A → Aa)Kurangi (A → Aa)Kurangi (A → Aa)
saya 7 Shift(I 10) saya 10
saya 8 Pergeseran (I 8)Pergeseran (I 9) saya 11 saya 8saya 9
saya 9 Kurangi (B → d)
saya 10Kurangi (B → cBc) Kurangi (B → cBc)
saya 11 Shift(I 12) saya 12
saya 12 Kurangi (B → cBc)
saya 13Shift(I 14) Kurangi(S → ABA) saya 14
saya 14Kurangi (A → Aa) Kurangi (A → Aa)

Penguraian rantai

Pada setiap langkah, karakter teratas dibaca v dari tumpukan penganalisis dan ambil karakter terakhir c rantai masukan.

Jika dalam tabel aksi di persimpangan v dan c terletak:

  • Menggeser( ik), lalu taruh di tumpukan dengan lalu ik. Di mana c dihapus dari tali.
  • Mengurangi( Akamu), maka semua simbol terminal dan non-terminal yang membentuk rantai dihapus dari bagian atas tumpukan kamu, setelah itu negara terlihat Aku tersisa di atas. Menurut tabel transisi di persimpangan Aku dan A temukan keadaan selanjutnya Adalah. Kemudian A didorong ke tumpukan, dan kemudian Adalah. Garis tetap tidak berubah.
  • Terima, lalu penguraian selesai
  • kekosongan adalah sebuah kesalahan

Contoh

Mari kita buat penguraian string aaaccdcc:

TumpukanGarisTindakan
saya 0 sebuah aaccdcc$Kurangi(A → ), masuk ke I 2
saya 0 A saya 2 sebuah aaccdcc$Shift(I 6)
Saya 0 A Saya 2 a saya 6 sebuah accdcc$Kurangi(A → Aa), masuk ke I 2
saya 0 A saya 2 sebuah accdcc$Shift(I 6)
Saya 0 A Saya 2 a saya 6 sebuah ccdcc$Kurangi(A → Aa), masuk ke I 2
saya 0 A saya 2 sebuah ccdcc$Shift(I 6)
Saya 0 A Saya 2 a saya 6 c cdcc$Kurangi(A → Aa), masuk ke I 2
saya 0 A saya 2 c cdcc$Shift(I 4)
Saya 0 A Saya 2 s saya 4 c dcc$Pergeseran (I 8)
I 0 A I 2 c I 4 c saya 8 d cc$Pergeseran (I 9)
I 0 A I 2 c I 4 c I 8 d saya 9 c c$Kurangi(B → d), lanjutkan ke I 11
I 0 A I 2 c I 4 c I 8 B saya 11 c c$Shift(I 12)
I 0 A I 2 c I 4 c I 8 B I 11 c saya 12 c$ Kurangi(B → cBc), lanjutkan ke I 7
I 0 A I 2 c I 4 B saya 7 c$ Shift(I 10)
I 0 A I 2 c I 4 B I 7 c saya 10 $ Kurangi(B → cBc), lanjutkan ke I 3
Saya 0 A Saya 2 B saya 3 $ Kurangi(A → ), masuk ke I 13
I 0 A I 2 B I 3 A saya 13 $ Kurangi(S → ABA), lanjutkan I 1
saya 0 S saya 1 $ Menerima

Terjemahan ekspresi aritmatika (algoritma Seti-Ullman)

Catatan. Kode dihasilkan oleh gaya doggy seperti Motorola, mis.

Op Arg1, Arg2

berdiri untuk

Arg2 = Arg1 Op Arg2

Membangun pohon

Pohon dibangun seperti biasa untuk ekspresi aritmatika: Pada akar, operasi dengan prioritas terendah, diikuti oleh operasi dengan prioritas sedikit lebih tinggi, dan seterusnya. Tanda kurung memiliki prioritas tertinggi. Jika ada beberapa operasi dengan prioritas yang sama - a op b op c, maka pohon dibangun untuk ekspresi (a op b) op c.

Contoh

Bangun pohon untuk ekspresi a + b / (d + a b × c / d e) + c × d

Keputusan: Kami menulis ekspresi dalam bentuk

((a) + ((b) / ((((d) + (a)) ((b) × (c)) / (d)) (e)))) + ((c) × ( d))

Kemudian pada akar setiap subpohon akan ada operasi, dan ekspresi dalam tanda kurung di sebelah kiri dan kanannya akan menjadi subpohonnya. Misalnya, untuk subekspresi ((b) × (c)) / (d), operasi “/” akan berada di akar subpohon yang sesuai, dan subekspresi ((b) × (c)) dan (d ) akan menjadi subpohonnya.

Tata letak pohon (perhitungan jumlah register)

  • Jika simpulnya adalah daun kiri (yaitu variabel), maka kita menandainya dengan nol.
  • Jika simpulnya adalah daun yang tepat, maka kami menandainya dengan satu
  • Jika kita menandai kedua subpohonnya untuk beberapa titik, maka kita menandainya sebagai berikut:
    • Jika subpohon kiri dan kanan diberi label dengan angka yang berbeda, maka pilihlah yang terbesar dari mereka
    • Jika subpohon kiri dan kanan diberi label dengan angka yang sama, maka subpohon ini diberi nomor satu lebih besar dari yang memberi label pada subpohon
tanda daunTata letak pohon dengan subpohon yang identikSubpohon kiri diberi label dengan angka besarSubpohon kanan diberi label dengan angka besar
Baik - sama seperti nenek moyang.
  • Jika labelnya kiri keturunan lagi label Baik, kemudian Baik anak ditugaskan mendaftar satu lagi daripada leluhur, dan kiri - sama seperti nenek moyang.
  • Kode dibentuk dengan melintasi pohon dari bawah ke atas sebagai berikut:

    1. Tidak ada kode yang dihasilkan untuk simpul dengan label 0

    2. Jika bagian atas adalah lembar X dengan label 1 dan register R saya, lalu kode

    PINDAHKAN X, Ri

    3. Jika bagian atas adalah internal dengan register R saya dan anak kirinya adalah lembar X dengan label 0, maka sesuai dengan kode

    <Код правого поддерева>OpX, Ri

    4. Jika subpohon dari suatu simpul dengan register R saya- tidak meninggalkan dan label simpul kanan lebih besar atau sama dengan label simpul kiri (yang memiliki register Rj, j = i + 1), maka kode sesuai dengan simpul

    <Код Baik subpohon><Код kiri subpohon > Op Rj, Ri

    5. Jika subpohon dari simpul dengan register R saya- tidak meninggalkan dan label dari simpul kanan (yang register Rj, j = i + 1) lebih kecil dari label kiri, maka kode sesuai dengan simpul

    Distribusi register ditunjukkan pada grafik di sebelah kanan. Kode yang dihasilkan:

    PINDAHKAN d, R0 ;R0 = d PINDAH c, R1 ;R1 = c MUL b, R1 ;R1 = (b × c) DIV R1, R0 ;R0 = (b × c) / d PINDAH a, R1 ;R1 = a TAMBAHKAN d, R1 ;R1 = a + d SUB R1, R0 ;R0 = (a + d) ((b × c) / d) PINDAH e, R1 ;R1 = e SUB R0, R1 ;R1 = ((a + d) ((b × c) / d)) − e PINDAHKAN R1, R0;R0 = ((a + d) ((b × c) / d)) − e DIV b, R0 ;R0 = b / (((a + d) ((b × c) / d)) e) TAMBAHKAN a, R0 ;R0 = a + (b / (((a + d) ((b × c) / d )) e)) PINDAHKAN d, R1 ;R1 = d MUL c, R1 ;R1 = c × d TAMBAHKAN R0, R1 ;R1 = (a + (b / (((a + d) ((b × c) ) / d)) e))) + (c × d) PINDAHKAN R1, R0;R0 = (a + (b / (((a + d) ((b × c) / d)) e) )) + (c × d)

    Terjemahan ekspresi logis

    Bagian ini menunjukkan cara membuat kode untuk evaluasi lazy dari ekspresi boolean. Sebagai hasil dari algoritme, sepotong kode diperoleh, yang, menggunakan operasi TST, BNE, BEQ, menghitung ekspresi logis dengan beralih ke salah satu label: TRUELAB atau FALSELAB.

    Membangun pohon

    Pohon dari ekspresi logika mencerminkan urutan yang dievaluasi sesuai dengan prioritas operasi, yaitu, untuk mengevaluasi nilai dari simpul pohon (yang merupakan operasi dari dua operan yang merupakan subpohon dari simpul), kita harus hitung dulu nilai subpohonnya.

    Prioritas Operasi: Operator NOT memiliki prioritas tertinggi, diikuti oleh AND dan kemudian OR. Jika operasi logis lain digunakan dalam ekspresi, maka mereka harus diekspresikan melalui ketiganya dengan cara tertentu (biasanya, tidak ada operasi lain dan konversi ekspresi tidak diperlukan). Keterkaitan untuk operasi dengan prioritas yang sama adalah dari kiri ke kanan, yaitu A dan B dan C diperlakukan sebagai (A dan B) dan C

    Contoh

    Buatlah pohon untuk ekspresi logika bukan A atau B dan C dan (B atau bukan C).

    Keputusan: lihat diagram di sebelah kanan.

    Untuk setiap simpul pohon, 4 atribut dihitung:

    • Nomor simpul
    • Label untuk melompat jika ekspresi dalam simpul salah (label salah, fl)
    • Label untuk melompat jika ekspresi dalam simpul benar (label benar, tl)
    • Label-sign (tanda) (untuk lebih jelasnya lihat di bawah)

    Simpul diberi nomor dalam urutan acak, satu-satunya syarat adalah keunikan nomor simpul.

    Tata letak pohon dilakukan sebagai berikut:

    • fl menentukan jumlah simpul tempat transisi dibuat atau falselab jika simpul ini salah
    • tl menunjukkan jumlah simpul tempat transisi dibuat atau truelab jika simpul ini benar

    Tanda menentukan dalam hal mana evaluasi subpohon saat ini dapat dihentikan.

    Untuk akar pohon, fl=falselab, tl=truelab, sign=false.

    Dengan demikian:

    Contoh

    Tandai pohon yang dibangun untuk ekspresi logis bukan A atau B dan C dan (B atau bukan C).

    Pembuatan kode

    Perintah mesin yang digunakan dalam kode yang dihasilkan:

    • TST - memeriksa kebenaran argumen dan memasang bendera jika argumen salah
    • BNE - lompat ke label jika bendera tidak disetel, yaitu kondisi diperiksa dengan TST BENAR
    • BEQ - lompat pada label jika bendera diatur, yaitu kondisi diperiksa dengan TST Salah

    Kode dibangun sebagai berikut:

    • pohon dilintasi dari akar, untuk AND dan OR, subpohon kiri dilalui terlebih dahulu, kemudian kanan
    • untuk setiap simpul yang dilewati, nomornya (label) dicetak
    • untuk lembar A(angka, tl, fl, tanda) TST A tercetak
      • jika tanda == benar, BNE tl dicetak
      • jika tanda == salah, BEQ fl dicetak

    Contoh

    Untuk ekspresi di atas, kode berikut akan dibuat:

    1:2:4: TST A BEQ TRUELAB 3:5:7: TST B BEQ FALSELAB 8: TST C BEQ FALSELAB 6:9: TST B BNE TRUELAB 10:11: TST C BNE FALSELAB TRUELAB: FALSELAB:

    Metode pencocokan sampel

    Gagasan metode ini adalah bahwa untuk bagian program yang sama, kode dapat dibuat dengan cara yang berbeda, dan, sebagai hasilnya, pengoptimalan dapat dicapai untuk satu atau beberapa parameter lainnya.

    Rumusan masalah

    Ada banyak sampel, yang masing-masing ditentukan oleh bagian dari representasi perantara yang dapat diterapkan, bobot dan kode yang dihasilkan. Ada pohon representasi perantara, yang merupakan bagian dari program yang diperlukan untuk menghasilkan kode. Tujuannya adalah untuk membangun penutup pohon representasi perantara dengan sampel sehingga berat total sampel minimal.

    Pola adalah instruksi perakitan dan pohon parsing yang sesuai dengannya. Untuk setiap sampel, waktu eksekusinya (dalam siklus) diketahui. Dengan bantuan mereka, kami akan menghasilkan kode yang optimal (dalam hal waktu eksekusi).

    Contoh contoh

    Membangun representasi perantara

    Pertama, kita membangun pohon parse untuk seluruh ekspresi.

    Membangun liputan

    Sekarang untuk setiap simpul (kita menelusurinya secara berurutan dari daun ke akar), kita akan menghasilkan kode optimal untuk subpohonnya. Untuk melakukan ini, kita cukup menelusuri semua sampel yang berlaku pada titik tertentu. Waktu eksekusi saat menggunakan pola tertentu akan menjadi jumlah waktu yang diperlukan untuk mengevaluasi argumennya (dan kita sudah mengetahui kode optimal untuk menghitungnya berkat urutan traversal pohon) dan waktu eksekusi pola itu sendiri. Dari semua opsi yang diperoleh, kami memilih yang terbaik - ini akan menjadi kode optimal untuk subpohon dari simpul ini. Di akar pohon, kami mendapatkan kode optimal untuk seluruh ekspresi.

    Pembuatan kode

    Tidak perlu menuliskan kode untuk semua simpul - cukup menuliskan waktu minimum yang diperlukan dan sampel yang perlu Anda gunakan. Segala sesuatu yang lain dari ini mudah dipulihkan.

    Kami memiliki jumlah register yang tak terbatas dalam masalah ini, jadi setiap kali Anda dapat menggunakan yang baru.

    Konstruksi RV menurut DFA

    Konstruksi NFA menurut tata bahasa linier kanan

    Pengecoran Tata Bahasa

    Untuk mengonversi tata bahasa COP arbitrer ke bentuk tereduksi, Anda harus melakukan langkah-langkah berikut:

    • hapus semua karakter mandul;
    • hapus semua karakter yang tidak terjangkau;

    Menghapus karakter yang tidak berguna

    Pintu masuk: COP-tata bahasa G = (T, N, P, S).

    Keluaran: Tata bahasa COP G' = (T, N', P', S) tidak mengandung simbol mandul, di mana L(G) = L(G').

    Metode:

    Bangun set secara rekursif N 0 , N 1 , ...

    1. N 0 = , i = 1.
    2. N i = (A | (A → ) P dan (N i - 1 T)*) N i-1 .
    3. Jika N i N i - 1, maka i = i + 1 dan lanjutkan ke langkah 2, jika tidak N’ = N i ; P' terdiri dari aturan himpunan P yang hanya berisi simbol dari N' T; G' = (T, N', P', S).

    Definisi: simbol x (T N) dikatakan tidak terjangkau dalam tata bahasa G = (T, N, P, S) jika tidak muncul dalam bentuk kalimat apa pun dari tata bahasa ini.

    Contoh

    Hapus karakter yang tidak berguna dari tata bahasa G((A, B, C, D, E, F, S), (a, b, c, d, e, f, g), P, S)

    • S → AcDe | CaDbCe | Saka | aCb | dFg
    • A → SeAd | cSA
    • B → CaBd | aDBc | BSC | bfg
    • C→Ebd | Seb | aAc | cfF
    • D→fCE | ac | dEdAS |
    • E→ESacD | aec | eFF

    Keputusan

    • N 0 =
    • N 1 = (B (B → bfg) , D (D → ac) , E (E → aec) )
    • N 2 = (B, D, E, C (C → Ebd) )
    • N 3 = (B, D, E, C, S (S → aCb) )
    • N 4 \u003d (B, D, E, C, S) \u003d N 3

    G"((B, C, D, E, S), (a, b, c, d, e, f, g), P", S)

    • S → CaDbCe | Saka | aCb
    • B → CaBd | aDBc | BSC | bfg
    • C→Ebd | seb
    • D→fCE | ac |
    • E→ESacD | aec

    Menghapus karakter yang tidak dapat dijangkau

    Pintu masuk: Tata bahasa COP G = (T, N, P, S)

    Keluaran: Tata bahasa COP G' = (T', N', P', S) tidak mengandung simbol yang tidak dapat dijangkau, dengan L(G) = L(G').

    Metode:

    1. V 0 = (S); saya = 1.
    2. V i = (x | x (T N), (A → xβ) P dan A V i - 1 ) V i-1 .
    3. Jika V i V i - 1 , maka i = i + 1 dan lanjutkan ke langkah 2, jika tidak N’ = V i N; T' = V i T; P' terdiri dari aturan-aturan himpunan P yang hanya berisi simbol-simbol dari V i ; G' = (T', N', P', S).

    Definisi: Sebuah COP-tata bahasa G dikatakan tereduksi jika tidak mengandung simbol-simbol yang tidak dapat dicapai dan steril.

    Contoh

    Hapus karakter yang tidak dapat dijangkau dari tata bahasa G"((B, C, D, E, S), (a, b, c, d, e, f, g), P", S)

    • S → CaDbCe | Saka | aCb
    • B → CaBd | aDBc | BSC | bfg
    • C→Ebd | seb
    • D→fCE | ac |
    • E→ESacD | aec

    Keputusan

    • V 0 = (S)
    • V 1 = (S, C (S → CaDbCe) , D (S → CaDbCe) , a (S → CaDbCe) , b (S → CaDbCe) , e (S → CaDbCe) )
    • V 2 = (S, C, D, a, b, e, E (C → Ebd) , d (C → Ebd) , f (D → fCE) )
    • V 3 = (S, C, D, E, a, b, d, e, f, c (E → ESacD) )
    • V 4 \u003d (S, C, D, E, a, b, d, e, f, c) \u003d V 3

    G""((C, D, E, S), (a, b, c, d, e, f), P"", S)

    • S → CaDbCe | Saka | aCb
    • C→Ebd | seb
    • D→fCE | ac |
    • E→ESacD | aec
    dengan jumlah total karakter alfabet simbol dan tanda operasi dan tanda kurung dalam catatan r .

    Dasar. Automata untuk ekspresi panjang 1: dan ditunjukkan pada gambar berikut.


    Beras. 5.1.

    Perhatikan bahwa masing-masing dari ketiga automata ini memiliki set status akhir terdiri dari satu negara bagian.

    langkah induksi. Mari kita asumsikan bahwa untuk setiap ekspresi reguler panjang<= k построен соответствующий НКА, причем у него единственное заключительное состояние. Рассмотрим произвольное ekspresi reguler r dengan panjang k+1 . Bergantung pada operasi terakhir, ia dapat memiliki salah satu dari tiga bentuk: (r 1 + r 2), (r 1 r 2) atau (r 1) * . Biarkan dan jadilah NFA masing-masing mengenali bahasa L r1 dan L r2 . Tanpa kehilangan keumuman, kita akan berasumsi bahwa mereka memiliki status yang berbeda: .

    Kemudian NFA , yang diagramnya ditunjukkan pada Gambar. 5.2, mengenali bahasa.


    Beras. 5.2.

    Mesin ini memiliki himpunan negara bagian, di mana q 0 adalah keadaan awal baru, q f adalah keadaan akhir baru (unik!), dan program tersebut mencakup program otomat M 1 dan M 2 dan empat perintah transisi baru: . Jelas, bahasa yang dikenali oleh NFA M mencakup semua kata dari L ( M 1 ) dan dari L ( M 2 ) . Di sisi lain, setiap kata mengambil q 0 ke q f , dan setelah langkah pertama jalan yang membawanya melewati q 0 1 atau q 0 2 . Karena keadaan M 1 dan M 2 tidak berpotongan, maka dalam kasus pertama jalur ini dapat mencapai q f hanya dengan a -transisi dari q f 1 dan kemudian . Demikian pula dalam kasus kedua.

    Untuk ekspresinya, diagram NFA yang mengenali bahasa L r ditunjukkan pada gambar berikut.


    Beras. 5.3.

    Mesin ini memiliki himpunan negara bagian , keadaan awal q 0 = q 0 1 , keadaan akhir q f =q f 2 , dan program ini mencakup program otomat M 1 dan M 2 dan satu perintah baru - transisi dari keadaan akhir M 1 ke keadaan awal M 2 , yaitu. . Di sini juga jelas bahwa setiap lintasan dari q 0 = q 0 1 ke q f = q f 2 melewati a -transisi dari q f 1 ke q 0 2 . Oleh karena itu, kata apa pun yang diizinkan oleh M adalah gabungan dari beberapa kata dari L M1 ) dengan beberapa kata dari L M2 ) , dan setiap penggabungan kata-kata tersebut diperbolehkan. Oleh karena itu, NFA M mengenali bahasa tersebut.

    Misalkan r = r 1 * . Diagram NFA yang mengenali bahasa L r =L r1* = L M1 * ditunjukkan pada gambar. 5.3.


    Beras. 5.3.

    Mesin ini memiliki himpunan negara bagian, di mana q 0 adalah status awal baru, q f adalah status akhir baru (unik!), dan program menyertakan program otomat M 1 dan empat perintah transisi baru: . Jelas sekali, . Untuk kata yang tidak kosong w, menurut definisi iterasi untuk beberapa k >= 1 kata w dapat dibagi menjadi k subkata: w=w 1 w 2 ... w k dan hanya itu. Untuk setiap i= 1,... ,k kata w i memetakan q 0 1 ke q f 1 . Kemudian untuk kata w pada diagram M ada jalurnya

    Karena itu, . Sebaliknya, jika beberapa kata menerjemahkan q 0 menjadi q f , maka kata itu ada atau dibawa oleh jalur q 0 1 dengan -transisi, akhirnya dari q f 1 oleh -transisi berakhir di q f . Oleh karena itu, kata seperti itu.

    Dari Teorema 4.2 dan 5.1 kita peroleh secara langsung

    Akibat wajar 5.1. Untuk semuanya ekspresi reguler seseorang dapat secara efisien membangun otomat terbatas deterministik yang mengenali bahasa yang diwakili oleh ekspresi ini.

    Pernyataan ini adalah salah satu contohnya teorema sintesis: sesuai dengan deskripsi tugas (bahasa as ekspresi reguler) sebuah program (DFA) yang mengeksekusinya dibangun secara efektif. Kebalikannya juga benar - teorema analisis.

    Teorema 5.2. Untuk setiap otomat hingga deterministik (atau non-deterministik), seseorang dapat membangun ekspresi reguler, yang mewakili bahasa yang dikenali oleh robot ini.

    Bukti teorema ini cukup teknis dan berada di luar cakupan kursus kita.

    Dengan demikian, kita dapat menyimpulkan bahwa kelas bahasa automata yang terbatas bertepatan dengan kelas bahasa biasa. Berikut ini, kami hanya akan menyebutnya kelas bahasa automata.

    Otomat M r yang dibangun dalam bukti Teorema 5.1

    Definisi Dasar Ekspresi reguler dalam alfabet dan himpunan beraturan yang dilambangkannya didefinisikan secara rekursif sebagai berikut: 1) ekspresi reguler yang menyatakan himpunan beraturan; 2) e adalah ekspresi reguler yang menunjukkan himpunan beraturan (e); 3) jika a , maka a adalah ekspresi reguler yang menunjukkan himpunan beraturan (a); 4) jika p dan q adalah ekspresi reguler yang menunjukkan himpunan beraturan P dan Q, maka a) (p+q) adalah ekspresi reguler yang menunjukkan P Q; b) pq adalah ekspresi reguler yang menunjukkan PQ; c) p* adalah ekspresi reguler yang menunjukkan P*; 5) tidak ada yang lain adalah ekspresi reguler.

    Definisi dasar Prioritas: * (iterasi) – prioritas tertinggi; rangkaian; + (persatuan). Jadi 0 + 10* = (0 + (1 (0*))). Contoh: 1. 01 artinya (01); 2. 0* - (0*); 3. (0+1)* - (0, 1)*; 4. (0+1)* 011 - berarti himpunan semua string yang terdiri dari 0 dan 1 dan diakhiri dengan string 011; 5. (a+b) (a+b+0+1)* berarti himpunan semua string (0, 1, a, b)* dimulai dengan a atau b.

    Definisi utama Lemma: 1) α + = + 2) * = e 3) + (β + ) = (α + ) + 4) (βγ) = (αβ)γ 5 ) ( + ) = + 6) (α + )γ = + 7) e = eα = 8) = 9) +α* = * 10) (α*)* = * 11) +α = 12) + =

    Komunikasi RT dan RM RM adalah bahasa yang dihasilkan oleh RT. Contoh: x = a+b, y = c+d, x X = (a, b), y Y = (c, d), x + y X Y = (a, b, c, d). Penggabungan: xy XY = (ac, iklan, bc, bd). k(u+o)t (k)(u, o)(t) = (paus, kucing) atau dengan Lemmas No. 5 dan No. 6 k(u+o)m = paus + kucing (paus, kucing) . Iterasi: x = a, x* X* = (e, a, aaa, …), yaitu x* = e + xxx + …

    Hubungan RT dan RM Iterasi penggabungan dan penyatuan: (xy)* = e + xyxyxy + ... (x + y)* = e + (x + y)(x + y) + ... = = e + xx + xy + yx + yy + xxx + … Contoh: 0 + 1(0+1)* (0) ((1) (0, 1)*) = (0, 1, 10, 11, 100, 101, 110, 111…). Persatuan komutatif: x + y = y + x Penggabungan bukan: xy yx

    Hubungan antara RT dan PM Contoh Prioritas: x + yz (x, yz), (x + y)z (xz, yz), x + y* (e, x, y, yyy, yyyy, …), (x + y)* (e, x, y, xx, xy, yx, yy, xxx, …), (xy)* (e, xyxy, …), xy* (x, xyy, xyyy, …). Lemma baru: a* + e = a*; (a + e)* = a*; a*a* = a*; e* = e; dll.

    Sistem persamaan regular Persamaan dengan koefisien regular X = a. X + b memiliki solusi (titik tetap terkecil) a*b: aa*b + b = (aa* + e)b = a*b Sistem persamaan dengan koefisien reguler: X 1 = 10 + 11 X 1 + 12 X 2 + … + 1 n. Xn X 2 \u003d 20 + 21 X 1 + 22 X 2 + ... + 2 n. Xn………………………. . Xn = n 0 + n 1 X 1 + n 2 X 2 + … + nn. Xn Tidak Diketahui – = (X 1, X 2, …, Xn).

    Sistem persamaan reguler Algoritma solusi (metode Gauss): Langkah 1. Tetapkan i = 1. Langkah 2. Jika i = n, lanjutkan ke langkah 4. Jika tidak, tulis persamaan untuk Xi dalam bentuk Xi = Xi + (β = 0 + i +1 Xi+1 + … + n.Xn). Kemudian, di ruas kanan untuk persamaan Xi+1, …, Xn, kita ganti Xi dengan ekspresi reguler *β. Langkah 3. Naikkan i sebanyak 1 dan kembali ke langkah 2. Langkah 4. Tulis persamaan untuk Xn sebagai Xn = Xn + . Pergi ke langkah 5 (dengan i = n). Langkah 5. Persamaan untuk Xi adalah Xi = Xi + . Tulis pada keluaran Xi = *β, dalam persamaan untuk Xi– 1, …, X 1 menggantikan *β sebagai ganti Xi. Langkah 6. Jika i = 1, hentikan, jika tidak turunkan i sebanyak 1 dan kembali ke langkah 5.

    Transformasi DFA ke RW Untuk DFA M = (Q, , , q 0, F) kita buat sistem dengan koefisien regular dimana = Q: 1. kita tentukan ij: = ; 2. jika (Xi, a) = Xj, a , maka ij: = ij + a; 3. jika Xi F atau (Xi,) = HALT, maka i 0: = e. Setelah menyelesaikan RV yang diinginkan adalah X 1 = q 0.

    Konversi DFA ke RW Contoh: untuk bilangan titik tetap, kita mendapatkan sistem q 0 = + q 0 + sq 1 + pq 2 + dq 3 + q 4 q 1 = + q 0 + q 1 + pq 2 + dq 3 + q 4 q 2 = + q 0 + q 1 + q 2 + q 3 + dq 4 q 3 = e + q 0 + q 1 + q 2 + dq 3 + pq 4 = e + q 0 + q 1 + q 2 + q 3 + dq 4 Di sini: s adalah tanda bilangan, s = "+" + "-"; p – titik desimal, p = ". "; d - angka, d = "0" + "1" + ... + "9".

    Konversi DFA ke RW Solusi: q 0 = *(kuadrat 1 + pq 2 + dq 3 + q 4 +) = kuadrat 1 + pq 2 + dq 3 q 1 = + q 0 + q 1 + pq 2 + dq 3 + q 4 = pq 2 + dq 3, q ​​2 = + q 0 + q 1 + q 2 + q 3 + dq 4 = dq 4, q 3 = e + q 0 + q 1 + q 2 + dq 3 + pq 4 = dq 3 + pq 4 + e, q 4 = e + q 0 + q 1 + q 2 + q 3 + dq 4 = dq 4 + e. Dari persamaan ketiga: q 3 \u003d dq 3 + pq 4 + e \u003d d * (pq 4 + e). Dari persamaan keempat: q 4 = dq 4 + e = d*.

    Konversi DFA ke RW Terbalik: q 3 = d*(pq 4 + e) ​​​​= d*(pd* + e), q 2 = dq 4 = dd*, q 1 = pq 2 + dq 3 = pdd* + dd *(pd* + e), q 0 = kuadrat 1 + pq 2 + dq 3 = s(pdd* + dd*(pd* + e)) + pdd* + dd*(pd* + e). Jadi, DFA ini sesuai dengan RE s(pdd* + dd*(pd* + e)) + pdd* + dd*(pd* + e). Untuk menyederhanakan: s(pdd* + dd*(pd* + e)) + pdd* + dd*(pd* + e) ​​​​= = spdd* + sdd*(pd* + e) ​​+ pdd* + dd*(pd* + e) ​​= (s + e)(pdd* + dd*(pd* + e)) Untuk notasi yang lebih pendek, Anda dapat menggunakan iterasi positif aa* = a*a = a+: (s + e )(pdd* + dd* (pd* + e)) = (s + e)(pd+ + d+pd* + d+)

    Transformasi DFA ke RT Memetakan grafik fungsi transisi DFA ke operasi ekspresi reguler dasar: q 0 a b a q 1 q 2 q 1 q 0 a+b a b ab q 2 a*

    Konversi DFA ke RT Kombinasi operasi yang lebih kompleks: q 0 a q 1 b b b q 0 a q 2 q 1 (a + e)b c b q 0 q 2 ab(cab)* q 0 (a + b)* q 0 a q 1 aa* = a+ q 0 a q 1 a b a a a (ab)+ q 2 b q 1 c e + (a + b)c*

    Konversi DFA ke RW Untuk RW (s + e)(pd+ + d+(pd* + e)): q 0 p q 2 d s p q 1 d d q 3 d p q 4 d q 5 d

    Ekspresi Reguler Pemrograman Waktu Nyata: Dibangun ke dalam banyak bahasa pemrograman (PHP, Java. Script, ...); Diimplementasikan sebagai plug-in (misalnya, kelas Regex untuk platform .NET). Perbedaan bentuk tulisan : x? = x + e x(1, 3) = x + xxx dst.

    Pemrograman RT Konstruksi Kelas Regex (System.Text.Regular.Expressions): Interpretasi Urutan Escape Karakter b Ketika digunakan dalam tanda kurung siku, cocok dengan karakter "←" (u 0008) t, r, n, a, f, v Tab (u 0009), carriage return (u 000 D), baris baru (u 000 A), dll. c. X Karakter kontrol (mis. c. C adalah Ctrl+C, u 0003) e Escape (u 001 B) ooo Oktal karakter ASCII xhh Hex karakter ASCII uhhhh Karakter Unicode Karakter berikut ini bukan karakter PB khusus. Semua karakter khusus harus diloloskan dengan karakter ini. Contoh (dalam contoh, pola dan string pencarian diberikan, kecocokan yang ditemukan dalam string digarisbawahi): @"rnw+" – "rn. Ada n dua string di sini" .

    Pemrograman RT Subset karakter. Karakter apa pun kecuali akhir string (n) Karakter apa pun dari himpunan [^xxx] Karakter apa pun kecuali karakter dari himpunan Karakter apa pun dari rentang ] Kurangi satu set atau rentang dari p(name) Karakter apa pun yang ditentukan oleh Unicode kategori bernama nama P (nama) Setiap karakter selain yang ditentukan oleh Unicode kategori bernama nama w Kumpulan karakter yang digunakan dalam menentukan pengidentifikasi W Kumpulan karakter yang tidak digunakan dalam menentukan pengenal s Spasi S Apa pun kecuali spasi d Digit D Bukan digit Contoh: @ ". +" – "rn. Ada n dua baris di sini"; @"+" - "0xabcfx"; @"[^fx]+" – "0 xabcfx"; @"+" - "0xabcfx"; @"[^a-f]+" – "0 xabcfx"; @"]+" – "0xabcfx"; @"p(Lu)" - "Lampu Kota"; // Lu - huruf besar @"P(Lu)" - "Kota"; @"p(Is. Cyrillic)" - "ha. OS"; // Adalah. Sirilik - huruf Rusia

    Pemrograman PB Jangkar ^, A Di awal string $, Z Di akhir string atau hingga karakter "n" di akhir string z Di akhir string G Di mana kecocokan sebelumnya berakhir b Word batas B Setiap posisi tidak pada batas kata Contoh: @ "G(d)" - "(1)(3)(5)(9)"; // tiga pertandingan (1), (2) dan (3) @"bnS*ionb" – "donasi negara"; @"Bendw*b" – "akhir mengirimkan pemberi pinjaman bertahan".

    Pemrograman Operasi RT (pengukur) *, *? Iterasi +, +? Iterasi positif? , ? ? Nol atau satu kecocokan (n), (n)? Tepat n cocok (n, ), (n, )? Setidaknya n cocok (n, m), (n, m)? Dari n ke m cocok Contoh (penghitung pertama rakus, mencari elemen sebanyak mungkin, yang kedua malas, mencari elemen sesedikit mungkin): @"d(3, )" – "888 -5555"; @"^d(3)" - "913 -913"; @"-d(3)$" - "913 -913"; @"5+? 5" - "888 -5555"; // tiga pertandingan - 55, 55 dan 55 @"5+5" - "888 -5555".

    Pengelompokan Pemrograman RT () Grup secara otomatis diberi nomor (?:) Jangan simpan grup (?) atau (? "nama") Jika kecocokan ditemukan, buat grup bernama (?) atau Hapus grup yang ditentukan sebelumnya dan (? "nama-nama") menyimpan di grup baru substring antara grup yang ditentukan sebelumnya dan grup baru (? imnsx :) Mengaktifkan atau menonaktifkan salah satu dari lima (? -imnsx:) opsi yang memungkinkan dalam grup: i - case tidak peka; s adalah satu baris (maka ". " adalah karakter apa pun); m – mode multiline (“^” , “$” – awal dan akhir setiap baris); n - jangan tangkap grup yang tidak disebutkan namanya; x - mengecualikan spasi yang tidak diloloskan dari pola dan menyertakan komentar setelah tanda angka (#) (?=) Pernyataan lookahead positif panjang nol

    Pemrograman RE (? !) Pernyataan lookahead negatif dengan panjang nol (?) Bagian ekspresi yang tidak kembali (serakah) Contoh: @"(an)+" – "bananas annals"; @"an+" – "sejarah pisang"; // membandingkan, tiga pertandingan - an, an dan ann @"(? i: an)+" - "ba. NAnas annals"; @"+(? =d)" – "abc xyz 12 555 w"; @"(?

    Src="https://website/presentation/-112203859_437213351/image-24.jpg" alt="(!LANG:Programming RT Nomor referensi Referensi grup k Referensi grup bernama Contoh: @"> Программирование РВ Ссылки число Ссылка на группу k Ссылка на именованную группу Примеры: @"(w)1" – "deep"; @"(? w)k " – "deep". Конструкции изменения | Альтернатива (соответствует операции объединения) (? (выражение)да|нет) Сопоставляется с частью «да» , если выражение соответствует; в противном случае сопоставляется с необязательной частью «нет» (? (имя)да|нет), Сопоставляется с частью «да» , если названное имя (? (число)да|нет) захвата имеет соответствие; в противном случае сопоставляется с необязательной частью «нет» Пример: @"th(e|is|at)" – "this is the day";!}

    Substitusi Pemrograman RT $number Mengganti bagian string yang sesuai dengan grup dengan nomor yang ditentukan $(name) Mengganti bagian dari string yang sesuai dengan grup dengan nama yang ditentukan $$ Mengganti $ $& Mengganti dengan salinan lengkap match $` Ganti teks string input hingga kecocokan $" Ganti teks baris input setelah kecocokan $+ Ganti grup yang terakhir ditangkap $_ Ganti seluruh baris Komentar (? #) Komentar sebaris # Komentar ke akhir baris

    Hasil Pemrograman RT Regex: Regex Matches() Match. Koleksi Pertandingan Grup() Grup. Koleksi Grup Tangkap() Tangkap. Koleksi Tangkapan()

    Contoh Pemrograman RT dalam C++ CLI (Aplikasi Konsol Visual C++/CLR/CLR): int main() ( Regex ^r = gcnew Regex(L"((\d)+)+"); Cocokkan ^m = r-> Cocokkan (L"123 456"); int match. Count = 0; while (m->Success) ( Console: : Write. Line(L"Match(0)", ++match. Count); for (int i = 1; i Grup->Hitung; i++) ( Grup ^g = m->Grup[i]; Konsol: : Tulis. Baris(L" Grup (0) = "(1)"", i, g-> Nilai ); for (int j = 0; j Captures->Count; j++) ( Capture ^c = g->Captures[j]; Console: : Write.Line(L" Capture(0) = "(1)" , position = (2), length = (3)", j, c, c->Index, c->Length); ) ) m = m->Next. Match(); ) return 0; ) System: : Text : :Reguler. ekspresi

    Penyertaan tindakan dan pencarian kesalahan Membatasi jumlah angka penting dalam suatu bilangan: (s + e)(pd+ + d+(pd* + e)) s = +|p = . d = ds + e = s? = (+|-)? pd* + e = (pd*)? =(.d*)? @"(+|-)? (. d+|d+(. d*)?)" atau @"^(+|-)? (. d+|d+(. d*)?)$" Regex r = Regex baru (@"^(+|-)? (. (? "digit"d)+|(? "digit"d)+(. (? "digit"d)*)?)$"); Cocokkan m = r. Cocok("+1. 23456789"); if (m. Sukses) ( Grup g = m. Grup["digit"]; if (g. Menangkap. Hitung

    Mengaktifkan Tindakan dan Menemukan Kesalahan Menentukan Posisi Kesalahan: Regex r = new Regex(@"(+|-)? (. (? "digit"d)+|(? "digit"d)+(. (? " angka"d )*)?)"); string str = "+1.2345!678"; Cocokkan m = r. Pertandingan(str); if (m. Sukses) ( Grup g = m. Grup["digit"]; if (g. Menangkap. Hitung 0) Console. Write. Line("Error pada posisi 1: karakter tak terduga "(0)"", str ); else if (m.Panjang

    Mengaktifkan tindakan dan mencari kesalahan Menentukan posisi kesalahan: 1. posisi pertama dari string input (1), jika pertandingan pertama tidak dimulai dari posisi Indeks = 0; 2. posisi setelah pertandingan terakhir (cocok. Panjang + 1), jika tidak cocok dengan posisi terakhir dari string input; 3. posisi jeda pertama antar pertandingan (match[i]. Index + match[i]. Length + 1), jika karakter yang mengikuti pertandingan sebelumnya bukan karakter pertama dari pertandingan berikutnya.

    indeks) istirahat; indeks = m[i]. Indeks + m[i]. panjang; ) Konsol. menulis. Line("Error pada posisi (0) "(1)"", indeks + 1, str); ) "abc. xyz. pqr" benar; + abc. xyz. pqr" - kesalahan pada posisi 1 ("+"); "abc. xyz. pqr!" – kesalahan pada posisi 12 (“!”); "abc. xyz!. pqr" - kesalahan pada posisi 8 ("!").

    Penyertaan tindakan dan mencari kesalahan Tapi! "abc. xyz. +pqr" - kesalahan pada posisi 8 (". "). Varian pola baru: @"w+(. w+)*(. (? !$))? " Validasi: "abc. xyz. +pqr" - kesalahan pada posisi 9 ("+"); "abc. xyz. pqr. "- kesalahan pada posisi 12 (". ").

    Definisi seimbang: "(? "x")" menambahkan satu elemen ke koleksi bernama "x"; "(? "-x")" menghapus satu elemen dari koleksi "x"; "(? (x)(? !))" memeriksa bahwa tidak ada elemen yang tersisa dalam koleksi "x". Bahasa L, menjelaskan pernyataan bersarang dari bahasa Pascal “begin end; ': @"^s*((? "mulai+)+(? "-mulai"berakhir*; s*)+)*(? (mulai)(? !))$".

    DFA adalah kasus khusus dari NFA. Di dalam dia:

      tidak ada keadaan dengan -transisi;

      untuk setiap state S dan simbol input a, terdapat paling banyak satu arc yang keluar dari S dan diberi label a.

    Sebuah DFA hanya memiliki maksimal satu transisi untuk setiap simbol input dari setiap state. Jika sebuah tabel digunakan untuk mewakili fungsi transisi DFA, maka setiap entri hanya akan berisi satu status. Dengan demikian, mudah untuk memeriksa apakah DFA tertentu mengizinkan baris tertentu, karena hanya ada satu jalur dari status awal, yang diberi label dengan baris ini.

    Gambar 3 menunjukkan grafik transisi DFA yang memungkinkan bahasa yang sama (a|b) * a(a|b)(a|b) sebagai NFA pada Gambar 1.

    Gambar 3. DFA yang mengizinkan string (a|b) * a(a|b)(a|b).

    Sebuah otomat terbatas deterministik M yang menerima bahasa tertentu:

    M = ((1, 2, 3, 4, 5, 6, 7, 8), (a, b), D, 1, (3, 5, 6, 8))

    Fungsi transisi D didefinisikan sebagai berikut:

    Membangun nc dari ekspresi reguler

    1. Untuk , NFA memiliki bentuk berikut (0 adalah keadaan awal, 1 adalah keadaan akhir):

    2. Untuk a yang disertakan dalam bahasa NFA yang diberikan:

    3. Misalkan N(s) dan N(t) adalah NFA untuk ekspresi reguler s dan t.

      Untuk ekspresi reguler s|t, NFA komposit memiliki bentuk berikut:

    b. Untuk ekspresi reguler st NFA:

    dengan. Untuk ekspresi s*, NFA memiliki bentuk:

    d. Untuk ekspresi dalam tanda kurung (s), NFA N(s) digunakan seperti pada paragraf a.

    Setiap negara bagian baru menerima nama individu. Konstruksi NFA N(r) memiliki sifat-sifat berikut:

      N(r) memiliki sejumlah keadaan yang tidak melebihi jumlah simbol lebih dari 2 kali.

      N(r) memiliki tepat satu keadaan awal dan satu keadaan akhir. Status akhir tidak memiliki transisi keluar.

      Setiap state N(r) memiliki 1 transisi untuk simbol dari alfabet (), atau tidak lebih dari 2 transisi keluar.

    Mengubah na ke dka.

    NFA pada Gambar 1 memiliki 2 transisi dari keadaan 0 untuk simbol a: keadaan 0 dan 1. Transisi seperti itu ambigu, seperti transisi dalam . Pemodelan NSC semacam itu dengan bantuan program komputer jauh lebih sulit. Definisi admissibility menyatakan bahwa harus ada beberapa jalur dari keadaan awal ke keadaan akhir, tetapi ketika ada beberapa jalur untuk string input yang sama, semuanya harus dipertimbangkan untuk menemukan jalur ke keadaan akhir atau untuk mencari tahu bahwa tidak ada jalan seperti itu.

    Di tabel transisi NFA, setiap entri sesuai dengan satu set status, dan di tabel transisi DFA - hanya satu. Inti dari transformasi adalah bahwa setiap keadaan DFA sesuai dengan himpunan keadaan NFA. DFA menggunakan statusnya untuk melacak semua kemungkinan status NFA setelah membaca simbol input berikutnya. Artinya, setelah membaca aliran input, DFA berada dalam status yang mewakili serangkaian status NFA tertentu yang dapat dijangkau dari yang awal di sepanjang jalur yang sesuai dengan string input. Jumlah status DFA semacam itu dapat secara signifikan melebihi jumlah status NFA (ketergantungan eksponensial), tetapi dalam praktiknya hal ini sangat jarang, dan terkadang ada lebih sedikit status di DFA daripada di NFA.

    Mari kita pertimbangkan transformasi seperti itu menggunakan contoh spesifik. Gambar 4 menunjukkan NFA lain yang memungkinkan bahasa (a|b) * a(a|b)(a|b) (seperti pada Gambar 1 dan 3).

    Gambar 4. NFA yang mengizinkan bahasa (a|b) * a(a|b)(a|b)

    Transisi dari keadaan 13 ke keadaan 14 yang digambarkan pada gambar dapat direpresentasikan dengan cara yang sama dengan transisi dari keadaan 8 ke keadaan 13.

    Mari buat DFA untuk bahasa yang diberikan. Keadaan awal dari DFA ekivalen adalah keadaan A =(0, 1, 2, 4, 7), yaitu keadaan yang dapat dicapai dari 0 sampai .

    Alfabet karakter input adalah (a, b). Dari keadaan awal A, seseorang dapat menghitung keadaan yang dapat dicapai sehubungan dengan a. Sebut saja keadaan ini B = (1, 2, 3, 4, 6, 7, 8, 9, 11, 13, 14).

    Di antara state di A, hanya state 4 yang memiliki transisi pada b ke state 5, jadi DFA memiliki transisi pada b dari A ke state C = (1, 2, 4, 5, 6, 7).

    Jika kita melanjutkan proses ini dengan keadaan B dan C, semua himpunan keadaan NFA akan diberi label. Jadi, kita akan memiliki set status:

    A = (0, 1, 2, 4, 7)

    B = (1, 2, 3, 4, 6, 7, 8, 9, 11, 13, 14)

    C = (1, 2, 4, 5, 6, 7)

    D = (10, 12, 13, 14)

    Keadaan A adalah awal, dan keadaan B, D, E adalah final.

    Tabel transisi lengkap ditunjukkan di bawah ini.

    Gambar 5 di bawah ini menunjukkan DFA itu sendiri untuk bahasa ini.

    Gambar 5. DFA yang menerima bahasa (a|b) * a(a|b)(a|b)

    Daftar literatur yang digunakan:

      Pentus A. E., Pentus M. R. – Teori bahasa formal

      A. Aho, R. Seti, D. Ullman - Penyusun: prinsip, teknologi, alat.

    Membangun otomat terbatas deterministik dari ekspresi reguler

    Mari kita sekarang menyajikan algoritma untuk membangun otomat hingga deterministik dari ekspresi reguler yang memungkinkan bahasa yang sama [?].

    Biarkan ekspresi reguler r diberikan dalam alfabet T. Tambahkan penanda akhir ke ekspresi reguler r: (r)#. Ekspresi reguler seperti itu akan disebut selesai. Dalam perjalanan kerjanya, algoritme akan menggunakan ekspresi reguler yang telah selesai.

    Algoritme akan beroperasi pada pohon sintaks untuk ekspresi reguler (r)# yang telah diselesaikan, setiap daunnya ditandai dengan simbol , dan masing-masing atasan bagian dalam ditandai dengan tanda salah satu operasi: (penggabungan),| (penyatuan), * (iterasi).

    Setiap daun pohon (kecuali daun elektronik) akan diberi nomor unik, yang disebut posisi, dan kami akan menggunakannya, di satu sisi, untuk merujuk ke daun di pohon, dan, di sisi lain, untuk merujuk dengan simbol yang sesuai dengan daun ini. Perhatikan bahwa jika karakter digunakan beberapa kali dalam ekspresi reguler, karakter tersebut memiliki beberapa posisi.

    Mari kita telusuri pohon T dari bawah ke atas dari kiri ke kanan dan hitung empat fungsi: nullable, firstpos, lastpos, dan followpos. Tiga fungsi pertama - nullable, firstpos dan lastpos - didefinisikan pada node pohon, dan followpos didefinisikan pada set posisi. Nilai semua fungsi kecuali nullable adalah himpunan posisi. Fungsi followpos dihitung melalui tiga fungsi lainnya.

    Fungsi firstpos(n) untuk setiap simpul n dari pohon sintaks ekspresi reguler memberikan himpunan posisi yang cocok dengan karakter pertama dalam substring, yang dihasilkan oleh subekspresi dengan simpul di n. Demikian pula, lastpos(n) memberikan himpunan posisi yang sesuai dengan karakter terakhir di substring dihasilkan oleh subekspresi dengan simpul n. Untuk simpul n yang subpohonnya (yaitu, pohon yang simpul akarnya n) dapat menghasilkan kata nol, tentukan nullable(n)=true, dan untuk simpul yang tersisa nullable(n)=false.

    Tabel untuk menghitung fungsi nullable, firstpos, dan lastpos ditunjukkan pada gambar. 3.11.

    Contoh 3.7.Dalam gambar. 3.12 menunjukkan pohon sintaks untuk ekspresi reguler lengkap (a|b) * abb# dengan hasil evaluasi fungsi firstpos dan lastpos. Di sebelah kiri setiap node adalah nilai firstpos, di sebelah kanan node adalah nilai lastpos. Perhatikan bahwa fungsi-fungsi ini dapat dihitung dalam satu traversal pohon.

    Jika i adalah posisi, maka followpos(i) adalah himpunan posisi j sehingga ada beberapa string... cd ... terjadi dalam bahasa yang dijelaskan oleh ekspresi reguler sehingga posisi i cocok dengan kemunculan c dan posisi ini j adalah entri d.

    Beras. 3.11.

    Beras. 3.12.

    Fungsi followpos juga dapat dihitung dalam satu traversal bottom-up dari pohon menurut dua aturan ini.

    1. Misalkan n adalah simpul internal dengan operasi (penggabungan), u dan v adalah turunannya. Kemudian untuk setiap posisi i yang termasuk dalam lastpos(u), kita tambahkan ke himpunan nilai followpos(i) himpunan firstpos(v).

    2. Biarkan n menjadi simpul internal dengan operasi * (iterasi), u - turunannya. Kemudian untuk setiap posisi i termasuk dalam lastpos(u), kita tambahkan ke himpunan nilai followpos(i) himpunan firstpos(u).

    Contoh 3.8. Hasil evaluasi fungsi followpos untuk ekspresi reguler dari contoh sebelumnya ditunjukkan pada Gambar. 3.13.

    Algoritma 3.3. Konstruksi langsung DFA dari ekspresi reguler.

    Pintu masuk. Ekspresi reguler r dalam alfabet T.

    Keluaran. DFA M = (Q, T, D, q 0 , F) sehingga L(M) = L(r).

    metode. Status DFA sesuai dengan set posisi.

    Awalnya, Q dan D kosong. Ikuti langkah 1-6:

    (1) Bangun pohon sintaks untuk ekspresi reguler augmented (r)#.