Dapatkah seseorang mencerahkan saya mengapa keturunan parser rekursif dengan backtracking yang mencoba produksi dan S → a a (agar) tidak mengakui bahasa yang dibentuk oleh grammar S → a S a | a a .
Tampaknya hanya mengurai kata-kata dari bahasa .
Saya membuat parser seperti itu menggunakan ABNF Parser Generator dengan aturan produksi S = "a" S "a" / "aa"
dan parser tidak mengenali kata aaaaaa
, misalnya.
Saya akan berharap untuk menggunakan produksi sampai gabungan dari parse pohon node terminal dari mulai kiri dengan 7 's, dan kemudian naik pohon parse memilih produksi S → a sebuah bukannya sampai terlihat pohon seperti ini:a
S
/ | \
a S a
/ | \
a S a
/ \
a a
context-free
formal-grammars
compilers
parsers
Meribold
sumber
sumber
aaaaaa
.aaaaaa
harus diurai dan tidak. Tapiaaaa
apakah parse. Anda tampaknya benar tentang kekuatan 2. Benda itu harus disadap. hanya diuraiaa
denganS = "aa" / "a" [S] "a"
. Bisakah Anda melacak apa yang dilakukan parser?Jawaban:
Ini tidak banyak jawaban, tetapi pohon parse tidak sesuai dengan komentar normal.
Tata bahasa Anda harus mengurai string a a a a a a .S→ a Sa | a a a a a a a a
Tetapi pohon parse memiliki bentuk sebagai berikut:
atau jika Anda lebih suka presentasi ini, dengan terminal pada jalur yang berbeda
Saya memeriksa bahwa generator parser ABNF tampaknya tidak berfungsi, tetapi saya tidak tahu bagaimana melacak apa fungsinya.
Tampaknya memang rekonsiliasi set yang bukan apa yang didefinisikan oleh tata bahasa.{ a2n | n≥1}
Agak mengejutkan untuk memiliki situs yang rumit di sekitar parser kereta, yang selanjutnya menggunakan teknik parsing yang sama sekali tidak menarik.
Setelah melihat lebih jauh:
Saya rasa saya menemukan satu sumber masalah. Kurung kotak berarti opsional .
Jadi tata bahasa Anda harus ditulis
S = "a" S "a" / "aa"
atauS = "a" [S] "a"
. Maka tampaknya berfungsi dengan benar.Tetapi sistem ini tampaknya hilang ketika memiliki dua kali aturan yang sama dalam bentuk yang berbeda. Saya tidak yakin mengapa.
Saya tidak menemukan halaman yang menjelaskan masalah sintaksis ini untuk menentukan tata bahasa.
Saya masih menganggap buggy itu.
sumber
S ::= 'a'<S>'a' | 'a''a'
aaaaaa
saat digunakanS = "a" S "a" / "aa"
, tetapi Anda tampaknya benar tentang tanda kurung.S = "a" S "a" / "aa"
... Saya menguji terlalu cepat, dan mengklik menghasilkan bukan parse.s1()
true
s()
s2()
Pertimbangkan untuk menguraikan kata
aaaaaa
lagi. Pada satu titik, pohon parse akan terlihat seperti ini:s()
true
S
Saya cenderung menganggap ini masalah dengan implementasi saya dan tidak dengan backtracking parser keturunan rekursif pada umumnya.
sumber
Ini adalah fitur bukan bug
Lihat dari dekat kapan & di mana terjadi backtracking:
Poin penting di sini adalah bahwa parser melakukan backtracks setelah posisi, di mana karakter yang cocok terakhir ditemukan. Itu sebabnya ia "melompat" dari pohon 11 dengan l = aaaaaaaa ke pohon ke-12 dengan l = aaaa dengan menggunakan S -> aa di l [7].
sumber