Khi bạn sử dụng trình gỡ lỗi ngữ pháp, nó cho phép bạn xem chính xác cách công cụ phân tích cú pháp chuỗi - thất bại là bình thường và được mong đợi. Được xem xét, ví dụ, phù hợp a+b*
với chuỗi aab
. Bạn sẽ nhận được hai trận đấu cho 'a', sau đó là thất bại (vì b
không phải a
) nhưng sau đó nó sẽ thử lại vớib
và khớp thành công.
Điều này có thể dễ dàng nhìn thấy hơn nếu bạn thực hiện xen kẽ với ||
(thực thi lệnh). Nếu bạn có
token TOP { I have a <fruit> }
token fruit { apple || orange || kiwi }
và bạn phân tích câu "Tôi có một quả kiwi", bạn sẽ thấy nó khớp đầu tiên "Tôi có một", sau đó là hai lần thất bại với "quả táo" và "quả cam", và cuối cùng là trận đấu với "quả kiwi".
Bây giờ hãy xem trường hợp của bạn:
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
Thất bại ở đây là bình thường: đến một lúc nào đó chúng ta sẽ hết <score>
token, vì vậy một thất bại là không thể tránh khỏi. Khi điều đó xảy ra, bộ máy ngữ pháp có thể chuyển sang bất cứ thứ gì xuất hiện sau <score>+
ngữ pháp của bạn. Vì không có gì, thất bại đó thực sự dẫn đến một trận đấu của toàn bộ chuỗi (vì TOP
khớp với ẩn/^…$/
).
Ngoài ra, bạn có thể xem xét viết lại ngữ pháp của mình với quy tắc tự động chèn <.ws> * (trừ khi nó chỉ là một khoảng trắng duy nhất):
grammar test {
rule TOP { <score>+ }
token score {
[
| <uc>
| <lc>
]+
}
token uc { <[A..G]> }
token lc { <[a..g]> }
}
Hơn nữa, IME, bạn cũng có thể muốn thêm mã thông báo proto cho uc / lc, bởi vì khi bạn có, [ <foo> | <bar> ]
bạn sẽ luôn có một trong số chúng không được xác định, điều này có thể khiến việc xử lý chúng trong lớp hành động hơi khó chịu. Bạn có thể thử:
grammar test {
rule TOP { <score> + }
token score { <letter> + }
proto token letter { * }
token letter:uc { <[A..G]> }
token letter:lc { <[a..g]> }
}
$<letter>
sẽ luôn được định nghĩa theo cách này.