2011-11-27 42 views
2

t_error()函數用於處理檢測到非法字符時出現的lexing錯誤。我的問題是:我怎樣才能使用這個函數獲得更多關於錯誤的具體信息?類似錯誤類型,錯誤出現在哪個規則或段中,等等。詞法分析器錯誤處理PLY Python

回答

1

Ply在名爲cpp.py的文件中包含示例ANSI-C樣式詞法分析器。它有怎樣出t_error()中提取某些信息的示例:

def t_error(t): 
    t.type = t.value[0] 
    t.value = t.value[0] 
    t.lexer.skip(1) 
    return t 

在此功能,您還可以訪問詞法分析器的公共屬性:

  • LINENO - 當前行號
  • lexpos - 輸入字符串中的當前位置

也有不列爲公開,但可以提供一些有用的診斷一些其他屬性:

  • lexstate - 當前詞法狀態
  • lexstatestack - 詞法分析器的棧規定
  • lexstateinfo - 國家信息
  • lexerrorf - 錯誤的規則(如果有的話)
3

一般情況下,只有提供給t_error()函數非常有限的信息。作爲輸入,它接收一個令牌對象,其中的值已被設置爲剩餘的輸入文本。該文本的分析完全取決於你。您可以使用t.lexer.skip(n)函數讓詞法分析器跳過一定數量的字符,這就是它。

除了輸入字符與任何已知標記的正則表達式不匹配之外,沒有「錯誤類型」的概念。由於詞法分析器與解析器分離,因此沒有直接的方法可以獲取有關解析引擎狀態的任何信息,或找出正在解析哪些語法規則。即使你可以獲得狀態(這將只是LALR狀態機的基本狀態號),但它的解釋可能會非常困難,因爲解析器可能處於匹配幾十個可能的語法規則的中間階段,尋找reduce動作。

我的建議如下:如果您需要t_error()函數中的其他信息,則應該設置某種在代碼的詞法分析器和分析器組件之間共享的對象。您應該明確地讓編譯器的不同部分根據需要更新該對象(例如,它可以根據特定的語法規則進行更新)。

正如一邊,對於壞的標記通常只有很少的行動路線。基本上,你得到的輸入文本不包含任何已知的語言字母部分(例如,沒有已知的符號)。因此,甚至沒有任何類型的標記值可以提供給解析器。通常情況下,唯一的行動方式是報告錯誤的輸入,並將其排除並繼續。

作爲Raymond答案的後續,我也不建議修改t_error()中的詞法分析器對象的任何屬性。