2010-03-30 10 views
7

मैं यहां सी और/या सी ++ के बारे में बात कर रहा हूं क्योंकि यह केवल उन्हीं भाषाएं हैं जिन्हें मैं दुभाषियों के लिए उपयोग करता हूं जहां निम्नलिखित समस्या हो सकती है:सी और सी ++ में लिखे गए दुभाषिया सी (++) कार्यों के लिए बाध्य पहचानकर्ता

यदि हमारे पास एक व्याख्या की गई भाषा एक्स है, तो इसके लिए लिखी गई लाइब्रेरी भाषा में फ़ंक्शंस कैसे जोड़ सकती है जिसे भाषा में लिखे गए प्रोग्रामों के भीतर से बुलाया जा सकता है?

पीएचपी उदाहरण:

substr($str, 5, 10); 
  • कैसे है समारोह substr PHP के "समारोह पूल" को जोड़ा गया तो यह स्क्रिप्ट के भीतर से कहा जा सकता है?

पीएचपी के लिए एक सरणी में सभी पंजीकृत फ़ंक्शन नामों को संग्रहीत करना और एक फ़ंक्शन के रूप में इसे खोजना एक स्क्रिप्ट में खोजना आसान है। हालांकि, चूंकि स्पष्ट रूप से सी (++) में कोई eval नहीं है, तो समारोह को फिर कैसे कहा जा सकता है? मुझे लगता है कि PHP में 100 एमबी कोड नहीं है जैसे:

if(identifier == "substr") 
{ 
    return PHP_SUBSTR(...); 
} else if(...) { 
    ... 
} 

हा हा, यह बहुत मजेदार होगा। मुझे आशा है कि अब तक आप मेरे प्रश्न को समझ चुके हैं।

  • सी/सी ++ में लिखे गए दुभाषिया इस समस्या को हल करते हैं?
  • सी ++ में लिखे गए अपने प्रयोगात्मक खिलौने दुभाषिया के लिए मैं इसे कैसे हल कर सकता हूं?
+0

आप में क्या रणनीति दुभाषिए पूछ रहे हैं सामान्य उपयोग? विशेष रूप से सी/सी ++ के लिए एक दुभाषिया यह कैसे कर सकता है? या कैसे सी/सी ++, संकलित जब, यह करते हैं? – MtnViewMark

+0

* दुभाषिया इस समस्या को कैसे हल करते हैं? * मैं अपने स्वयं के प्रयोगात्मक खिलौने दुभाषिया के लिए इसे कैसे हल कर सकता हूं? – sub

उत्तर

7

असल में पटकथा भाषाएं आपके द्वारा उल्लेखित कुछ की तरह कुछ करती हैं।
वे फ़ंक्शन लपेटते हैं और वे उस फ़ंक्शन को दुभाषिया इंजन में पंजीकृत करते हैं।

लुआ नमूना:

static int io_read (lua_State *L) { 
    return g_read(L, getiofile(L, IO_INPUT), 1); 
} 


static int f_read (lua_State *L) { 
    return g_read(L, tofile(L), 2); 
} 
... 
static const luaL_Reg flib[] = { 
    {"close", io_close}, 
    {"flush", f_flush}, 
    {"lines", f_lines}, 
    {"read", f_read}, 
    {"seek", f_seek}, 
    {"setvbuf", f_setvbuf}, 
    {"write", f_write}, 
    {"__gc", io_gc}, 
    {"__tostring", io_tostring}, 
    {NULL, NULL} 
}; 
... 
luaL_register(L, NULL, flib); /* file methods */ 
+0

यह शर्मनाक है लेकिन मुझे नहीं पता था कि आप सरणी में कार्यों को स्टोर कर सकते हैं, निश्चित रूप से सबकुछ बदलता है; डी – sub

+0

@sub, हाँ, फ़ंक्शन पॉइंटर्स के सरणी। इसे देखें :) –

+1

