2010-08-27 4 views
13

में सुरक्षित अभिव्यक्ति पार्सर मैं उपयोगकर्ताओं को गणितीय अभिव्यक्तियों को सुरक्षित तरीके से निष्पादित करने की अनुमति कैसे दे सकता हूं? क्या मुझे एक पूर्ण पार्सर लिखने की ज़रूरत है?पायथन

क्या ast.literal_eval() जैसा कुछ है, लेकिन अभिव्यक्तियों के लिए?

उत्तर

10

Pyparsing examples page सूचियों कई अभिव्यक्ति पारसर्स:

http://pyparsing.wikispaces.com/file/view/fourFn.py - एक पारंपरिक गणित इन्फ़िक्स संकेतन पार्सर/मूल्यांकनकर्ता कार्यान्वयन pyparsing का उपयोग कर

(जैसा कि इसके नाम के बावजूद, यह वास्तव में 5-समारोह गणित, प्लस कई ट्रिग कार्य करता है) http://pyparsing.wikispaces.com/file/view/simpleBool.py - बूलियन इन्फ़िक्स संकेतन पार्सर/मूल्यांकनकर्ता, एक pyparsing सहायक विधि operatorPrecedence, जो इन्फ़िक्स ऑपरेटर अंकन की परिभाषा को सरल का उपयोग कर

http://pyparsing.wikispaces.com/file/view/simpleArith.pyhttp://pyparsing.wikispaces.com/file/view/eval_arith.py - operatorPrecedence का उपयोग करके चारFn.py को पुन: प्रस्तुत करने वाले उदाहरणों की एक जोड़ी। पहला बस पार्स और एक पार्स पेड़ देता है, दूसरा मूल्यांकन तर्क जोड़ता है।

+0

पाइपर्सिंग वास्तव में अच्छा है, हालांकि पहली नज़र में थोड़ा डरावना – dmitry

0

हां। यहां तक ​​कि यदि अभिव्यक्तियों के लिए ast.literal_eval() के बराबर थे, तो एक पाइथन अभिव्यक्ति केवल शुद्ध गणितीय अभिव्यक्ति के अलावा कई चीजें हो सकती है, उदाहरण के लिए एक मनमानी फ़ंक्शन कॉल।

यह मुझे आश्चर्य नहीं करेगा अगर कुछ खुले स्रोत मॉड्यूल में पहले से ही एक अच्छा गणितीय अभिव्यक्ति पार्सर/मूल्यांकनकर्ता उपलब्ध है, लेकिन यदि नहीं, तो अपने आप में से एक लिखना बहुत आसान है।

0

गणित कार्यों में संख्यात्मक और विराम चिह्न, संभवतः 'ई' या 'ई' शामिल होंगे यदि आप तर्कसंगत संख्याओं के लिए वैज्ञानिक नोटेशन की अनुमति देते हैं, और अल्फा वर्णों का एकमात्र (अन्य) कानूनी उपयोग होगा यदि आप विशिष्ट/अनुमति प्रदान करते हैं गणित कार्य (उदाहरण के लिए stddev)। तो, अल्फा वर्णों के लिए स्ट्रिंग के साथ चलाने के लिए तुच्छ होना चाहिए और अगले छोटे बिट को संदिग्ध नहीं करना चाहिए, फिर बस कोशिश करें/ब्लॉक को छोड़कर स्ट्रिंग को निकालें।

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

def evalMaths(s): 
    i = 0 
    while i < len(s): 
     while s[i].isalpha() and i < len(s): 
      idn += s[i] 
      i += 1 
     if (idn and idn != 'e' and idn != 'abs' and idn != 'round'): 
      raise Exception("you naughty boy: don't " + repr(idn)) 
     else: 
      i += 1 
    return eval(s) 

मुझे यह सुन कर बहुत दिलचस्पी होगी अगर/यह कैसे धोखा दिया जा सकता ... (^_^) BTW/मुझे पता है तुम जैसे कार्यों कॉल कर सकते हैं abs2783 या _983 - यदि वे अस्तित्व में थे, लेकिन वे नहीं करेंगे। मेरा मतलब कुछ व्यावहारिक है।

वास्तव में, यदि कोई ऐसा कर सकता है, तो मैं 200 बाउंटी के साथ एक प्रश्न बनाउंगा और उनका जवाब स्वीकार करूँगा।

+2

-1 ऐसा मत करो। उपयोगकर्ता-इनपुट स्ट्रिंग को 'eval'-ing करना __never__ एक अच्छा विचार है। किसी को आपकी सुरक्षा के आसपास एक रास्ता मिल जाएगा। – katrielalex

+0

पूरी तरह से व्यर्थ दावा के बजाए औचित्य प्रदान करने के बारे में कैसे? यह सुंदर नहीं हो सकता है, लेकिन यदि आप कुछ हासिल करना चाहते हैं, तो एक समाधान समाधान नहीं होने पर, या कुछ जटिल के साथ झुकाव में लागत-लाभ विश्लेषण होता है। –

+0

@ टोनी, इसे गड़बड़ करने की लागत अनंत और परे है। – carl

2

आप किस तरह के भाव चाहते हैं? परिवर्तनीय असाइनमेंट? समारोह मूल्यांकन?

SymPy का लक्ष्य पूर्ण पाइथन सीएएस बनना है।

+0

मैं उपलब्ध संभावनाओं के आधार पर अपनी आवश्यकताओं को बदलने में सक्षम हूं। SymPy दिलचस्प लग रहा है। एक छोटी एकल फ़ाइल लाइब्रेरी भी बेहतर होगी। –

+0

@Ivo: संभावनाएं आपकी आवश्यकताओं पर निर्भर करती हैं! @Paul ने 'pyparsing' के साथ ऐसा करने के कई सरल तरीकों को जोड़ा। 'SymPy 'अधिक खर्च पर अधिक शक्ति उत्पन्न करता है (बड़ा, धीमा हो सकता है)। – katrielalex

+0

'SymPy' अविश्वसनीय इनपुट के लिए सुरक्षित नहीं है। –

1

कुछ हफ्ते पहले मैंने इसी तरह की चीज की, लेकिन तार्किक अभिव्यक्तियों (या,, नहीं, तुलना, कोष्ठक इत्यादि) के लिए। मैंने Ply पार्सर का उपयोग करके ऐसा किया। मैंने सरल लेक्सर और पार्सर बनाया है। पार्सर ने एएसटी पेड़ उत्पन्न किया जिसे बाद में गणना करने के लिए उपयोग किया गया था। इस तरह से ऐसा करने से आप जो उपयोगकर्ता दर्ज करते हैं उसे पूरी तरह से नियंत्रित करने की अनुमति देते हैं, क्योंकि व्याकरण के साथ संगत केवल अभिव्यक्तियों को पार्स किया जाएगा।

+0

मुझे आपकी तार्किक अभिव्यक्ति पार्सर कहां मिल सकती है? अग्रिम में धन्यवाद। –