簡體   English   中英

使用解析器重新同步處理PLY.yacc錯誤

[英]PLY.yacc error handling using parser resynchronization

我正在嘗試在解析過程中實現用戶友好的語法錯誤處理。 根據我在官方PLY 文檔中的觀察。 一種方法是在第一個SyntaxError發生時引發異常並終止解析。 但是,正如文檔所建議的,我想做類似的事情來使用解析器重新同步技術。

該文件說:

處理語法錯誤的最完善的方法是編寫包含錯誤標記的語法規則。 例如,假設您的語言對這樣的打印語句具有語法規則:

 def p_statement_print(p): 'statement : PRINT expr SEMI' ... 

為了解決表達錯誤的可能性,您可以編寫一個附加的語法規則,如下所示:

 def p_statement_print_error(p): 'statement : PRINT error SEMI' print("Syntax error in print statement. Bad expression") 

我有一個這樣的語法摘錄:

def p_operation(self, p) -> None:
    '''
    operation : unaryOperation
              | binaryOperation
    '''

def p_unaryOperation(self, p) -> None:
    '''
    unaryOperation : unaryOperation L_SQUARE_BRACKET projection R_SQUARE_BRACKET
                   | RELATION_NAME
    '''

def p_projection(self, p) -> None:
    '''
    projection : multipleAttributes
               | attribute
    '''

def p_multipleAttributes(self, p) -> None:
    '''
    multipleAttributes : projection COMMA attribute
    '''

def p_attribute(self, p) -> None:
    '''
    attribute : ATTRIBUTE
    '''

我不確定如何定義包括error令牌的新規則。 我應該用error令牌替換每個非終端嗎?

期待收到您的答復! 非常感謝你的幫助

您絕對不應該為每個非終端添加錯誤產生。

當存在某些令牌時,重新同步將正常工作,這些令牌通常會將解析上下文重置為已知狀態。 在具有清晰的語句結尾標記的語言中(在您引用的示例中為分號),該標記可以很好地用作重新同步點。 丟棄文本直到下一個分號,然后再從那里進行解析不會在100%的時間內起作用,但是在許多情況下它確實起作用。

括號和括號也可以用作重新同步點,但是啟發式方法不那么可靠,因為許多語法錯誤是括號或括號不匹配的結果。 例如,掃描缺少的右方括號可能會丟棄整個輸入。

在沒有明確的語句定界符的語言中,重新同步更為復雜,包括像Python這樣的語言,其中的換行符僅在不嵌套在括號內的情況下才終止語句。 丟棄最多換行符可能會起作用,但是您可能必須處理掃描程序和解析器之間的反饋,該反饋確定何時將換行符作為令牌發送以及何時將其作為空白符跳過。

縮進不一致可能是有用的重新同步觸發器,但有幾點警告。 首先,您一定不能拒絕帶有“誤導”縮進的有效輸入,因此觸發器在重新同步過程中比在正常解析過程中需要更加敏感。 其次,跟蹤不一致的縮進肯定需要解析器->掃描器反向通道。 因此,它比簡單的緊急恢復要花更多的時間,但它可能是有效的。

最重要的是,只有很少的通用算法可以實現良好的錯誤報告和恢復。 您需要基於語言的句法本質來制定策略。

理想情況下,您將希望通過檢查解析器對常見錯誤的響應來優化代碼,但是只有在進行實際部署並看到常見錯誤之后才能真正做到這一點。 因此,我能提供的最佳建議是從一個簡單的恢復策略開始,看看它如何處理不同的語法錯誤,尤其是您偶然創建的語法錯誤(或您的朋友和合作者的語法錯誤)。 保留遇到的各種語法錯誤的存檔,可用於測試對診斷和恢復代碼的改進。 別指望它是完美的,因為這是一個難題,但是請盡一切可能使它更准確。

暫無
暫無

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

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