2017-03-27 26 views
1

我已經定義了一個運營商#如何在Prolog中捕獲語法錯誤?

:- op(500, yfx, #). 

我寫了下面的規則來檢查,如果一個術語是合式:

valid(X):- integer(X). 
valid(X # Y):- valid(X), valid(Y). 

我想寫一個謂語check/1都將返回true如果它的參數是有效的,否則返回false。我寫到:

check(Exp):- catch(valid(Exp), error(syntax_error(_),_), fail), !. 

當Exp是格式正確時,它返回true。然而,當它是不合法的不抓住語法錯誤:

?- check(5 ## 6). 
ERROR: [Thread pdt_console_client_0_Default Process] Syntax error: Operator expected 
ERROR: [Thread pdt_console_client_0_Default Process] check(5 
ERROR: [Thread pdt_console_client_0_Default Process] ** here ** 
ERROR: [Thread pdt_console_client_0_Default Process] ## 6) . 

我使用SWI-Prolog version 7.4.1 for amd64

如何發現語法錯誤並在出現錯誤時使check返回false?

回答

3

在你的情況下,問題是check/1只稱爲如果第一 位置輸入一個有效的Prolog的目標

因此,當已經被調用check/1,語法絕對是至少一個有效的Prolog  來看,即使它可能不是從視圖的check/1本身的點纔有意義。如果語法  有效,Prolog的  頂層已經引發 錯誤,甚至沒有調用  check/1

因此,爲了更好地控制語法問題,您需要自己閱讀條款

有幾種方法可以做到這一點。一個簡單的方法是使用read/1。例如:

 
?- catch(read(X), Error, true). 
|: check(5##6). 

Error = error(syntax_error(operator_expected), stream(user_input, 8, 7, 347)). 

通過這種方式,你基本上可以建立自己的頂層,它爲您提供了這樣 問題更多的控制。另見read_term/2和幾個相關的謂詞幫助解決這個問題。

與這些問題有關的一個重要的選項是variable_names/1:它產生一個對應的Prolog之間 變量及其原子,這樣就可以報告可讀 綁定。這是最高級別的重要組成部分,ISO標準化最近取得的進展非常有助於實現這些功能。也許,在適當的時候,我們將能夠在  Prolog中編寫便攜式頂層,可用於多個 系統。有很多應用程序可以從中受益,其中之一就是其中的一個。