Ketika Anda menggunakan tata bahasa debugger, itu memungkinkan Anda melihat dengan tepat bagaimana mesin mengurai string - gagal adalah normal dan diharapkan. Dianggap, misalnya, cocok a+b*
dengan string aab
. Anda harus mendapatkan dua pertandingan untuk 'a', diikuti oleh gagal (karena b
tidak a
) tetapi kemudian akan mencoba lagi b
dan berhasil mencocokkan.
Ini mungkin lebih mudah dilihat jika Anda melakukan pergantian dengan ||
(yang memberlakukan perintah). Jika Anda memiliki
token TOP { I have a <fruit> }
token fruit { apple || orange || kiwi }
dan Anda parsing kalimat "Saya punya kiwi", Anda akan melihatnya pertandingan pertama "Saya punya", diikuti oleh dua gagal dengan "apel" dan "oranye", dan akhirnya cocok dengan "kiwi".
Sekarang mari kita lihat kasus Anda:
TOP # Trying to match top (need >1 match of score)
| score # Trying to match score (need >1 match of lc/uc)
| | lc # Trying to match lc
| | * MATCH "a" # lc had a successful match! ("a")
| * MATCH "a " # and as a result so did score! ("a ")
| score # Trying to match score again (because <score>+)
| | lc # Trying to match lc
| | * MATCH "b" # lc had a successful match! ("b")
| * MATCH "b " # and as a result so did score! ("b ")
…………… # …so forth and so on until…
| score # Trying to match score again (because <score>+)
| | uc # Trying to match uc
| | * MATCH "G" # uc had a successful match! ("G")
| * MATCH "G\n" # and as a result, so did score! ("G\n")
| score # Trying to match *score* again (because <score>+)
| * FAIL # failed to match score, because no lc/uc.
|
| # <-------------- At this point, the question is, did TOP match?
| # Remember, TOP is <score>+, so we match TOP if there
| # was at least one <score> token that matched, there was so...
|
* MATCH "a b c d e f g\nA B C D E F G\n" # this is the TOP match
Kegagalan di sini adalah normal: pada titik tertentu kita akan kehabisan <score>
token, sehingga kegagalan tidak bisa dihindari. Ketika itu terjadi, mesin tata bahasa dapat beralih ke apa pun yang muncul setelah <score>+
tata bahasa Anda. Karena tidak ada apa-apa, kegagalan itu sebenarnya menghasilkan kecocokan seluruh string (karena TOP
cocok dengan implisit /^…$/
).
Selain itu, Anda dapat mempertimbangkan untuk menulis ulang tata bahasa Anda dengan aturan yang menyisipkan <.ws> * secara otomatis (kecuali penting untuk hanya menjadi satu ruang saja):
grammar test {
rule TOP { <score>+ }
token score {
[
| <uc>
| <lc>
]+
}
token uc { <[A..G]> }
token lc { <[a..g]> }
}
Selanjutnya, IME, Anda mungkin ingin juga ingin menambahkan token proto untuk uc / lc, karena ketika Anda memilikinya [ <foo> | <bar> ]
Anda akan selalu memiliki salah satu dari mereka yang tidak terdefinisi yang dapat membuat memprosesnya dalam kelas tindakan agak mengganggu. Kamu bisa mencoba:
grammar test {
rule TOP { <score> + }
token score { <letter> + }
proto token letter { * }
token letter:uc { <[A..G]> }
token letter:lc { <[a..g]> }
}
$<letter>
akan selalu didefinisikan dengan cara ini.