2011-04-07 23 views
9

जैसे स्ट्रिंग का मूल्यांकन कैसे करें असल में मेरे पास "x + y" जैसे कुछ सूत्र हैं, जो String है। मैं x/y वैरिएबल को "1.2" जैसे विशिष्ट मानों के साथ बदलने में कामयाब रहा, जो अभी भी String प्रकार है। अब मेरे पास "1 + 2" जैसी अभिव्यक्ति है।हास्केल: "1 + 2"

तो समस्या यह है कि एक स्ट्रिंग प्रकार की अभिव्यक्ति का मूल्यांकन कैसे करें और परिणाम प्राप्त करें।

ps: मैं read की तरह sth चाहता हूं, जो सीधे ऑपरेटर (+/-, आदि) केस को संभालने के बजाय पूरी स्ट्रिंग अभिव्यक्ति को परिवर्तित कर सकता है। क्या यह संभव है?

+1

बेशक, यह संभव है। लेकिन मुझे लगता है कि आपको अभिव्यक्तियों के लिए बेहतर प्रतिनिधित्व का उपयोग करना चाहिए।एक सुराग आपका वाक्यांश हो सकता है "संपूर्ण स्ट्रिंग अभिव्यक्ति को परिवर्तित करें"। सवाल यह है कि ** ** ** में कनवर्ट करें? – Ingo

+0

मुझे लगता है कि yoz इसका मूल्यांकन करना चाहता है, और शब्द को 'परिणाम में कनवर्ट' के रूप में परिवर्तित कर रहा है। – mdm

+0

@ एमडीएम, निश्चित रूप से, यही कारण है कि मैं पूछ रहा हूं: उसे यह महसूस करने के लिए कि रूपांतरण और मूल्यांकन अलग-अलग चीजें हैं। या तो वह सीधे स्ट्रिंग का मूल्यांकन करता है (जिसे उसने पहले ही अस्वीकार कर दिया है), या वह परिवर्तित करता है (क्या? यह मुख्य प्रश्न है) और उसके बाद इसका मूल्यांकन करें। – Ingo

उत्तर

19

आपका प्रश्न व्याख्या के लिए बहुत सारे कमरे छोड़ देता है। मैं अनुमान लगा रहा हूं कि आप लेक्सिंग, पार्सिंग, शायद टाइपिंग, और मूल्यांकन की पूरी पाइपलाइन बनाने के आदी नहीं हैं। लंबे उत्तर में आपको यह परिभाषित करना होगा कि आप किस भाषा का मूल्यांकन करना चाहते हैं (बस '+' के साथ पूर्णांक, शायद '+', '-' '*', '/', या यहां तक ​​कि एक बड़ी भाषा के साथ सभी राशन?) और प्रत्येक को निष्पादित करें उस भाषा के लिए उपरोक्त चरणों में से।

संक्षिप्त उत्तर है: हास्केल भाव का मूल्यांकन करने, जो बुनियादी गणित ऑपरेटरों आप शायद के बारे में बात कर रहे हैं शामिल हैं, बस "संकेत" पैकेज का उपयोग करें:

$ cabal install hint 
... 
$ ghci 
> import Language.Haskell.Interpreter 
> runInterpreter $ setImports ["Prelude"] >> eval "3 + 5" 
Right "8" 

आहा!

+0

मैं लेक्सिकल विश्लेषण, व्याकरण परिभाषा इत्यादि के बिना स्ट्रिंग अभिव्यक्ति का मूल्यांकन करने का एक तरीका खोजने का प्रयास कर रहा था। सी # रनटाइम पर कोड संकलित करके इसे प्राप्त कर सकता है। तो वास्तव में मैं बस सोच रहा था कि हास्केल में एसएचएच समान है या नहीं। आपका जवाब बिल्कुल वही है जो मुझे चाहिए। बहुत धन्यवाद ~ – yoz

+0

