Question

I'd like to parse C header files in Javascript. Is there any such library available? Otherwise, any tips to help me get started?

Update: My ultimate goal is to automatically build interfaces for node-ffi. The parser doesn't necessarily have to be in Javascript as long as it can spit out a format understandable by Javascript. If it's very hard to develop by myself, I'll probably have to go with an off the shelf solution...?

Was it helpful?

Solution

You should check out clang.

For a simple command-line invocation, you can try this:

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

Or you can build your own tool using clang reasonably-well-documented parser library, which will build an AST for you, and let you walk it as you see fit (perhaps for output in JSON).

OTHER TIPS

You might start by looking at peg.js which generates javascript code to parse a grammar given as input. Details avalable here https://pegjs.org/

Then yo would need to write or find a grammar for the header files you want to parse.

Well I'll answer my own question since I found something interesting:

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

Swig can output an XML representation of C header files that I could then load from Javascript.

For example:

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

Generates the following file (snippet below for the yaml_token_delete function):

...

<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" />

...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top