根据Parser API,您可以调用Reflect.parse()
来获取AST。不幸的是,在尝试使用C ++评估脚本时,它给出了一个错误ReferenceError: Reflect is not defined
:
const char *script = "var r = Reflect.parse(\"obj.foo + 42\");";
bool ok = JS_EvaluateScript(cx, global, script, strlen(script), filename, lineno, rval.address());
实际上,我想解析一些简单的JS Scripts并在C ++中获取AST,我不喜欢绕道而行,并在JS本身进行分析。你有什么建议吗?文档不是很好imho。
我尝试使用JS_CompileScript()
,但似乎1)JSScript
类的成员在使用已编译的库时不可见2)不再有关于树的信息(? )。
我很想使用非常旧的版本1.6,因为那里有一个非常好的parsing tutorial。你对此有何看法?
另一种方法是不编译SpiderMonkey并直接使用Parser类。
任何提示/建议以最佳方式(在您看来)都会受到高度赞赏。谢谢:))
答案 0 :(得分:3)
实际上,我想解析一些简单的JS Scripts并在C ++中获取AST,我不喜欢绕道而行并在JS本身进行分析。你有什么建议吗?
如果修补猴子是你的选择,我有一个可能的方法。我正在使用SpiderMonkey 45进行此操作,但Reflect API已经存在于24。
在ReflectParse.cpp:3593
中,有功能
static bool reflect_parse(JSContext* cx, uint32_t argc, Value* vp)
使其成为非静态的,并在jsapi.h
中声明它:
extern JS_PUBLIC_API(bool) reflect_parse(JSContext* cx, uint32_t argc, JS::Value* vp);
实际上,这是从所述文件中的JS_InitReflectParse
声明中复制/粘贴。现在,您可以从外部调用Reflect.parse()
的C实现。
您还需要一堆私有标头,我目前包含以下内容:builtin/ModuleObject.h
,jscntxt.h
,jscompartment.h
,jsobj.h
,frontend/ParseNode.h
Value* vp
期望作为第二个参数的reflect_parse
是JS::AutoValueArray<3>
,其构造如下:
JSValue
保存到返回的对象。 CallArgs::rval()
从那里检索它。JS::AutoValueArray<n>
,其中包含Reflect.parse
的参数。因此,对于像Reflect.parse(code)
这样的简单调用,参数可能如下所示:
JS::RootedString codeJsStr(context); // Empty string for now
JS::AutoValueArray<1> parseParams(context);
parseParams[0].setString(codeJsStr);
JS::AutoValueArray<3> vp(m_context);
vp[2].set(*parseParams.begin());
reflect_parse(m_context, parseParams.length(), vp.begin());
然后可以在CallArgs
的帮助下处理返回值,就像记录从C调用js函数一样。