एक नोट: कई कॉल हर कॉल के लिए ऐसा नहीं करते हैं। अक्सर, वे पार्सिंग के दौरान यह लुक-अप करते हैं, और तुरंत फ़ंक्शन पॉइंटर्स में सभी फ़ंक्शन नाम बदल देते हैं। कुछ रनटाइम पर कॉल असेंबलर निर्देश भी उत्पन्न करते हैं, जिसका अर्थ है कि उनके कार्यों को किसी अन्य मूल कार्य की तरह ही कहा जा सकता है, और केवल लाइब्रेरी दिनचर्या ही कॉल करता है। – uliwitness

1

बहुत सारे सभी कंपाइलरों में "प्रतीक तालिका" होती है जिसे वे पहचानने के लिए उपयोग करते हैं जो पहचानकर्ता प्रतिनिधित्व करता है। प्रतीक तालिका में फ़ंक्शन नाम, परिवर्तनीय नाम, प्रकार के नाम, इत्यादि होंगे ... कुछ भी जिसका नाम एक प्रतीक तालिका में जाता है, जो कि मूल रूप से उस नाम के बारे में जानता है जो संकलक जानता है (मैं यहां सरलीकृत कर रहा हूं)। फिर जब संकलक एक पहचानकर्ता से मुठभेड़ करता है, तो यह इसे प्रतीक तालिका में देखता है, और पता लगाता है कि यह एक कार्य है। यदि आप एक दुभाषिया का उपयोग कर रहे हैं, तो प्रतीक तालिका में फ़ंक्शन को ढूंढने और व्याख्या जारी रखने के बारे में जानकारी होगी। यदि यह एक कंपाइलर है, तो प्रतीक तालिका में पता होगा कि वह फ़ंक्शन संकलित कोड (या बाद में पता भरने के लिए प्लेसहोल्डर) में होगा। तब असेंबली का उत्पादन किया जा सकता है जो अनिवार्य रूप से कहता है: स्टैक पर तर्क डालें, और कुछ पते पर निष्पादन फिर से शुरू करें।

तो, आप उदाहरण के लिए एक दुभाषिया

substr($str, 5, 10); 

को देखो और "substr" लगता है यह प्रतीक तालिका है में होगा:

symbolTableEntry entry = symbolTable["substr"]; 
वहाँ से

, यह $str, 5 इकट्ठा होगा और 10 तर्क के रूप में, और entry पर यह देखने के लिए कि तर्क फ़ंक्शन के लिए मान्य हैं। फिर यह चिह्नित करने के लिए entry में देखेंगे कि मार्शल किए गए तर्कों के साथ कहां जाना है।

2

दुभाषिए शायद फ़ंक्शन परिभाषा में फ़ंक्शन नामों का हैशैप रखें (जिसमें पैरामीटर जानकारी, रिटर्न प्रकार, फ़ंक्शन स्थान/परिभाषा इत्यादि शामिल होंगे) इस तरह, आप फ़ंक्शन नाम के लिए हैशपैप पर एक खोज कर सकते हैं (जब आपका दुभाषिया एक मुठभेड़ करता है)। यदि यह मौजूद है, तो इसका मूल्यांकन करने के लिए हैशटेबल में फ़ंक्शन जानकारी का उपयोग करें।

आपको स्पष्ट रूप से दायरे के विभिन्न स्तरों के प्रावधान जोड़ने की आवश्यकता है, लेकिन यह इसका सारांश है।

0

C++ में आप शायद एक ही एक तंत्र का उपयोग करेंगे के रूप में निक डी किया था, लेकिन इसके OO क्षमताओं का लाभ लेने:

typedef luaFunction boost::function<void(*)(lua_State&)> 
std::map<std::string, luaFunction > symbolTable; 
symbolTable["read"] = f_read; 
symbolTable["close"] = f_close; // etc. 
// ... 
luaFunction& f = symbolTable[*symbolIterator++]; 
f(currentLuaState);