2012-04-02 15 views
14

क्या आप मुझे कुछ विचार दे सकते हैं कि मैं सी में सरल गणितीय अभिव्यक्ति पार्सर कैसे बना सकता हूं?स्ट्रिंग से गणितीय फ़ंक्शन का मूल्यांकन

उपयोगकर्ता एक स्ट्रिंग में गणितीय फ़ंक्शन में प्रवेश करता है और स्ट्रिंग से मैं सी उदाहरण में फ़ंक्शन बनाना चाहता हूं। x + sin(2*x)

->return x + sin(2x);

अग्रिम धन्यवाद।

+0

बाइसन दस्तावेज़ीकरण पर एक नज़र डालें, [उदाहरण] (http://www.gnu.org/software/bison/manual/html_node/Infix-Calc.html#Infix-Calc) जो आपको मार्गदर्शन करेंगे। –

+0

http://stackoverflow.com/questions/1151127/evaluating-mathematical-expressions के संभावित डुप्लिकेट, [तेज़ सी या उद्देश्य-सी गणित पार्सर क्या है?] (Http://stackoverflow.com/questions/4892152/what -इस-ए-फास्ट-सी-या-उद्देश्य-सी-गणित-पार्सर), http://stackoverflow.com/questions/5115872/what-is-the-best-way-to-evaluate-mathematical-expression- इन-सी/5117028 # 5117028, http://stackoverflow.com/questions/4071456/opensouce-cc-math-expression-parser-library/4071701#4071701, और कई अन्य। – lhf

+0

कोशिश करें [TinyExpr] (https://github.com/codeplea/tinyexpr)। यह एक सी स्रोत कोड फ़ाइल और शीर्षलेख में है। – 131

उत्तर

6

आप अभिव्यक्ति आधारित "शंटिंग-यार्ड एल्गोरिदम" http://en.wikipedia.org/wiki/Shunting-yard_algorithm पर पार्स कर सकते हैं। आपको पाप, कॉस इत्यादि जैसे फ़ंक्शन कॉल को संभालने के लिए विस्तार करना होगा ...

+0

+1 है। पार्सिंग कार्यों के लिए यह सही दृष्टिकोण (एल्गोरिदमिक सादगी, स्टैक ओवरफ्लो का कोई जोखिम नहीं है) इसे संभाल सकता है। –

1

ऐसा करने का एक तरीका अभिव्यक्तियों के लिए रिवर्स पॉलिश नोटेशन और ऑपरेटरों के लिए एक ढेर का उपयोग करना है। कुछ त्वरित छद्म कोड: अभिव्यक्ति के अंत तक

if element is operand 
    push in stack 
else if element is operation 
    pop last 2 elements 
    perform operation 
    push result in stack 

दोहराएँ। अंतिम परिणाम स्टैक में एकमात्र तत्व है।

3

यह बिल्कुल आसान नहीं है, चेहरे में, यह एक कठिन बात है। आपको एक पूर्ण व्याकरण पार्सर की आवश्यकता है, जो पूर्व परिभाषित स्थिरांक/कार्यों (sin, log, pi, आदि) के साथ संयुक्त है।

यदि आपके पास सीआई के साथ कोई व्यापक पिछला अनुभव नहीं है, तो यह करने से इनकार कर दिया जाएगा, लेकिन यदि आप वास्तव में यह देखना चाहते हैं तो recursive descent parsing पर यह करने का सबसे आसान तरीका है (उपयोगकर्ता पर बोझ डाले बिना, रिवर्स पॉलिश अंकन)।

अंतिम लेकिन कम से कम आप कम से कम नहीं कहते हैं कि आप उपयोगकर्ता द्वारा जेनरेट किए गए इनपुट से सी फ़ंक्शन बनाना चाहते हैं। यह लगभग हमेशा गलत काम है - उपयोगकर्ता इनपुट से कोड उत्पन्न करना, इसके बजाय सबसे आसान तरीका एक मध्यवर्ती प्रतिनिधित्व बनाने के लिए पूर्व-प्रसंस्करण है जिसे कुशलतापूर्वक निष्पादित किया जा सकता है।

+0

मैं उस पर ढेर करता हूं कि आपको शायद [बीएनएफ (बैकस-नौर फॉर्म) का अध्ययन करना चाहिए [http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form) सत्तारूढ़ – Eregrith

+0

मैं दूसरा हूं कि यह एक नहीं है करने के लिए सरल बात है। यह भयानक नहीं है, वास्तव में यह काफी सुरुचिपूर्ण है, लेकिन यह किसी भी तरह से सरल नहीं है। रिकर्सिव सभ्य सरल तरीका है, ऑपरेटर प्राथमिकता अधिक परिष्कृत है लेकिन शर्टिंग यार्ड के लिए काफी जटिल –

0

एक अभिव्यक्ति पार्सर और मूल्यांकनकर्ता लिखना सामान्य उदाहरणों में से एक है जब चर्चा पार्सर लेखन तकनीकें होती हैं। उदाहरण के लिए आप फ्लेक्स/बाइसन या लेक्स/yacc के लिए प्रलेखन देख सकते हैं। इसमें पार्सर्स/अभिव्यक्ति मूल्यांकनकर्ताओं के निर्माण के उदाहरण होंगे।

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