2014-12-02 38 views
3

我很好奇使用正則表達式解析C++代碼。我迄今(使用紅寶石)什麼可以讓我解壓類的聲明及其父類(如果有的話):Ruby正則表達式:解析C++類

/(struct|class)\s+([^{:\s]+)\s*[:]?([^{]+)\s*\{/ 

這裏是Rubular的example。注意我可以正確捕獲「聲明」和「繼承」部分。

我被卡住的地方在於捕獲類本體。如果我用原來的正則表達式的以下擴展:

/(struct|class)\s+([^{:\s]+)\s*[:]?([^{]+)\s*\{[^}]*\};/ 

然後我可以捕捉類體只有它不包含任何大括號,因此任何類或函數的定義。 在這一點上,我嘗試了很多東西,但沒有一個讓這個更好。例如,如果我在正則表達式中包含body可以包含大括號的事實,它將捕獲第一個類聲明,然後捕獲所有後續的類,就好像它們是第一個類的body的一部分一樣!

我錯過了什麼?

回答

1

group capturing可能幫助:

#     named v backref   v 
/(struct|class)\s+(?<match>{((\g<match>|[^{}]*))*})/m 

在這裏,我們找到了一個下面struct/class聲明匹配花括號。你可能會想要調整正則表達式,我發佈了這個解決方案儘可能清晰。

0

什麼我可以爲您提供這樣的:

(struct|class)\s+([^{:\s]+)\s*[:]?([^{]+)\{([^{}]|\{\g<4>\})*\}; 

哪裏\g<4>是第四捕獲組,這是([^{}]|\{\g<4>\})的遞歸應用。

將非正則語言與正則表達式匹配永遠不會很漂亮。您可能需要考慮切換到正確的遞歸下降解析器,特別是如果您打算對剛剛捕獲的內容執行某些操作。

4

正則表達式不是解析代碼的推薦方法。

在編譯或運行代碼之前,大多數編譯器和解釋器都使用lexers和解析器將代碼轉換爲abstract syntax tree

Ruby有幾個詞法寶石,比如this,你可以嘗試並納入你的項目。

+1

一般而言,這是正確的。然而,在某些情況下,正則表達式可能會「足夠好」。例如。對一些代碼進行快速的啓發式分析。 – 2014-12-02 11:09:42

+1

@undur_gongor - 陳述OP的第一句話 - 「我很好奇使用正則表達式來解析C++代碼」 - 這聽起來像是一般,因爲他們來:)。我同意,只要代碼不是任意的(你確切地說來自哪裏以及它是如何構造的),使用正則表達式來閱讀HTML或代碼的一些任務已經足夠了 – 2014-12-02 11:13:31

+0

謝謝你。雖然你的回答看起來很有啓發性,但我只是「玩」瞭解析C++代碼的可能性(例如計算一個類中的方法數量等)。我會接受mudasobwa的回答,因爲它幫助了我很多,但請記住您寶貴的建議;) – 2015-01-09 15:47:04