सबसे पहले, एक वर्ग CExpression, जो मॉडल अपने अभिव्यक्ति की संरचना तैयार करते हैं।
CRule
लागू करें, जिसमें एक पैटर्न और प्रतिस्थापन शामिल है। पैटर्न चर के रूप में विशेष प्रतीकों का प्रयोग करें, जो पैटर्न मिलान के दौरान बाध्य होने और प्रतिस्थापन अभिव्यक्ति में प्रतिस्थापित करने की आवश्यकता है।
फिर, CRule
कक्षा को लागू करें। यह मुख्य विधि applyRule(CExpression, CRule)
अभिव्यक्ति के किसी भी लागू उप-अभिव्यक्ति के खिलाफ नियम से मिलान करने का प्रयास करती है। यदि यह मेल खाता है, तो परिणाम वापस कर दें।
फिनली, कक्षा CRuleSet
को लागू करें, जो कि केवल CRule ऑब्जेक्ट्स का एक सेट है।मुख्य विधि reduce(CExpression)
तब तक नियमों का सेट लागू करती है जब तक कोई नियम लागू नहीं किया जा सकता है और फिर कम अभिव्यक्ति देता है।
इसके अतिरिक्त, आपको कक्षा CBindingEnvironment
की आवश्यकता है, जो पहले से मिलान किए गए मानों के लिए मिलान किए गए प्रतीकों से मेल खाते हैं।
कोशिश एक सामान्य रूप
मत भूलना के लिए अभिव्यक्ति के पुनर्लेखन के लिए, कि इस दृष्टिकोण एक निश्चित बिंदु तक काम करता है, लेकिन गैर पूरा होने की संभावना है। यह इस तथ्य के कारण है कि निम्नलिखित सभी नियम स्थानीय शब्द पुनर्लेखन करते हैं।
इस स्थानीय पुनर्लेख तर्क को मजबूत बनाने के लिए, किसी को अभिव्यक्ति को किसी सामान्य रूप में बदलने की कोशिश करनी चाहिए। यह मेरा दृष्टिकोण है:
यदि किसी शब्द में शाब्दिक मूल्य होते हैं, तो यथासंभव यथासंभव अवधि को स्थानांतरित करने का प्रयास करें।
आखिरकार, यह शाब्दिक मूल्य सही दिखाई दे सकता है और पूरी तरह से शाब्दिक अभिव्यक्ति के हिस्से के रूप में मूल्यांकन किया जा सकता है।
जब पूरी तरह से शाब्दिक अभिव्यक्ति का मूल्यांकन करने के
एक दिलचस्प सवाल है जब पूरी तरह से शाब्दिक अभिव्यक्ति का मूल्यांकन करने के। मान लीजिए आप एक अभिव्यक्ति
x * (1/3)
जो करने के लिए
x * 0.333333333333333333
अब मान लीजिए कि एक्स को कम करेगा 3. द्वारा बदल दिया जाता है इस तरह
0.999999999999999999999999
इस प्रकार उत्सुक मूल्यांकन कुछ लाभ होगा एक से थोड़ा गलत रिटर्न है मूल्य।
दूसरे पक्ष पर , अगर आप (1/3) और पहले से 3
3 * (1/3)
एक्स की जगह रीराइट नियम
1
इस प्रकार देना होगा, यह मूल्यांकन करने के लिए उपयोगी हो सकता है रखने के देर से पूरी तरह से शाब्दिक अभिव्यक्ति।
पुनर्लेखन नियमों के उदाहरण
यहाँ कैसे मेरे नियमों अनुप्रयोग के भीतर दिखाई देते हैं:
addRule(new TARuleFromString('0+_1', // left hand side :: pattern
'_1' // right hand side :: replacement
)
);
या थोड़ा और अधिक जटिल
: _1, _2, ... प्रतीकों किसी भी उपसूचक से मेल खाते हैं addRule(new TARuleFromString('_1+_2*_1',
'(1+_2)*_1'
)
);
कुछ विशेष प्रतीकों केवल विशेष उप-अभिव्यक्तियों से मेल खाते हैं। जैसे _ लिटरल 1, _ लिटरल 2, ...केवल शाब्दिक मान से मेल:
addRule(new TARuleFromString('exp(_Literal1) * exp(_Literal2)',
'exp(_Literal1 + _Literal2)'
)
);
यह नियम बाईं ओर गैर शाब्दिक अभिव्यक्ति ले जाता है:
addRule(new TARuleFromString('_Literal*_NonLiteral',
'_NonLiteral*_Literal'
)
);
किसी भी नाम है तो उस के साथ एक '_', एक पैटर्न चर रहा है शुरू होता है। जबकि सिस्टम एक नियम से मेल खाता है, यह पहले से मिलान किए गए प्रतीकों के असाइनमेंट का ढेर रखता है।
अंत में, यह न भूलें कि नियम गैर-समाप्ति प्रतिस्थापन अनुक्रम उत्पन्न कर सकते हैं। इस प्रकार अभिव्यक्ति को कम करते समय, प्रक्रिया को याद रखें, जो मध्यवर्ती अभिव्यक्ति पहले ही पहुंच चुकी है।
मेरे कार्यान्वयन में, मैं सीधे मध्यवर्ती अभिव्यक्तियों को सहेजता नहीं हूं। मैं मध्यवर्ती अभिव्यक्ति के MD5() हैश की एक सरणी रखता हूं।
addRule(new TARuleFromString('0+_1', '_1'));
addRule(new TARuleFromString('_Literal2=0-_1', '_1=0-_Literal2'));
addRule(new TARuleFromString('_1+0', '_1'));
addRule(new TARuleFromString('1*_1', '_1'));
addRule(new TARuleFromString('_1*1', '_1'));
addRule(new TARuleFromString('_1+_1', '2*_1'));
addRule(new TARuleFromString('_1-_1', '0'));
addRule(new TARuleFromString('_1/_1', '1'));
// Rate = (pow((EndValue/BeginValue), (1/(EndYear - BeginYear)))-1) * 100
addRule(new TARuleFromString('exp(_Literal1) * exp(_Literal2)', 'exp(_Literal1 + _Literal2)'));
addRule(new TARuleFromString('exp(0)', '1'));
addRule(new TARuleFromString('pow(_Literal1,_1) * pow(_Literal2,_1)', 'pow(_Literal1 * _Literal2,_1)'));
addRule(new TARuleFromString('pow(_1, 0)', '1'));
addRule(new TARuleFromString('pow(_1, 1)', '_1'));
addRule(new TARuleFromString('pow(_1, -1)', '1/_1'));
addRule(new TARuleFromString('pow(pow(_1, _Literal1), _Literal2)', 'pow(_1, _Literal1 * _Literal2)'));
// addRule(new TARuleFromString('pow(_Literal1, _1)', 'ln(_1)/ln(_Literal1)'));
addRule(new TARuleFromString('_literal1 = pow(_Literal2, _1)', '_1 = ln(_literal1)/ln(_Literal2)'));
addRule(new TARuleFromString('pow(_Literal2, _1) = _literal1 ', '_1 = ln(_literal1)/ln(_Literal2)'));
addRule(new TARuleFromString('pow(_1, _Literal2) = _literal1 ', 'pow(_literal1, 1/_Literal2) = _1'));
addRule(new TARuleFromString('pow(1, _1)', '1'));
addRule(new TARuleFromString('_1 * _1 = _literal', '_1 = sqrt(_literal)'));
addRule(new TARuleFromString('sqrt(_literal * _1)', 'sqrt(_literal) * sqrt(_1)'));
addRule(new TARuleFromString('ln(_Literal1 * _2)', 'ln(_Literal1) + ln(_2)'));
addRule(new TARuleFromString('ln(_1 * _Literal2)', 'ln(_Literal2) + ln(_1)'));
addRule(new TARuleFromString('log2(_Literal1 * _2)', 'log2(_Literal1) + log2(_2)'));
addRule(new TARuleFromString('log2(_1 * _Literal2)', 'log2(_Literal2) + log2(_1)'));
addRule(new TARuleFromString('log10(_Literal1 * _2)', 'log10(_Literal1) + log10(_2)'));
addRule(new TARuleFromString('log10(_1 * _Literal2)', 'log10(_Literal2) + log10(_1)'));
addRule(new TARuleFromString('ln(_Literal1/_2)', 'ln(_Literal1) - ln(_2)'));
addRule(new TARuleFromString('ln(_1/_Literal2)', 'ln(_Literal2) - ln(_1)'));
addRule(new TARuleFromString('log2(_Literal1/_2)', 'log2(_Literal1) - log2(_2)'));
addRule(new TARuleFromString('log2(_1/_Literal2)', 'log2(_Literal2) - log2(_1)'));
addRule(new TARuleFromString('log10(_Literal1/_2)', 'log10(_Literal1) - log10(_2)'));
addRule(new TARuleFromString('log10(_1/_Literal2)', 'log10(_Literal2) - log10(_1)'));
addRule(new TARuleFromString('_Literal1 = _NonLiteral + _Literal2', '_Literal1 - _Literal2 = _NonLiteral'));
addRule(new TARuleFromString('_Literal1 = _NonLiteral * _Literal2', '_Literal1/_Literal2 = _NonLiteral'));
addRule(new TARuleFromString('_Literal1 = _NonLiteral/_Literal2', '_Literal1 * _Literal2 = _NonLiteral'));
addRule(new TARuleFromString('_Literal1 =_NonLiteral - _Literal2', '_Literal1 + _Literal2 = _NonLiteral'));
addRule(new TARuleFromString('_NonLiteral + _Literal2 = _Literal1 ', '_Literal1 - _Literal2 = _NonLiteral'));
addRule(new TARuleFromString('_NonLiteral * _Literal2 = _Literal1 ', '_Literal1/_Literal2 = _NonLiteral'));
addRule(new TARuleFromString('_NonLiteral/_Literal2 = _Literal1 ', '_Literal1 * _Literal2 = _NonLiteral'));
addRule(new TARuleFromString('_NonLiteral - _Literal2 = _Literal1', '_Literal1 + _Literal2 = _NonLiteral'));
addRule(new TARuleFromString('_NonLiteral - _Literal2 = _Literal1 ', '_Literal1 + _Literal2 = _NonLiteral'));
addRule(new TARuleFromString('_Literal2 - _NonLiteral = _Literal1 ', '_Literal2 - _Literal1 = _NonLiteral'));
addRule(new TARuleFromString('_Literal1 = sin(_NonLiteral)', 'asin(_Literal1) = _NonLiteral'));
addRule(new TARuleFromString('_Literal1 = cos(_NonLiteral)', 'acos(_Literal1) = _NonLiteral'));
addRule(new TARuleFromString('_Literal1 = tan(_NonLiteral)', 'atan(_Literal1) = _NonLiteral'));
addRule(new TARuleFromString('_Literal1 = ln(_1)', 'exp(_Literal1) = _1'));
addRule(new TARuleFromString('ln(_1) = _Literal1', 'exp(_Literal1) = _1'));
addRule(new TARuleFromString('_Literal1 = _NonLiteral', '_NonLiteral = _Literal1'));
addRule(new TARuleFromString('(_Literal1/_2) = _Literal2', '_Literal1/_Literal2 = _2 '));
addRule(new TARuleFromString('_Literal*_NonLiteral', '_NonLiteral*_Literal'));
addRule(new TARuleFromString('_Literal+_NonLiteral', '_NonLiteral+_Literal'));
addRule(new TARuleFromString('_Literal1+(_Literal2+_NonLiteral)', '_NonLiteral+(_Literal1+_Literal2)'));
addRule(new TARuleFromString('_Literal1+(_Literal2+_1)', '_1+(_Literal1+_Literal2)'));
addRule(new TARuleFromString('(_1*_2)+(_3*_2)', '(_1+_3)*_2'));
addRule(new TARuleFromString('(_2*_1)+(_2*_3)', '(_1+_3)*_2'));
addRule(new TARuleFromString('(_2*_1)+(_3*_2)', '(_1+_3)*_2'));
addRule(new TARuleFromString('(_1*_2)+(_2*_3)', '(_1+_3)*_2'));
addRule(new TARuleFromString('(_Literal * _1)/_Literal', '_1'));
addRule(new TARuleFromString('(_Literal1 * _1)/_Literal2', '(_Literal1 * _Literal2)/_1'));
addRule(new TARuleFromString('(_1+_2)+_3', '_1+(_2+_3)'));
addRule(new TARuleFromString('(_1*_2)*_3', '_1*(_2*_3)'));
addRule(new TARuleFromString('_1+(_1+_2)', '(2*_1)+_2'));
addRule(new TARuleFromString('_1+_2*_1', '(1+_2)*_1'));
addRule(new TARuleFromString('_literal1 * _NonLiteral = _literal2', '_literal2/_literal1 = _NonLiteral'));
addRule(new TARuleFromString('_literal1 + _NonLiteral = _literal2', '_literal2 - _literal1 = _NonLiteral'));
addRule(new TARuleFromString('_literal1 - _NonLiteral = _literal2', '_literal1 - _literal2 = _NonLiteral'));
addRule(new TARuleFromString('_literal1/_NonLiteral = _literal2', '_literal1 * _literal2 = _NonLiteral'));
बनाओ नियमों प्रथम श्रेणी के भाव
एक दिलचस्प बिंदु:
एक प्रारंभिक बिंदु
यहाँ के रूप में नियमों का एक सेट नियमों का एक सेट आरंभ करने के लिए है: चूंकि उपरोक्त नियम विशेष अभिव्यक्ति हैं, जो अभिव्यक्ति पार्सर द्वारा सही ढंग से मूल्यांकन करते हैं, उपयोगकर्ता भी नए नियम जोड़ सकते हैं और इस प्रकार एप्लिकेशन की पुनर्लेख को बढ़ा सकते हैं क्षमताओं।
पार्सिंग भाव (या अधिक सामान्य: भाषा)
कोको/ObjC अनुप्रयोगों के लिए, Dave DeLong's DDMathParser एक आदर्श उम्मीदवार वाक्य रचना गणितीय अभिव्यक्ति का विश्लेषण करने के लिए है।
अन्य भाषाओं के लिए, हमारे पुराने दोस्त Lex & Yacc या नए GNU Bison मदद की जा सकती है।
बहुत छोटा और enourmous set of ready to use syntax-files, ANTLR जावा पर आधारित एक आधुनिक पार्सर जनरेटर है। पूरी तरह से कमांड लाइन उपयोग के अलावा, ANTLRWorks एएनटीएलआर आधारित पार्सर्स बनाने और डिबग करने के लिए GUI फ्रंटएंड प्रदान करता है। एएनटीएलआर various host language, जैसे JAVA, C, Python, PHP or C# के लिए व्याकरण उत्पन्न करता है। एक्शनस्क्रिप्ट रनटाइम वर्तमान में broken है।
मामले में आप जानने के लिए नीचे-ऊपर से भाव (या सामान्य तौर पर भाषाओं) पार्स करने के लिए कैसे करना चाहते हैं, मैं इस free book's text from Niklaus Wirth (या german book edition), पास्कल और Modula- के प्रसिद्ध आविष्कारक का प्रस्ताव करता हूँ 2।
और 'sqrt (पाउ (-3, 2)) के बारे में क्या? – Howard
@ हावर्ड जो '3' का मूल्यांकन करता है, और यह एक उदाहरण है कि मैं अभी तक एक अच्छा उत्तर क्यों नहीं सोच पा रहा हूं (इसे प्रतिबिंबित करने के लिए संपादित प्रश्न)। :) –
मेरा जवाब भी देखें। आपको बहुत सारे नियमों को परिभाषित करना होगा जो परिवर्तन की अनुमति है और जो नहीं हैं। – Howard