2012-12-24 103 views
1

使用GNU bison時,匹配生產後是否可以不做任何事情,然後檢查是否可以使用其他規則來減少相同的令牌序列?基本上,我在找的是與此類似:忽略yacc中的匹配生產

iexpr: VARIABLE { if (condition) { 
        /*some action */ 
        } 
        else { 
        /*pushback read symbol, and check if other pattern can 
         be matched */ 
        } 
       } 
fexpr: VARIABLE { } 

感謝

+0

我很想知道你是如何滿足這個要求的。我不知道這種野牛的設施。如果控制執行你的代碼,這意味着野牛已經爲你匹配了模式。即使你以某種方式破解它並試圖實現你的目標,野牛最終會在下一次迭代時匹配相同的規則。我會建議適當地定義語法。如果你告訴你正在解析的內容,我可能會幫助你。 – Icarus3

+0

@AshishMahamuni:我基本同意你的評價。我無法回答OP,但是一個類似可能有用的上下文是一種冗長的語言(SQL),您希望允許將關鍵字用作標識符。我已經看到了一些操作,以便在檢測到錯誤時,如果令牌當前是關鍵字,則會使用標記類型的IDENTIFIER而不是關鍵字重試語法。這很有效,還有一些地方你會遇到麻煩。 –

+0

請正確使用術語。這些是*製作,*不是'模式'。 – EJP

回答

1

好了,你可以用btyacc做到這一點 - 這並回溯一個yacc的變種:

iexpr: VARIABLE [ if (!condition) 
        /* this parse was wrong, backtrack and try something else */ 
        YYERROR; ] 
       { /* some action */ } 
fexpr: VARIABLE { /* some other action */ } 

但評論者指出的那樣,試圖做的類型檢查的解析器是一個壞主意,只是導致不必要的複雜語法和錯誤的混淆錯誤消息。

取而代之,只需要爲所有類型的表達式規定單個(一套)expr規則,並在生成的分析樹上單獨進行類型檢查。你甚至不需要構建整個分析樹併爲此保留它;您可以立即構建小塊的分析樹並對它們進行類型檢查,然後在進一步解析之前丟棄不需要的信息。類似於:

expr: expr '+' expr { 
    Typecheck('+', $1, $3); /* make sure operand types are appropriate for an add */ 
    $$ = BuildBinopCode('+', $1, $2); /* build some code to add two things */ 
} 
1

您應該能夠使用YYBACKUP功能這一點。