2012-09-20 88 views
4

解析器通常如何處理自動完成?解析器自動完成整合

如果我們舉一個例子,在那裏我通過以下的解析器:

"int i=2" 

那麼對於這個自動完成選項可能包括:

"int i=2," 
"int i=2;" 

應自動完成是解析器的一部分?

如果沒有,那麼在基於事件的解析器的情況下,我猜解析器將發出包含在解析器的狀態機的分支是可能的IDS的事件。然後自動完成模塊將知道爲每個這樣的狀態打印什麼。

對於基於樹的解析器,解析器會返回一個樹形結構,其中包含以某種方式現有的那些分支。

這是如何完成的?當需要自動完成時,哪種類型的解析器最適合處理命令字符串?

回答

8

可以讀取先行集(即,令牌類型的可接受如下)從LR(k)文法,但這樣的文法往往是巨大的。壓縮語法的各種形式(其中LALR(1)可能仍然是最常見的)使得lookahead集合不那麼精確(它總是包含有效的標記類型,但也可能包含無效的標記)。表視圖集中的無效標記類型也可以通過表壓縮和故意包含錯誤生成(包含在內以改進錯誤消息)來引入。

讀取先行從遞歸下降語法分析器設置可以是麻煩,部分原因是因爲這樣的解析器通常開編碼,而不是依賴於轉換表。然而,至少在理論上,一個LL(k)語法也有可能計算一個前瞻集,儘管它也可能變得不精確。

最有趣的自動完成,不過,是不是標點符號,而且符號。一個語法不足以告訴你在給定點上哪些名稱在範圍內,儘管它可能能夠告訴你哪些類型的名稱是可行的。您需要掛鉤到符號表才能獲得準確的自動填充信息。在標識符可以在聲明之前使用的語言中,這可能更加棘手,儘管解析器很可能在某處保留了未解析名稱的列表。

使用解析器生成自動完成信息的另一個困難是,解析器傾向於爲語法正確的程序進行優化,並且可以不檢測語法錯誤之後在所有工作。對於IDE用戶來說,這可能會讓人感到惱火;輕微的標點符號錯誤會禁用自動完成,直到錯誤被追蹤並修復。 (就我個人而言,我發現這樣的系統過於分散注意力;我寧願把重點放在我現在寫的東西上,而不是在代碼的其他部分丟失括號。)

IM(H)O,it最好使用類似於packrat解析的東西來在插入點處選擇足夠的上下文以獲得關於可能遵循的內容的合理概念。如果您有權訪問完整的數據類型聲明,請使用它們,但始終存在將文本中看起來像符號的任何內容放入預見集(儘管這也可能會讓人惱火)的後備方法。

祝你好運,無論如何。