@yoz Glad मैं मदद कर सकता था। जाहिर है आप [हैडॉक दस्तावेज़ स्वयं] पढ़ सकते हैं (http://hackage.haskell.org/packages/archive/hint/0.3.3.2/doc/html/Language-Haskell-Interpreter.html), लेकिन वास्तव में जल्दी से 'व्याख्या 'फ़ंक्शन आपको पॉलिमॉर्फिक प्रकार का परिणाम देगा (स्ट्रिंग प्रस्तुति नहीं), जो आपकी आवश्यकताओं के आधार पर भी बेहतर हो सकता है। हैप्पी हैकिंग। –

+0

मानक हास्केल के साथ ऐसा करने का कोई तरीका, बिना 'संकेत' इंस्टॉल किए? – vikingsteve

5

Real World Haskell के Parsec अनुभाग पढ़ने के लायक हो सकता है। आप इसे एक अभिव्यक्ति वृक्ष में पार्स कर सकते हैं और फिर मानों को प्रतिस्थापित कर सकते हैं। जैसा कि आप पारसेक का उपयोग करते हैं, आप प्रकारों का उपयोग करके अभिव्यक्ति वृक्ष का निर्माण करेंगे (बहुत मोटे तौर पर, मुझे यकीन है कि मैंने कुछ गलतियां की हैं जिन्हें मैं ठीक करता हूं जैसे ही लोग उन्हें इंगित करते हैं!) नीचे की तरह।

data Op = Plus | Minus 
data Term = Variable String 
      | Value Int 
data Expression = Expr Expression Op Expression 
       | Term 

फिर 1 + 2 (Expr (Variable "x") Plus (Variable "y")) हो सकता है और आप उपयुक्त प्रतिस्थापन लागू हो सकते हैं।

परिणाम प्राप्त करने के लिए, मुझे लगता है कि आप सही काम कर सकते हैं evaluate :: Map String Int -> Expression -> Either ErrorMessage Int जो मानचित्र में बाइंडिंग लागू करेगा और फिर यदि संभव हो तो परिणाम की गणना करेगा।

+1

मुझे लगता है कि @yoz ने एक इनबिल्ट फ़ंक्शन 'eval :: स्ट्रिंग -> डबल' की कुछ और अपेक्षा की थी। ए * थोड़ा * अधिक हैकेलिश शायद 'eval :: स्ट्रिंग -> या तो त्रुटि संदेश डबल' होगा। हालांकि, जैसा कि अधिकांश ने इंगित किया है: तारों के रूप में प्रतिनिधित्व अभिव्यक्ति खराब है। जेफ ने दिखाए गए सिंटैक्स पेड़ का बेहतर उपयोग करें। – Tarrasch

2

वैसे मैं hint के खिलाफ अपने सिर को टक्कर लगी हूं लेकिन अब मैं हार मानता हूं। मुझे पता है संकेत यह कर सकता है लेकिन मुझे यकीन नहीं है कि कैसे। [संपादित करें] संकेत के लिए आयात सेट करने के लिए टॉमएमडी का जवाब देखें। [/ संपादित करें]

import Language.Haskell.Interpreter (eval, runInterpreter, Interpreter, InterpreterError) 

main = do let resIO = eval "3" :: Interpreter String 
      res <- runInterpreter resIO 
      print res 

यह uninterestingly परिणाम के रूप में Right "3" पैदा करता है। मैं निम्नलिखित वेरिएंट की कोशिश की, चौंकाने त्रुटियों में केवल चलाने के लिए:

... eval "3 + 3" .... 
-- yields -- 
Left (WontCompile [GhcError (errMsg = "Not in scope: `+'"]) 

+ ऑपरेटर दायरे में नहीं है ??? wtf ...

import Language.Haskell.Interpreter (interpret, as, runInterpreter, Interpreter) 

main = do let resIO = interpret "3" (as :: Int) :: Interpreter Int 
      res <- runInterpreter resIO 
      print res 
-- yields -- 
Left (WontCompile [GhcError (errMsg = "Not in scope: type constructor or class 'Int'")]) 

Int कक्षा दायरे में नहीं है ??? उह ...

मैं उन संकेतों के बारे में अधिक जानकारी देता हूं जो संकेत के बेहतर विवरण पर विस्तार से हैं।

+4

आपको मेरा सेट देखने के लिए 'सेट आयात' करने की आवश्यकता है। –

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