2010-02-27 11 views
11

क्या किसी को ऑनलाइन संसाधन के बारे में पता है, जहां मैं बूस्ट :: आत्मा का उपयोग करके एक साधारण अभिव्यक्ति पार्सर लिखना सीख सकता हूं?बूस्ट :: आत्मा का उपयोग कर सरल अभिव्यक्ति पार्सर उदाहरण?

मुझे अभिव्यक्ति का मूल्यांकन करने की आवश्यकता नहीं है, लेकिन मुझे इसे पार्स करने की आवश्यकता है और यह इंगित करने के लिए एक बूलियन लौटने में सक्षम होना चाहिए कि अभिव्यक्ति पारदर्शी है या नहीं (उदा। ब्रैकेट मिलान नहीं कर रहे हैं)।

मुझे पार्सर को फ़ंक्शन नामों (उदाहरण के लिए foo और foobar) पहचानने में सक्षम होने की आवश्यकता है, इसलिए यह बीएनएफ नोटेशन लिखने में मेरी सहायता करने के लिए एक उपयोगी उदाहरण भी होगा।

भाव सामान्य गणित समीकरण, यानी निम्न प्रतीक के शामिल हो जाएगा:

  1. खोलने/बंद कोष्ठक
  2. अंकगणितीय ऑपरेटर
  3. मान्यता प्राप्त फ़ंक्शन नाम, और उनके लिए आवश्यक तर्क के लिए जाँच
+1

क्या आपने आत्माओं के दस्तावेज और उदाहरणों में देखा था? –

+1

आत्मा का दस्तावेज उतना सरल नहीं है जितना मैं चाहता हूं। मैं इसके द्वारा सीखने में कामयाब रहा, लेकिन बेहतर ट्यूटोरियल निश्चित रूप से सीखना आसान बना देगा। – Tronic

+0

धन्यवाद ट्रॉनिक। जब मैं आत्मा होम पेज पर दस्तावेज़ों के माध्यम से उलझा हुआ था तो यह मेरा विचार था। –

उत्तर

5

यहां कुछ पुराना आत्मा प्रोटोटाइप कोड है जो मैंने चारों ओर बिछाया था:

#include <iostream> 
#include <algorithm> 
#include <vector> 
#include <string> 
#include <exception> 
#include <iterator> 
#include <sstream> 
#include <list> 

#include <boost/spirit.hpp> 
#include <boost/shared_ptr.hpp> 

using namespace std; 
using namespace boost::spirit; 
using namespace boost; 

void g(unsigned int i) 
{ 
    cout << "row: " << i << endl; 
} 

struct u 
{ 
    u(const char* c): s(c) {} 
    void operator()(const char* first, const char* last) const 
    { 
     cout << s << ": " << string(first, last) << endl; 
    } 
private: 
    string s; 
}; 


struct Exp 
{ 
}; 

struct Range: public Exp 
{ 
}; 

struct Index: public Exp 
{ 
}; 

struct String: public Exp 
{ 
}; 

struct Op 
{ 
    virtual ~Op() = 0; 
    virtual string name() = 0; 
}; 

Op::~Op() {} 

struct CountIf: public Op 
{ 
    string name() { return "CountIf"; } 
}; 

struct Sum: public Op 
{ 
    string name() { return "Sum"; } 
}; 

struct Statement 
{ 
    virtual ~Statement() = 0; 
    virtual void print() = 0; 
}; 

Statement::~Statement() {} 

struct Formula: public Statement 
{ 
    Formula(const char* first, const char* last): s(first, last), op(new CountIf) 
    { 
     typedef rule<phrase_scanner_t> r_t; 

     r_t r_index  = (+alpha_p)[u("col")] >> uint_p[&g]; 
     r_t r_range  = r_index >> ':' >> r_index; 
     r_t r_string = ch_p('\"') >> *alnum_p >> '\"'; 
     r_t r_exp  = r_range | r_index | r_string; // will invoke actions for index twice due to range 
     r_t r_list  = !(r_exp[u("arg")] % ','); 
     r_t r_op  = as_lower_d["countif"] | as_lower_d["sum"]; 
     r_t r_formula = r_op >> '(' >> r_list >> ')'; 

     cout << s << ": matched: " << boolalpha << parse(s.c_str(), r_formula, space_p).full << endl; 
    } 
    void print() { cout << "Formula: " << s << "/" << op->name() << endl; } 
private: 
    string s; 
    shared_ptr<Op> op; 
    list<shared_ptr<Exp> > exp_list; 
}; 

