Dilbilgisi hata ayıklayıcısını kullandığınızda, motorun dizeyi nasıl ayrıştırdığını tam olarak görmenizi sağlar - başarısızlıklar normal ve beklenen bir durumdur. Örneğin, a+b*
dize ile eşleştirme olarak düşünülür aab
. 'A' için iki maç almanız ve ardından başarısız olmanız gerekir (çünkü b
değildir a
) ancak daha sonra yeniden dener b
ve başarıyla eşleşir.
Eğer ||
(siparişi zorlar) ile bir değişiklik yaparsanız bu daha kolay görülebilir . Eğer varsa
token TOP { I have a <fruit> }
token fruit { apple || orange || kiwi }
ve "Ben bir kivim var" cümlesini ayrıştırırsınız, ilk maçta "Ben" var, ardından "elma" ve "portakal" ile iki başarısızlık ve son olarak da "kivi" ile bir eşleşme görürsünüz.
Şimdi davanıza bakalım:
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
Buradaki başarısızlık normaldir: bir noktada <score>
belirteçler tükenir, bu nedenle başarısızlık kaçınılmazdır. Bu olduğunda, dilbilgisi motoru dilbilginizde gelen her şeye geçebilir <score>+
. Hiçbir şey olmadığından, bu başarısızlık aslında tüm dizenin eşleşmesiyle sonuçlanır (çünkü TOP
örtük olanlarla eşleşir/^…$/
).
Ayrıca, dilbilginizi otomatik olarak <.ws> * ekleyen bir kuralla yeniden yazmayı düşünebilirsiniz (yalnızca tek bir boşluk olması önemli değilse):
grammar test {
rule TOP { <score>+ }
token score {
[
| <uc>
| <lc>
]+
}
token uc { <[A..G]> }
token lc { <[a..g]> }
}
Ayrıca, IME, uc / lc için bir proto jetonu da eklemek isteyebilirsiniz, çünkü sahip [ <foo> | <bar> ]
olduğunuzda bunlardan her zaman tanımlanamayacaksınız, bu da onları bir eylem sınıfında işlemeyi biraz can sıkıcı hale getirebilir. Deneyebilirsiniz:
grammar test {
rule TOP { <score> + }
token score { <letter> + }
proto token letter { * }
token letter:uc { <[A..G]> }
token letter:lc { <[a..g]> }
}
$<letter>
her zaman bu şekilde tanımlanacaktır.