2008-09-22 12 views
52

गणित पार्सर को डिजाइन करने का सबसे बढ़िया तरीका क्या है? मेरा मतलब है कि एक ऐसा फ़ंक्शन है जो गणित स्ट्रिंग लेता है (जैसे: "2 + 3/2 + (2 * 5)") और गणना मूल्य लौटाता है? मैंने वीबी 6 साल पहले एक लिखा था, लेकिन यह फूला हुआ और बहुत पोर्टेबल नहीं था (या उस मामले के लिए स्मार्ट ...)। सामान्य विचार, psuedo कोड या असली कोड की सराहना की है।गणित पार्सर का स्मार्ट डिज़ाइन?

+0

आप यहां शंटिंग यार्ड एल्गोरिदम के जावा कार्यान्वयन की जांच कर सकते हैं: http://projects.congrace.de/exp4j/ – fasseg

+0

मैंने जो कोड पोस्ट किया है उसे देखें https://stackoverflow.com/questions/28256/equation- अभिव्यक्ति-पारसर-साथ-प्राथमिकता/46722767 # 46722767 – user4617883

+0

मैंने जो कोड पोस्ट किया है उसे देखें https://stackoverflow.com/questions/28256/equation-expression-parser-with-precedence/46722767#46722767 – user4617883

उत्तर

76

एक सुंदर अच्छे दृष्टिकोण में दो कदम शामिल होंगे। पहले चरण में converting the expression from infix to postfix (उदा। Dijkstra's shunting yard के माध्यम से) नोटेशन शामिल है। एक बार ऐसा करने के बाद, postfix evaluator लिखना बहुत मुश्किल है।

+0

मुझे नहीं लगता शंटिंग यार्ड एल्गोरिदम एक्सपोनेंट्स के आधार पर बाध्यकारी सही यूनरी माइनस को संभाल सकता है। यानी यह -2^3 के रूप में विश्लेषण नहीं कर सकता - (2^3), केवल (-2)^3 के रूप में। हालांकि मैं गलत हो सकता हूं, मुझे यकीन नहीं है। – chbaker0

+0

@mebob यह मुझे उपयोगकर्ता इनपुट त्रुटि की तरह दिखता है। मैं इसे सही करने के लिए परेशान नहीं होगा। अगर मैं अच्छा महसूस कर रहा था तो मैं इसे देखने के लिए कुछ जोड़ सकता हूं और उपयोगकर्ता को सतर्क कर सकता हूं कि वे गलत हो सकते हैं। – Yay295

5

आपके पास कुछ दृष्टिकोण हैं। आप अधिक कोड लिखने के बिना उत्तर प्राप्त करने के लिए गतिशील कोड उत्पन्न कर सकते हैं और इसे निष्पादित कर सकते हैं। बस .NET में रनटाइम जेनरेट कोड पर एक खोज करें और आसपास के कई उदाहरण हैं।

वैकल्पिक रूप से आप एक वास्तविक पार्सर बना सकते हैं और थोड़ा पार्स पेड़ उत्पन्न कर सकते हैं जिसका उपयोग अभिव्यक्ति का मूल्यांकन करने के लिए किया जाता है। फिर मूलभूत अभिव्यक्तियों के लिए यह बहुत आसान है। कोडप्लेक्स देखें क्योंकि मुझे लगता है कि उनके पास गणित पार्सर है। या बस बीएनएफ देखें जिसमें उदाहरण शामिल होंगे। कंपाइलर अवधारणाओं को पेश करने वाली कोई भी वेबसाइट इसे मूल उदाहरण के रूप में शामिल करेगी।

Codeplex Expression Evaluator

1

स्ट्रिंग स्वरूप में कोई इन्फ़िक्स अभिव्यक्ति अपने इनपुट मान लिया जाये कि है, आप इसे postfix को परिवर्तित कर सकते हैं और, ढेर की एक जोड़ी का उपयोग कर: एक ऑपरेटर ढेर और एक संकार्य ढेर, वहाँ से समाधान काम करते हैं। आप विकिपीडिया लिंक पर सामान्य एल्गोरिदम जानकारी पा सकते हैं।

4

यदि आपके पास "हमेशा चालू" एप्लिकेशन है, तो बस गणित स्ट्रिंग को Google पर पोस्ट करें और परिणाम को पार्स करें। सरल तरीका लेकिन यह सुनिश्चित नहीं है कि आपको यही चाहिए - लेकिन मुझे लगता है कि किसी भी तरह से स्मार्ट।

+2

नहीं, वास्तव में स्मार्ट नहीं। लेकिन "चीजें हो जाती हैं"। –

+2

मेरा यही मतलब है, आप समझने के लिए पर्याप्त समझदार हैं कि चीजें कैसे प्राप्त करें ;-) – JRoppert

