जब आप व्याकरण डीबगर का उपयोग करते हैं, तो यह आपको यह देखने देता है कि इंजन स्ट्रिंग को कैसे पार्स कर रहा है - विफल सामान्य और अपेक्षित हैं। माना जाता है, उदाहरण के लिए, a+b*
स्ट्रिंग के साथ मिलान aab
। आपको 'ए' के लिए दो मैच मिलने चाहिए, उसके बाद फेल होना (क्योंकि b
नहीं है a
) लेकिन फिर यह b
मैच और सफलतापूर्वक मैच होगा।
यह अधिक आसानी से देखा जा सकता है यदि आप एक वैकल्पिक व्यवस्था करते हैं ||
(जो आदेश को लागू करता है)। यदि आपके पास है
token TOP { I have a <fruit> }
token fruit { apple || orange || kiwi }
और आप वाक्य "मेरे पास एक कीवी है" को पार्स करते हैं, आप इसे पहले मैच "मेरे पास" देखेंगे, उसके बाद "सेब" और "नारंगी" के साथ दो असफलताएं, और अंत में "कीवी" के साथ एक मैच होगा।
अब आपके मामले को देखते हैं:
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
यहां असफल होना सामान्य है: किसी समय हम <score>
टोकन से बाहर निकल जाएंगे , इसलिए असफल होना अपरिहार्य है। जब ऐसा होता है, तो व्याकरण इंजन <score>+
आपके व्याकरण में आने के बाद आगे बढ़ सकता है । चूंकि कुछ भी नहीं है, यह वास्तव में पूरे स्ट्रिंग के एक मैच के परिणामस्वरूप होता है (क्योंकि TOP
अंतर्निहित के साथ मेल खाता है /^…$/
)।
इसके अलावा, आप एक नियम के साथ अपने व्याकरण को फिर से लिखने पर विचार कर सकते हैं, जो <।
grammar test {
rule TOP { <score>+ }
token score {
[
| <uc>
| <lc>
]+
}
token uc { <[A..G]> }
token lc { <[a..g]> }
}
इसके अलावा, IME, आप uc / lc के लिए एक प्रोटो टोकन भी जोड़ना चाह सकते हैं, क्योंकि जब आपके पास [ <foo> | <bar> ]
होगा तो आपके पास हमेशा उनमें से एक अपरिभाषित रहेगा जो उन्हें एक्शन क्लास में थोड़ा परेशान कर सकता है। तुम कोशिश कर सकते हो:
grammar test {
rule TOP { <score> + }
token score { <letter> + }
proto token letter { * }
token letter:uc { <[A..G]> }
token letter:lc { <[a..g]> }
}
$<letter>
हमेशा इस तरह से परिभाषित किया जाएगा।