struct Comment: public Statement 
{ 
    Comment(const char* first, const char* last): comment(first, last) {} 
    void print() {cout << "Comment: " << comment << endl; } 
private: 
    string comment; 
}; 


struct MakeFormula 
{ 
    MakeFormula(list<shared_ptr<Statement> >& list_): list(list_) {} 
    void operator()(const char* first, const char* last) const 
    { 
     cout << "MakeFormula: " << string(first, last) << endl; 
     list.push_back(shared_ptr<Statement>(new Formula(first, last))); 
    } 
private: 
    list<shared_ptr<Statement> >& list; 
}; 

struct MakeComment 
{ 
    MakeComment(list<shared_ptr<Statement> >& list_): list(list_) {} 
    void operator()(const char* first, const char* last) const 
    { 
     cout << "MakeComment: " << string(first, last) << endl; 
     list.push_back(shared_ptr<Statement>(new Comment(first, last))); 
    } 
private: 
    list<shared_ptr<Statement> >& list; 
}; 


int main(int argc, char* argv[]) 
try 
{ 
    //typedef vector<string> v_t; 
    //v_t v(argv + 1, argv + argc); 
    // copy(v.begin(), v.end(), ostream_iterator<v_t::value_type>(cout, "\n")); 

    string s; 
    getline(cin, s); 

    //  =COUNTIF(J2:J36, "Abc") 

    typedef list<shared_ptr<Statement> > list_t; 
    list_t list; 

    typedef rule<phrase_scanner_t> r_t; 

    r_t r_index  = (+alpha_p)[u("col")] >> uint_p[&g]; 
    r_t r_range  = r_index >> ':' >> r_index; 
    r_t r_string = ch_p('\"') >> *alnum_p >> '\"'; 
    r_t r_exp  = r_range | r_index | r_string; // will invoke actions for index twice due to range 
    r_t r_list  = !(r_exp[u("arg")] % ','); 
    r_t r_op  = as_lower_d["countif"] | as_lower_d["sum"]; 
    r_t r_formula = r_op >> '(' >> r_list >> ')'; 
    r_t r_statement = (ch_p('=') >> r_formula [MakeFormula(list)]) 
        | (ch_p('\'') >> (*anychar_p)[MakeComment(list)]) 
        ; 

    cout << s << ": matched: " << boolalpha << parse(s.c_str(), r_statement, space_p).full << endl; 

    for (list_t::const_iterator it = list.begin(); it != list.end(); ++it) 
    { 
     (*it)->print(); 
    } 
} 
catch(const exception& ex) 
{ 
    cerr << "Error: " << ex.what() << endl; 
} 

यह चल रहा है और तरह की एक पंक्ति में प्रवेश का प्रयास करें:

=COUNTIF(J2:J36, "Abc") 
+1

अच्छा उदाहरण! खैर, लेकिन क्या यह वास्तव में _simple_ है? – Vlad

+0

ठीक है, यह पूरी तरह से मामूली नहीं है, लेकिन यह अभी भी एक पृष्ठ है (शायद डबल-पक्षीय!) मुद्रित कोड के लायक है जिसे मैंने घरेलू उड़ान पर लिखा था। :) –

1

मुझे यकीन है कि अगर यह या तो के रूप में सरल उत्तीर्ण नहीं कर रहा हूँ, लेकिन मैं इस URI-व्याकरण उपलब्ध का उपयोग किया है http://code.google.com/p/uri-grammar/source/browse/trunk/src/uri/grammar.hpp पर। यह तुच्छ नहीं हो सकता है, लेकिन कम से कम इसका विश्लेषण कुछ ऐसा है जिसे आप शायद पहले से ही समझते हैं (यूआरआई)। इन व्याकरणों को पढ़ने के दौरान, नीचे से पढ़ने के लिए सबसे अच्छा है, क्योंकि वह सबसे सामान्य टोकन परिभाषित किया जाता है।

5

आत्मा (V2.x) के वर्तमान संस्करण में कैलकुलेटर उदाहरणों की एक पूरी श्रृंखला बहुत सरल से पूर्ण मिनी-सी दुभाषिया तक है। आपको वहां एक नज़र रखना चाहिए क्योंकि यह आपके स्वयं के अभिव्यक्ति पार्सर लिखने के लिए एक आदर्श प्रारंभिक बिंदु है।

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