syntax/parse
का उपयोग करने वाले मैक्रो को लिखते समय, मैंने एक स्प्लिसिंग सिंटैक्स क्लास बनाया है जो मैक्रो को प्रदान किए जा सकने वाले विकल्पों को कैप्चर करता है। ये विकल्प सभी वैकल्पिक हैं, और उन्हें किसी भी क्रम में प्रदान किया जा सकता है। ~optional
अंडाकार सिर पैटर्न का उपयोग करते हुए यह पर्याप्त आसान बनाता है:मैं सिंटैक्स-पार्स के साथ कैप्चर किए गए वैकल्पिक विशेषताओं को कैसे समूहित कर सकता हूं?
(define-splicing-syntax-class opts
(pattern (~seq (~or (~optional (~seq #:a a))
(~optional (~seq #:b b))
(~optional (~seq #:x x))
(~optional (~seq #:y y)))
...))
हालांकि, वहाँ एक कमी है: मैं दो समूहों में समूह इन विकल्पों में करने में सक्षम होना चाहता हूँ: समूह a
और b
, और समूह युक्त जिसमें x
और y
शामिल हैं। हालांकि, उपयोगकर्ता अभी भी किसी भी क्रम में विकल्प निर्दिष्ट है, तो हो सकता है इस उदाहरण इनपुट के लिए:
(foobar #:b 3 #:y 7 #:a 2)
मैं निम्न विशेषताओं का उत्पादन करने में सक्षम होना चाहते:
first-opts: (#:a 2 #:b 3)
second-opts: (#:y 7)
अब तक, मैंने मैन्युअल #:with
का उपयोग कर ऐसा करने में कामयाब रहे, लेकिन यह काफी नहीं है:
(define-splicing-syntax-class opts
#:attributes ([first-opts 1] [second-opts 1])
(pattern (~seq (~or (~optional (~seq #:a a))
(~optional (~seq #:b b))
(~optional (~seq #:x x))
(~optional (~seq #:y y)))
...)
#:with (first-opts ...)
#`(#,@(if (attribute a) #'(#:a a) #'())
#,@(if (attribute b) #'(#:b b) #'()))
#:with (second-opts ...)
#`(#,@(if (attribute x) #'(#:x x) #'())
#,@(if (attribute y) #'(#:y y) #'()))))
यह syntax/parse/experimental/template
से template
का उपयोग कर एक छोटा सा सरल किया जा सकता:
(define-splicing-syntax-class opts
#:attributes ([first-opts 1] [second-opts 1])
(pattern (~seq (~or (~optional (~seq #:a a))
(~optional (~seq #:b b))
(~optional (~seq #:x x))
(~optional (~seq #:y y)))
...)
#:with (first-opts ...)
(template ((?? ([email protected] #:a a))
(?? ([email protected] #:b b))))
#:with (second-opts ...)
(template ((?? ([email protected] #:a x))
(?? ([email protected] #:b y))))))
बहरहाल, यह वास्तव में सिर्फ ऊपर के लिए कुछ चीनी है, और यह वास्तव में एक खंड में प्रत्येक विकल्प की गणना करने में होने की समस्या का समाधान नहीं है। यदि मैंने, उदाहरण के लिए, #:c
विकल्प जोड़ा, तो मुझे इसे first-opts
समूह में जोड़ने की याद रखना होगा, अन्यथा इसे पूरी तरह अनदेखा कर दिया जाएगा।
मैं वास्तव में वैकल्पिक मानों के इन सेटों को समूहित करने के लिए कुछ घोषणात्मक तरीका चाहता हूं। उदाहरण के लिए, मैं इस तरह के वाक्य रचना चाहते हैं:
(define-splicing-syntax-class opts
#:attributes ([first-opts 1] [second-opts 1])
(pattern (~seq (~or (~group first-opts
(~optional (~seq #:a a))
(~optional (~seq #:b b)))
(~group second-opts
(~optional (~seq #:x x))
(~optional (~seq #:y y))))
...)))
या, और भी बेहतर है, यह अगर मैं मौजूदा पुरातन, कुछ इस तरह इस्तेमाल कर सकते हैं अच्छा होगा:
(define-splicing-syntax-class opts
#:attributes ([first-opts 1] [second-opts 1])
(pattern (~seq (~or (~and first-opts
(~seq (~optional (~seq #:a a))
(~optional (~seq #:b b))))
(~and second-opts
(~seq (~optional (~seq #:x x))
(~optional (~seq #:y y)))))
...)))
हालांकि, की न वो काम syntax/parse
द्वारा प्रदान किए गए बिल्टिन का उपयोग करके ऐसा करने का कोई तरीका है? यदि नहीं, तो क्या ~group
जैसे कुछ को परिभाषित करने का कोई आसान तरीका है?
यह मेरे लिए काम नहीं करता है क्योंकि मेरे पास उपयोग करने के लिए डिफ़ॉल्ट मान नहीं है- मुझे उन कीवर्ड तर्कों की आवश्यकता है जो विस्तार में नहीं दिखाए गए हैं * नहीं। –