निम्न समाधान बिल्कुल वही नहीं है जो आपने पूछा है, लेकिन मुझे उम्मीद है कि एक सादा सी जवाब होने के बावजूद यह आपकी आवश्यकताओं को पूरा करेगा। पहिया को पुनर्निर्मित करने का कोई तरीका नहीं है इसलिए चलिए स्पाइडरमोन्की, मोज़िला जावास्क्रिप्ट इंजन के साथ इसे चलाकर सी में date.js का उपयोग करें।
यहां मैंने यह कैसे किया। मैंने डेट.जेएस डाउनलोड करने और इसे const char*
में code
नामित date.js.h
में परिभाषित करने के साथ शुरू किया है।
(\
echo 'const char *code =' ; \
curl https://datejs.googlecode.com/files/date.js | \
sed -e 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/\r\?$/\\n"/'; \
echo ';' \
) > date.js.h
फिर मैंने शुरुआती बिंदु के रूप में JSAPI's Hello, World! लिया।
#include "jsapi.h"
#include "date.js.h"
static JSClass global_class = { "global", JSCLASS_GLOBAL_FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
JSCLASS_NO_OPTIONAL_MEMBERS };
void reportError(JSContext *cx, const char *message, JSErrorReport *report) {
fprintf(stderr, "%s:%u:%s\n",
report->filename ? report->filename : "<no filename>",
(unsigned int) report->lineno, message);
}
int main(int argc, const char *argv[]) {
JSRuntime *rt;
JSContext *cx;
JSObject *global;
rt = JS_NewRuntime(8L * 1024L * 1024L);
if (rt == NULL) return 1;
cx = JS_NewContext(rt, 8192);
if (cx == NULL) return 1;
JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
JS_SetVersion(cx, JSVERSION_LATEST);
JS_SetErrorReporter(cx, reportError);
global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
if (global == NULL) return 1;
if (!JS_InitStandardClasses(cx, global)) return 1;
/* Here's where the interesting stuff is starting to take place.
* Begin by evaluating sources of date.js */
jsval out;
if (!JS_EvaluateScript(cx, global, code, strlen(code), "code", 1, &out))
return 1;
/* Now create a call to Date.parse and evaluate it. The return value should
* be a timestamp of a given date. If no errors occur convert the timestamp
* to a double and print it. */
const int buflen = 1024;
char parse[buflen + 1];
snprintf(parse, buflen, "Date.parse(\"%s\").getTime();", argv[1]);
if (!JS_EvaluateScript(cx, global, parse, strlen(parse), "parse", 1, &out))
return 1;
double val;
JS_ValueToNumber(cx, out, &val);
printf("%i\n", (int) (val/1000));
/* Finally, clean everything up. */
JS_DestroyContext(cx);
JS_DestroyRuntime(rt);
JS_ShutDown();
return 0;
}
यहां अभ्यास में यह कैसे काम करता है।
$ time ./parse "week ago"
1331938800
0.01user 0.00system 0:00.02elapsed 92%CPU (0avgtext+0avgdata 6168maxresident)k
0inputs+0outputs (0major+1651minor)pagefaults 0swaps
$ time ./parse yesterday
1332457200
0.01user 0.00system 0:00.02elapsed 84%CPU (0avgtext+0avgdata 6168maxresident)k
0inputs+0outputs (0major+1653minor)pagefaults 0swaps
आप यह काफी तेज है देख सकते हैं और आप काफी Date.parse
के बाद के सभी कॉल के लिए शुरू में बनाई गई संदर्भ पुन: उपयोग से इसके प्रदर्शन को बढ़ा सकता है के रूप में।
लाइसेंसिंग मुद्दों के बारे में बोलते हुए, दिनांक.जेएस एमआईटी और स्पाइडरमोन्की के तहत उपलब्ध है एमपीएल 1.1, जीपीएल 2.0 या एलजीपीएल 2.1 के तहत उपलब्ध है। इसे जोड़ने से गतिशील रूप से गैर-जीपीएल आवश्यकता को पूरा किया जाता है।
टी एल; डॉ:git clone https://gist.github.com/2180739.git && cd 2180739 && make && ./parse yesterday
क्या इसके लायक है के लिए, date.js एमआईटी लाइसेंस प्राप्त है। तो यदि यहां लक्ष्य कुछ प्राप्त करना है, तो आप स्वामित्व कोड से लिंक कर सकते हैं, तो आपको डेट.जेएस को एक सुरक्षित प्रारंभिक बिंदु के रूप में उपयोग करने में सक्षम होना चाहिए यदि आपको अपना खुद का रोल करना है। हालांकि जावास्क्रिप्ट-टू-सी रीराइटिट पार्क में चलना नहीं हो सकता है। –
यही कारण है कि मैं कोड लिखने के लिए आगे बढ़ने के बजाय इस सवाल से पूछ रहा हूं :-) –
यदि आप अपने स्वयं के पार्सर लिखने के लिए स्रोत जटिलता के बारे में चिंतित हैं, तो क्या आप lex/yacc टूल्स का उपयोग कर सकते हैं? – Jerry