簡體   English   中英

解析不完整的語句時Antlr3下一個可用令牌

[英]Antlr3 next available tokens when parsing incomplete statement

我試圖為SQL的命令行客戶端實現簡單的自動完成。 我正在使用antlr在應用程序的其余部分中生成解析器,我想重用語法以使用自動完成功能。 我的想法是:-當用戶要求完成時解析不完整的語句(例如, select a from )-從解析器中獲取當他引發NoViableAltException時期望的令牌列表

然后,我想從此令牌列表中進行操作:如果(isreserved_word){提議完成}否則{通知用戶期望使用標識符}

原則上,這看起來是一個明智的主意(至少對我而言),我發現了這一點: http : //www.antlr.org/wiki/pages/viewpage.action? pageId =11567208 ,這使我確信

但是,在進行了一些測試之后,我意識到在state.following[state._fsp]並沒有很多令牌,例如對於create條目來說,它僅包含';' 當我的這部分語法看起來像:

root : statement? (SEMICOLON!)? EOF!;
statement : create | ...;
create : CREATE | ( TABLE table_create | USER user_create | ....);

所以我很困惑,看着生成的代碼:

    try {
        int alt6=16;
        alt6 = dfa6.predict(input);
        switch (alt6) {
            case 1 :
                {
                root_0 = (CommonTree)adaptor.nil();

                pushFollow(FOLLOW_create_in_statement1088);
                create8=create();

                state._fsp--;

                adaptor.addChild(root_0, create8.getTree());

                }
                break;
            case 2 :
            ...

因此,這對我來說很有意義:解析器嘗試讀取下一個標記,然后從該標記中找到(切換大小寫)下一個規則。 在我的情況下,由於沒有下一個標記,所以預測只是失敗了。 因此,從那里我了解到我需要破解一點,然后在模板和Java.stg查找以下代碼:

/** A (...) subrule with multiple alternatives */
block(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
// <fileName>:<description>
int alt<decisionNumber>=<maxAlt>;
<decls>
<@predecision()>
<decision>
<@postdecision()>
<@prebranch()>
switch (alt<decisionNumber>) {
    <alts:{a | <altSwitchCase(i,a)>}>
}
<@postbranch()>
>>

/** A case in a switch that jumps to an alternative given the alternative
 *  number.  A DFA predicts the alternative and then a simple switch
 *  does the jump to the code that actually matches that alternative.
 */
 altSwitchCase(altNum,alt) ::= <<
 case <altNum> :
   <@prealt()>
   <alt>
   break;<\n>
 >>

從那時起,我以為我要做的就是做自己的函數,將所有altNum放在預測調用之前的堆棧中。 所以我嘗試嘗試:/ * Yout}> * /

我期望得到一些不錯的令牌ID列表。 但是我完全沒有得到真正不同的東西。

因此,我真的迷失了自己,想知道是不是有一種無需手動操作即可提供此自動完成功能的簡便方法,還是我錯過了修改模板以添加自定義堆棧以在其中添加其他選項的方式?一條規則,以便在引發異常后可以閱讀

非常感謝你

抱歉,但不要直接使用解析器來自動完成。 如果沒有在生成的解析器中進行大量的手動更改(這需要熟悉的知識),則無法按預期工作的原因有幾個:

  • 您通常輸入不完整,除非您只有一種簡單的語言,否則由於解析器的回溯特性,您經常會發現自己處於意外的規則路徑中。 例如,如果您在規則中有多個替代項,如果只有一個額外的令牌可用,則第一個替代項將匹配,那么解析器將在嘗試所有其他替代項之前為您提供完全不同的令牌或比實際需要更多的令牌,否則不會失敗。

  • 僅在出現錯誤情況時,才能使用以下設置。 但是,可能沒有錯誤,也可能有錯誤,但是位置與插入符當前所在的位置(用戶期望自動完成框的位置)完全不同。

  • 跟隨集僅滿足您要顯示的一小部分信息(即關鍵字)。 但是,通常,如果您在FROM子句中(例如此處使用SQL語言),通常希望顯示數據庫中可能的表。 您不會從解析器中獲得這種類型的信息,僅僅是因為解析器沒有此類上下文信息。 但是,您得到的是“標識符”,它可以是表,函數名稱,變量或類似名稱中的任何一種。

我目前針對此類問題的方法是對輸入進行標記化,並在決策樹中應用領域知識。 也就是說,我遍歷輸入標記並根據我從語法中獲得的知識來決定要顯示的最重要的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM