Javascript中的C解析器

Posted

技术标签:

【中文标题】Javascript中的C解析器【英文标题】:C parser in Javascript 【发布时间】:2012-10-21 17:14:09 【问题描述】:

我想用 javascript 解析 C 头文件。有没有这样的图书馆?否则,有什么提示可以帮助我入门吗?

更新:我的最终目标是为node-ffi 自动构建接口。解析器不一定必须使用 Javascript,只要它可以吐出 Javascript 可以理解的格式即可。如果我自己开发非常困难,我可能不得不使用现成的解决方案......?

【问题讨论】:

err 我真的不明白这个问题...解析 HEADER 文件?目的是什么 我不想这样说,但是……你确定你想这样做吗?众所周知,解析 C 的语法非常困难,即使您不必处理 C 预处理器宏扩展和包含。 @JameySharp 与解析 C 的其余语法相比,编写一个扩展宏并包含文件的 CPreProcessor 非常容易。 解析是一个巨大的主题。您的目标是哪个 C 标准?你想把它解析成什么?为什么你甚至想这样做?此外,您有解析方面的背景经验吗? 对于 C 源代码或标头的纯解析,例如创建 AST,与大多数其他语言相比,我发现它相对微不足道。 C实际上是一种非常简单的语言。但是,如果您不知道“AST”或“递归下降”等术语的含义,那么您面前肯定有一些学习曲线。如果您说明您想要这样做的原因,我们或许可以为您提供更好的帮助。 【参考方案1】:

您可以从查看 peg.js 开始,它生成 javascript 代码来解析作为输入给出的语法。详情请看https://pegjs.org/

然后你需要为你想要解析的头文件编写或找到一个语法。

【讨论】:

太好了,看起来这真的很有帮助。【参考方案2】:

好吧,我会回答我自己的问题,因为我发现了一些有趣的东西:

http://www.swig.org/Doc2.0/SWIGDocumentation.html#SWIG_nn2

Swig 可以输出 C 头文件的 XML 表示,然后我可以从 Javascript 加载。

例如:

swig -module yaml -xmlout yaml.xml yaml.h

生成以下文件(yaml_token_delete 函数下面的 sn-p):

...

<cdecl id="16015" addr="0x10835d500" >
    <attributelist id="16016" addr="0x10835d500" >
        <attribute name="name" value="yaml_token_delete" id="16017" addr="0x1082b2d00" />
        <attribute name="sym_symtab" value="0x1081007e0" id="16018" addr="0x1081007e0" />
        <attribute name="view" value="globalfunctionHandler" id="16019" addr="0x1082b2d00" />
        <attribute name="kind" value="function" id="16020" addr="0x1082b2d00" />
        <attribute name="sym_name" value="yaml_token_delete" id="16021" addr="0x1082b2d00" />
        <attribute name="wrap_parms" value="0x10835d460" id="16022" addr="0x10835d460" />
        <attribute name="decl" value="f(p.yaml_token_t)." id="16023" addr="0x1082b2d00" />
        <attribute name="tmap_out" value="" id="16024" addr="0x1082b2d00" />
        <parmlist id="16025" addr="0x10835d460" >
            <parm id="16026">
                <attributelist id="16027" addr="0x10835d460" >
                    <attribute name="tmap_typecheck" value="void *vptr = 0;&#10;  int res = SWIG_ConvertPtr($input, &amp;vptr, SWIGTYPE_p_yaml_token_s, 0);&#10;  arg1 = SWIG_CheckState(res);" id="16028" addr="0x1082b2d00" />
                    <attribute name="tmap_typecheck_match_type" value="p.SWIGTYPE" id="16029" addr="0x1082b2d00" />
                    <attribute name="tmap_in_match_type" value="p.SWIGTYPE" id="16030" addr="0x1082b2d00" />
                    <attribute name="tmap_freearg_match_type" value="p.SWIGTYPE" id="16031" addr="0x1082b2d00" />
                    <attribute name="compactdefargs" value="1" id="16032" addr="0x1082b2d00" />
                    <attribute name="name" value="token" id="16033" addr="0x1082b2d00" />
                    <attribute name="emit_input" value="objv[1]" id="16034" addr="0x1082b2d00" />
                    <attribute name="tmap_typecheck_precedence" value="0" id="16035" addr="0x1082b2d00" />
                    <attribute name="tmap_in_numinputs" value="1" id="16036" addr="0x1082b2d00" />
                    <attribute name="tmap_in" value="res1 = SWIG_ConvertPtr(objv[1], &amp;argp1,SWIGTYPE_p_yaml_token_s, 0 |  0 );&#10;  if (!SWIG_IsOK(res1))  &#10;    SWIG_exception_fail(SWIG_ArgError(res1), &quot;in method '&quot; &quot;$symname&quot; &quot;', argument &quot; &quot;1&quot;&quot; of type '&quot; &quot;yaml_token_t *&quot;&quot;'&quot;); &#10;  &#10;  arg1 = (yaml_token_t *)(argp1);" id="16037" addr="0x1082b2d00" />

...

【讨论】:

【参考方案3】:

您应该查看clang。

对于一个简单的命令行调用,你可以试试这个:

clang -cc1 -ast-dump-xml myfile.h

或者您可以使用 clang 合理完善的 parser library 构建您自己的工具,它会为您构建一个 AST,并让您按照您认为合适的方式进行操作(也许以 JSON 格式输出)。

【讨论】:

谢谢。实际上有 Node.js 的 Javascript 绑定github.com/tjfontaine/node-libclang

以上是关于Javascript中的C解析器的主要内容,如果未能解决你的问题,请参考以下文章

Python中的JavaScript解析器[关闭]

node.js 概述与安装以及环境搭建

javaScrip

javascrip

Javascript中的Markdown解析器[关闭]

Javascript 中的 IP 地址解析器