2010-03-18 114 views
4

我需要驗證C#方法的內容。C#方法內容驗證

我不關心不影響方法範圍的語法錯誤。

我關心字符,將無效解析其餘的代碼。例如:

method() 
{ 
    /* valid comment */ 
    /*   <-- bad 
    for (i..) { 
    } 
    for (i..) { <-- bad 
} 

我需要驗證/修復任何非配對字符。

這包括/ * * /,{}和其他人。

我應該怎麼辦?

我的第一個想法是正則表達式,但顯然不會完成工作。

回答

3

你會更仔細地需要範圍的問題,爲了得到一個合理的答案。

例如,您打算如何處理包含預處理器指令的方法?

void M() 
{ 

#if FOO 
    for(foo;bar;blah) { 
#else 
    while(abc) { 
#endif 
     Blah(); 
    } 
} 

這是愚蠢但合法,所以你必須處理它。你會把它算作不匹配的大括號嗎?

您能提供詳細規格正是您想要確定的內容嗎?正如我們在本網站上多次看到的那樣,人們無法成功構建一個在沒有規範的情況下劃分兩個數字的例程。你所談論的分析比分兩個數字要複雜得多;那些在實際編譯器中描述的代碼就是成千上萬行的代碼。

+0

我不需要絕對的解決方案。我試圖提供的是一個簡單的指標,可能在代碼中有錯誤。 1.如果代碼包含preproccesor語句,則不執行任何操作。對於我的用戶來說,這是一個極端情況,而且難度更大。 2.如果代碼包含一個不匹配的{或/ *,將其突出顯示 這並不是很詳細,但它確切地說明了我需要的內容。 – jaws 2010-03-19 13:37:23

+0

@ user258651:好的,字符串呢?假設你的代碼有一個不匹配的大括號,但包含* Console.WriteLine(「}}}}}」); * - 做這些計數作爲大括號結束或不? – 2010-03-19 15:36:12

+0

@ user258651:如果評論包含一個大括號怎麼辦?你是否把它當作最後的大括號? – 2010-03-19 15:36:39

1

正則表達式當然不是這個問題的答案。正則表達式是用於某些類型的數據驗證的有用工具。但是一旦你進入更復雜的數據如匹配大括號或​​註釋塊的業務,正則表達式不再能完成工作。

這是一篇關於使用正則表達式驗證輸入時遇到的限制的博客文章。

爲了做到這一點,你將不得不寫這的確驗證了各種各樣的解析器。

0

如果您試圖「驗證」定義方法的字符串的內容,那麼您可能會更好,只是嘗試使用CodeDom類並將該方法即時編譯到內存組合中。

編寫您自己的全功能解析器來進行驗證將非常非常困難,特別是如果您想支持C#3或更高版本。 Lambda表達式和其他類似的構造將很難「乾淨地」驗證。

0

您在「將解析剩餘代碼無效的字符」和「語法錯誤」之間進行錯誤的二分法。缺少一個大括號(你提到的其中一個問題)是一個語法錯誤。看起來你的意思是你正在尋找可能破壞範圍邊界的語法錯誤?不幸的是,沒有可靠的方法來做到這一點,使用完整的解析器。

舉個例子:

method() 
{ <-- is missing closing brace 
    /* valid comment */ 
    /*   <-- bad 
    for (i..) { 
    } 
    for (i..) { 
} <-- will be interpreted as the closing brace for the for loop 

有來推斷它的for循環唯一缺少的右括號,而不是方法沒有通用的,實用的方法。

如果您真的有興趣尋找這些東西,您應該考慮以編程方式運行編譯器並解析結果 - 這是使用最低入口閾值的最佳方法。

+0

該方法的大括號不是我正在驗證的一部分。只有內容位於我需要驗證的字符串中 – jaws 2010-03-18 21:37:59

+0

我以前曾考慮過這個特定問題,並且看不到爲什麼縮進無法用於確定最後一個大括號是否適用於該方法。 – 2010-03-18 21:39:19

+0

@ user258651道歉 - 我必須誤解你的代碼示例,然後。第二個for循環的「< - bad」是什麼意思? – Dathan 2010-03-18 22:00:47

1

對於這樣的任務,正則表達式不是一件很方便的事情。這通常通過使用如下算法的堆棧來實現:

  1. 創建一個空堆棧S.
  2. while(there left characters){
  3. 閱讀字符ch。
  4. 如果是CH的開口括號(任何種類的),將其推到小號
  5. 否則
  6. 如果CH是一個閉合括號(任何種類的),看S.
  7. 頂部
  8. 若S這一點是空的,報告失敗。
  9. 如果S的頂部是與c相對應的開頭paren,則彈出S並繼續到1,這個paren匹配OK。
  10. 其他報告失敗。
  11. 如果在輸入結束時堆棧S不爲空,則返回失敗。 其他回報成功。

的更多信息,請http://www.ccs.neu.edu/home/sbratus/com1101/lab4.htmlhttp://codeidol.com/csharp/csharpckbk2/Data-Structures-and-Algorithms/Determining-Where-Characters-or-Strings-Do-Not-Balance/

+0

步驟#4不正確,因爲您必須考慮評論。下面的代碼會註冊爲有效,但實際上是無效的:儘管如此,foo(//) – JaredPar 2010-03-18 21:40:05

+0

正則表達式有助於忽略註釋或字符串中的內容,您可以一次性匹配整個事件,無需解析器狀態。 – 2010-03-18 21:41:43

+0

@JaredPar:行註釋只是一個「/」開頭匹配「\ n」結束。阻止評論或字符串沒有什麼不同。 – 2010-03-18 21:42:43