Dalam artikel Parsing Expressions by Recursive Descent oleh Theodore Norvell (1999) penulis mulai dengan tata bahasa berikut untuk ekspresi aritmatika:
E --> E "+" E | E "-" E | "-" E | E "*" E | E "/" E | E "^" E | "(" E ")" | v
yang sangat buruk, karena ambigu dan kiri-rekursif. Jadi dia mulai menghilangkan rekursi kiri dari sana, dan hasilnya adalah seperti ini:
E --> P {B P}
P --> v | "(" E ")" | U P
B --> "+" | "-" | "*" | "/" | "^"
U --> "-"
Tapi saya tidak tahu bagaimana dia bisa mencapai hasil ini. Ketika saya mencoba untuk menghapus rekursi kiri sendiri, saya melakukannya dengan cara berikut:
Pertama, saya mengelompokkan produksi yang tidak memiliki rekursi dalam satu kelompok, dan lainnya (rekursif kiri) dalam kelompok lain:
E --> E "+" E | E "-" E | E "*" E | E "/" E | E "^" E // L-recursive E --> v | "(" E ")" | "-" E
Selanjutnya, saya beri nama dan faktor untuk manipulasi yang lebih mudah:
E --> E B E // L-recursive; B stands for "Binary operator" E --> P // not L-recursive; P stands for "Primary Expression" P --> v | "(" E ")" | U E // U stands for "Unary operator" B --> "+" | "-" | "*" | "/" | "^" P --> "-"
Sekarang saya hanya perlu berurusan dengan dua produksi pertama, yang sekarang lebih mudah untuk ditangani.
Saya menulis ulang dua produksi pertama dengan memulai dari produksi non-L-rekursif (yang sederhana
P
, ekspresi Primer) dan mengikutinya dengan Tail opsionalT
, yang saya definisikan sebagai sisa produksi asli kurang dari non-rekursif kiri-rekursif pertama (yaitu, hanyaB E
) diikuti oleh EkorT
, atau yang bisa kosong:E --> P T T --> B E T |
(perhatikan alternatif kosong untuk ekor).
Dua produksi ini sekarang saya dapat menulis ulang di EBNF seperti ini:
E --> P {B E}
yang hampir seperti apa yang penulis dapatkan, tetapi saya memiliki
E
alih - alihP
di dalam pola pengulangan nol atau lebih (Ekor). Produksi lain yang saya dapatkan sama persis seperti yang dia dapatkan:P --> v | "(" E ")" | U E B -> "+" | "-" | "*" | "/" | "^" U -> "-"
tapi di sini juga saya miliki
E
daripadaP
di produksi pertama untukP
.
Jadi, pertanyaan saya adalah: Apa yang saya lewatkan? Transformasi aljabar apa pada sintaks yang saya perlukan untuk melanjutkan sekarang untuk mendapatkan bentuk yang sama persis dengan yang didapat autor? Saya mencoba substitusi E
, tetapi itu hanya membuat saya menjadi loop. Saya menduga bahwa saya perlu entah bagaimana untuk menggantikan P
untuk E
, tapi saya tidak tahu apapun transformasi hukum untuk membenarkan itu. Mungkin Anda tahu apa langkah terakhir yang hilang?
Jawaban:
Langkah yang hilang:
tulis ulang E dalam T:
Sederhanakan T:
Setara dengan:
Dan itu dia.
sumber
T
bersama menjadi satuT
? Apakah ada aturan untuk itu? (Saya menduga itu bisa mirip dengan aturan dalam logika aljabar Boolean yang mengatakan "aa = a".)*
? Saya melihat di "Buku Naga" (3.3, hal.91) itux** = x*
. Apakah itu aturan yang sama yang Anda gunakan?