2008-11-02 10 views
6

मैं कर रहा हूँ रेती Horstmann के Combinator पार्सर व्यायाम, मैं सबसे अच्छा तरीका तार कि संख्या और तार कि एक मैच बयान में चर का प्रतिनिधित्व प्रतिनिधित्व के बीच अंतर करने के बारे में चिंता:स्काला Combinator पारसर्स - नंबर तार और चर तार के बीच अंतर

def factor: Parser[ExprTree] = (wholeNumber | "(" ~ expr ~ ")" | ident) ^^ { 
    case a: wholeNumber => Number(a.toInt) 
    case a: String => Variable(a) 
} 

दूसरी पंक्ति, "केस ए: पूर्ण नम्बर" कानूनी नहीं है। मैंने एक regexp के बारे में सोचा, लेकिन इसे "मामले" के साथ काम करने के लिए एक रास्ता नहीं मिला है।

उत्तर

6

मैं इसे थोड़ा सा विभाजित कर दूंगा और केस विश्लेषण को | में दबा दूंगा।

def factor: Parser[ExprTree] = (wholeNumber ^^ { Number(_.toInt) } 
           | "(" ~> expr <~ ")" 
           | ident ^^ { Variable(_) }) 

मैं माफी माँगता हूँ अगर आप अंडरस्कोर वाक्य रचना से परिचित नहीं हैं: यह सामान्य रूप में combinators और वास्तव में डालूँगा (*) पार्स के लाभों में से एक है। असल में इसका मतलब है "संलग्न कार्य मूल्य के लिए n वें पैरामीटर को प्रतिस्थापित करें"। इस प्रकार { Variable(_) }{ x => Variable(x) } के बराबर है।

~> और <~ ऑपरेटर ~ के स्थान पर ऑपरेटर का एक और बिट है। इन ऑपरेटरों का मतलब है कि उस अवधि के विश्लेषण में माता-पिता दोनों के वाक्यविन्यास शामिल होना चाहिए, लेकिन परिणाम expr के परिणाम से पूरी तरह से निर्धारित किया जाना चाहिए। इस प्रकार, "(" ~> expr <~ ")""(" ~ expr ~ ")" के समान ही मेल खाता है, लेकिन expr से आंतरिक परिणाम मान को पुनर्प्राप्त करने के लिए अतिरिक्त केस विश्लेषण की आवश्यकता नहीं है।

+0

उत्कृष्ट! {X (स्ट्रिंग => संख्या (x)} में {संख्या (_। ToInt)} को बदलना पड़ा क्योंकि मुझे "त्रुटि: विस्तारित फ़ंक्शन के लिए अनुपलब्ध पैरामीटर प्रकार" मिला, फिर यह एक आकर्षण की तरह काम करता था। फिर भी उत्सुक है अगर इसे हल करने का केस क्लास तरीका है। –

+0

अच्छा, वास्तव में मामला सिर्फ आंशिक कार्य को परिभाषित करता है। यह आपको इनपुट पर पैटर्न मिलान करने देता है, जो वास्तव में उपयोगी है। मैं इसके बजाय आंशिक कार्यों (मामले) का उपयोग करके आसानी से अपना जवाब लिख सकता था, यह सिर्फ जरूरी नहीं था। :-) (यह ~> और <~) –

+0

को छोड़कर किया गया होगा यदि आपका मतलब पूरे शब्द पर मिलान करना है, तो मुझे लगता है कि जवाब "नहीं है, ऐसा करने का कोई तरीका नहीं है"। जब तक 'wholeNumber' विधि स्ट्रिंग की तुलना में एक अलग घटक प्रकार के साथ एक पार्सर लौटाती है, तो' पहचान 'या यहां तक ​​कि "(" ~> expr <~ ") से अलग करने का कोई तरीका नहीं है। –

संबंधित मुद्दे