2010-11-19 94 views
3

我正在寻找一种方法来访问来自一些(其他)JavaScript代码的javascript评论。 我打算使用它来显示调用各种js函数的页面上的元素的低级别帮助信息,而不用在多个地方复制该信息。在javascript中检索javascript评论,或者,如何在js中解析js?

的mypage.html:

... 
<script src="foo.js"></script> 
... 
<span onclick="foo(bar);">clickme</span> 
<span onclick="showhelpfor('foo');>?</span> 
... 

foo.js:

/** 
* This function does foo. 
* Call it with bar. Yadda yadda "groo". 
*/ 
function foo(x) 
{ 
    ... 
} 

我想我可以使用的getElementsByTagName抢script标签,然后用AJAX请求,以获得纯加载文件它的文字内容。然而,那么我需要一种可靠的方式来解析JavaScript(即不是一堆黑客一起正则表达式),它保留了简单评估它的人物会丢弃的字符。

我正在考虑简单地将文档放在函数后面,在一个js字符串中,但这很尴尬,我有一种感觉,让doxygen去挑选它会很困难。

function foo(x) { ... } 
foo.comment = "\ 
This functions does foo.\ 
Call it with bar. Yadda yadda \"groo\".\ 
"; 

回答

8

您可以创建一个不解析完整JS语言的小解析器,但当然只匹配字符串文字,单行和多行注释和函数。

有一个名为PEG.js的JS解析器生成器,可以很容易地做到这一点。语法看起来是这样的:

{ 
var functions = {}; 
var buffer = ''; 
} 

start 
    = unit* {return functions;} 

unit 
    = func 
/string 
/multi_line_comment 
/single_line_comment 
/any_char 

func 
    = m:multi_line_comment spaces? "function" spaces id:identifier {functions[id] = m;} 
/"function" spaces id:identifier        {functions[id] = null;} 

multi_line_comment 
    = "/*" 
    (!{return buffer.match(/\*\//)} c:. {buffer += c;})*    
    { 
     var temp = buffer; 
     buffer = ''; 
     return "/*" + temp.replace(/\s+/g, ' '); 
    } 

single_line_comment 
    = "//" [^\r\n]* 

identifier 
    = a:([a-z]/[A-Z]/"_") b:([a-z]/[A-Z]/[0-9] /"_")* {return a + b.join("");} 

spaces 
    = [ \t\r\n]+ {return "";} 

string 
    = "\"" ("\\" ./[^"])* "\"" 
/"'" ("\\" ./[^'])* "'" 

any_char 
    = . 

当你解析与生成的解析器以下来源:

/** 
* This function does foo. 
* Call it with bar. Yadda yadda "groo". 
*/ 
function foo(x) 
{ 
    ... 
} 

var s = " /* ... */ function notAFunction() {} ... "; 

// function alsoNotAFunction() 
// { ... } 

function withoutMultiLineComment() { 
} 

var t = ' /* ... */ function notAFunction() {} ... '; 

/** 
* BAR! 
* Call it? 
*/ 





      function doc_way_above(x, y, z) { 
    ... 
} 

// function done(){}; 

解析器的start()函数返回以下地图:

{ 
    "foo": "/** * This function does foo. * Call it with bar. Yadda yadda \"groo\". */", 
    "withoutMultiLineComment": null, 
    "doc_way_above": "/** * BAR! * Call it? */" 
} 

我意识到有一些需要填补的空白(如this.id = function() { ... }),但在阅读the docs from PEG.js之后,这应该不是什么大问题(讽刺g你知道一些解析器生成器)。如果这是一个问题,请回复并将其添加到语法中,并解释一下语法中发生的事情。

你甚至可以在test the grammar以上发布在线!

+0

eek,这比我所希望的要多一点,但它看起来应该做我所需要的。谢谢! – Eric 2013-04-09 16:54:19

0

你可以在每一个注释的开始使用一个唯一的字符串标识,然后使用唯一的标识符,你可以很容易地制作一个正则表达式来提取评论。