2012-02-29 16 views
2

尋找代碼中RPAREN的最佳方法是什麼? 舉例來說,我有這樣的僞代碼:正確尋找RPAREN(以啓用快速解析)

if(a && (b || "c)")) 
    |  ^---------^| CASE A 
    ^----------------^ CASE B 

舉例來說,如果我考慮的第一LPAREN,它需要匹配的最後RPAREN(案例B)。如果我考慮第二個LPAREN,它需要與最後一個RPAREN匹配(情況A)。

請注意,有字符串"C)"有一個RPAREN,但它需要被忽略的情況下。

嗯......我想到了正則表達式,但我想這將是非常複雜的(注意,需要匹配字符串,正則表達式,而另一個認爲可以包括RPAREN或類似的東西)。然後我考慮使用手動掃描(通過代碼)來檢測每個部分(如手動正則表達式)。

我需要那個解析我正在構建的代碼(自己的編程語言)。我想忽略閱讀一些代碼以使其更快。

例如:

function a() { return 1; } 
function b() { return 2; } 
alert(b()); 

在這種情況下,只需要b()被解析,因爲a()從來沒有被使用。所以我會通過starter {掃描並忽略(但是存儲)直到真實}。如果使用該函數,它將被解析。

我的疑惑:

  1. 正則表達式或手動代碼?
  2. 這是一件好事還是壞事?如果從不使用代碼,將會有助於提高解析器的速度嗎?
  3. 題外話:提高分析器的一些技巧?也許一個「預解析」文件,用計算機代碼(操作碼???)存儲語言代碼?
+1

你不能使用正則表達式來分析嵌套結構。使用詞法分析器和解析器。 – leppie 2012-02-29 04:33:08

回答

2

如果您正在構建您自己的語言,您應該真正瞭解處理語言源代碼的標準方法。 (歡迎您提出聰明的新想法,但大多數這樣的想法結果並不那麼聰明,如果您知道標準的想法,爲什麼它通常是非常明顯的)。

你真的無法處理你的代碼,並與純正則表達式「匹配」括號。您需要某種下推式自動機或計數引擎來匹配在此類任務的上下文中經常被稱爲「分析器」的嵌套派生類(或任何可能匹配的其他內容,例如,大括號,IF和ENDIF,...)。

關於你提到的3個問題:

1)正則表達式或手動代碼?

瞭解/使用解析器生成器代替,例如ANTLR

2)這是一件好事還是壞事?如果從不使用代碼,將會有助於提高解析器的速度嗎?

這實在是一個「過早」的優化。它更好地簡單地得到一個快速的解析引擎。 ANTLR很不錯,我懷疑你是否會注意到不同之處。如果你堅持快速燃燒,請考慮LRSTAR。在過去的十年中,構建它的人對其生成的解析器進行了微優化,並且它們非常快。

考慮到您正在嘗試實現一種編程語言,我建議您擔心實際定義它的更大問題,構建一個工作解析器,並努力以實用的方式執行它(不管意味着解釋或編譯無關緊要)。鑑於您對解析業務的理解程度,我懷疑您確實沒有做好準備。你最好花一些時間學習編譯器如何工作,以便你有一個參考點。

3)題外話題:提高分析器的一些技巧?也許一個「預解析」文件,用計算機代碼(操作碼???)存儲語言代碼?

您可以通過預處理文本並將其存儲爲一組令牌來加快解析器的速度。你也可以通過在沒有改變的假設下存儲前面解析的結果來加速它(大型代碼系統中的大多數源文件即使可能重新編譯也不會改變)。您甚至可以將編譯後的代碼與源文本一起保存爲一些表示形式,以避免編譯它。 [我曾考慮過爲這些單獨的函數存儲編譯後的代碼;即使在編輯文件時,大部分功能都不會更改]。這些技巧都有問題:如何讓程序員和編輯合作設置所有這些?創建一個快速解析器要容易得多,而且你應該從那裏開始並在後期擔心這些花哨的技巧。

3
  1. 正則表達式無法比擬的括號 - 這是不可能的。 解析這種語言的一種方法是lex(tokenize)和yacc(parser) - 你可以在網上找到很多信息。

  2. 向解析器添加優化不太可能使解析速度更快,但可以提高生成的代碼的性能。道德判斷的好壞,我不知道它們在這裏的意思。

  3. 在源代碼中匹配模式並替換預編譯的優化代碼可以爲您提供改進的結果,但它是否加快了解析速度取決於模式出現在代碼中的頻率。

+0

是啊......我想起那個(這是手動編碼方法)。但關於問題2和問題3?你可以回答嗎? :) – 2012-02-29 11:29:00