3

संबंधित प्रश्न Equation (expression) parser with precedence? इस बारे में कुछ अच्छी जानकारी भी है कि इसके साथ कैसे शुरुआत करें।

-Adam

12

मैं एक गणित पार्सर को डिजाइन करने के बारे में कुछ ब्लॉग पोस्ट में लिखा था। एक सामान्य introduction है, grammars, sample implementation written in Ruby और test suite के बारे में मूल ज्ञान है। शायद आप इन सामग्रियों को उपयोगी पाएंगे।

1

एएनटीएलआर एक बहुत अच्छा एलएल (*) पार्सर जनरेटर है। मैं इसे अत्यधिक अनुशंसा करता हूं।

3

मुझे पता है कि यह पुराना है, लेकिन मैं एक बड़े ऐप के हिस्से के रूप में कैलकुलेटर विकसित करने की कोशिश कर रहा हूं और स्वीकार किए गए उत्तर का उपयोग करके कुछ मुद्दों पर भाग गया। लिंक इस समस्या को समझने और हल करने में तत्काल सहायक थे और उन्हें छूट नहीं दी जानी चाहिए। मैं जावा में एक एंड्रॉइड ऐप लिख रहा था और "स्ट्रिंग" अभिव्यक्ति में प्रत्येक आइटम के लिए, मैंने वास्तव में एक ऐरेलिस्ट में स्ट्रिंग को उपयोगकर्ता के प्रकार के रूप में कुंजीपैड पर संग्रहीत किया था। इन्फिक्स-टू-पोस्टफिक्स रूपांतरण के लिए, मैंने ऐरेलिस्ट में प्रत्येक स्ट्रिंग के माध्यम से पुनरावृत्त किया, फिर स्ट्रिंग्स के नए व्यवस्थित पोस्टफिक्स अर्रेलिस्ट का मूल्यांकन किया। यह ऑपरेटरों/ऑपरेटरों की एक छोटी संख्या के लिए शानदार था, लेकिन लंबी गणना लगातार बंद थी, विशेष रूप से अभिव्यक्तियों ने गैर-पूर्णांक का मूल्यांकन करना शुरू किया। Infix to Postfix conversion के लिए दिए गए लिंक में, यह स्कैन पॉपिंग करने का सुझाव देता है यदि स्कैन किए गए आइटम ऑपरेटर हैं और टॉपस्टैक आइटम की उच्च प्राथमिकता है। मैंने पाया कि यह लगभग सही है। टॉपस्टैक आइटम को रोकना यदि इसकी प्राथमिकता अधिक है या स्कैन किए गए ऑपरेटर के बराबर अंततः मेरी गणना सही हो गई है। उम्मीद है कि यह इस समस्या पर काम करने वाले किसी भी व्यक्ति की मदद करेगा, और कुछ अमूल्य लिंक प्रदान करने के लिए जस्टिन पोली (और फास?) के लिए धन्यवाद।

1

डेवलपर्स हमेशा एक साफ दृष्टिकोण चाहते हैं, और जमीन से ऊपर पार्सिंग तर्क को लागू करने का प्रयास करें, आमतौर पर Dijkstra Shunting-Yard Algorithm के साथ समाप्त होता है। नतीजा साफ दिखने वाला कोड है, लेकिन संभवतः बग के साथ सवार हो गया है। मैंने ऐसा एपीआई विकसित किया है, JMEP, यह सब कुछ करता है, लेकिन मुझे स्थिर कोड रखने में वर्षों लगे।

यहां तक ​​कि सभी कामों के साथ, आप उस परियोजना पृष्ठ से भी देख सकते हैं कि मैं जावासीसी या एएनटीएलआर का उपयोग करने के लिए स्विच करने पर गंभीरता से विचार कर रहा हूं, यहां तक ​​कि पहले से किए गए सभी कामों के बाद भी।