2013-02-06 29 views
13

我是doctest的作者,快速和髒doctests爲JavaScript和CoffeeScript。我想通過使用JavaScript解析器而不是正則表達式來定位註釋,從而減少庫的髒問題。替換JavaScript中的評論AST與從評論的內容派生的子樹

我想使用EsprimaAcorn做到以下幾點:

  1. 創建AST
  2. 走的樹,併爲每個註釋節點:
    1. 創建一個從評論的AST節點的文本
    2. 用此子樹替換主樹中的註釋節點

輸入:

!function() { 

    // > toUsername("Jesper Nøhr") 
    // "jespernhr" 
    var toUsername = function(text) { 
    return ('' + text).replace(/\W/g, '').toLowerCase() 
    } 

}() 

輸出:

!function() { 

    doctest.input(function() { 
    return toUsername("Jesper Nøhr") 
    }); 
    doctest.output(4, function() { 
    return "jespernhr" 
    }); 
    var toUsername = function(text) { 
    return ('' + text).replace(/\W/g, '').toLowerCase() 
    } 

}() 

我不知道如何做到這一點。 Acorn提供了一個walker,它接受一個節點類型和一個函數,並在每次遇到指定類型的節點時遍歷調用該函數的樹。這似乎很有前途,但不適用於評論。

與Esprima我可以使用esprima.parse(input, {comment: true, loc: true}).comments來獲得評論,但我不知道如何更新樹。

+1

你試過[JSShaper](https://github.com/olov/jsshaper)嗎? –

+0

我不知道那個項目。看起來很有希望。 – davidchambers

回答

3

大多數AST產生的解析器會丟棄評論。我不知道Esprima或Acorn做了什麼,但這可能是問題所在。

....其實,Esprima列出註釋捕獲作爲當前的錯誤: http://code.google.com/p/esprima/issues/detail?id=197

... Acorn的代碼是正確的,在GitHub上。它似乎也放棄了評論。

因此,看起來您可以修復任何一個解析器來捕獲註釋,此時您的任務應該很簡單,或者您被困住了。

我們的DMS Software Reengineering Toolkit擁有可在樹中捕獲註釋的JavaScript解析器。它也有語言substring解析器,可用於將註釋文本解析爲任何類型註釋表示的JavaScript AST(例如,函數聲明,表達式,變量聲明等),以及支持機制新的AST進入主樹。如果您要操縱AST,這個子字符串功能可能很重要:大多數解析器不會解析任意語言片段,它們僅用於解析「整個程序」。對於DMS,沒有要替換的註釋節點;有與AST節點相關的評論,所以嫁接過程比「替換評論節點」有點棘手。還是很容易的。

我會觀察到大多數解析器(包括這些)通過使用或應用正則表達式的等價物來讀取源代碼並將其分解爲令牌。因此,如果您已經在使用這些來查找評論(這意味着使用它們來查找*非*評論以便丟棄,例如,您需要識別包含類似註釋的文本的字符串文本並忽略它們),您所做的和解析器無論如何都會按照找到註釋。如果你想要做的只是用它們的內容來替換它們,用源碼流/註釋前綴/ suffix/* * /剝離來回顯源碼流將完全按照你想要的來做,所以這些解析機制看起來似乎是矯枉過正的。

2

您已經可以用Esprima達到你想要的東西:

  1. 解析代碼,得到的意見(如數組)。
  2. 迭代評論,看看你是否都感興趣。
  3. 如果你需要轉換評論,請注意它的範圍。收集所有轉換。
  4. 先應用變換,以避免範圍偏移。

訣竅是這裏沒有改變AST。只需直接應用文本更改,就好像您正在對源字符串進行典型搜索替換一樣。因爲替換的位置可能會發生變化,所以您需要收集所有內容,然後從最後一個位置開始。有關如何進行此類轉換的示例,請參閱我的博客帖子"From double-quotes to single-quotes"(它涉及字符串引號,但原理保持不變)。

最後但並非最不重要的一點,您可能需要使用一個稍高級別的實用程序,如Rocambole