2012-11-15 32 views
4

我們試圖生成(在guile中)一個解析器和一個從字符串中讀取字符而不是標準輸入的詞法分析器。Scheme - LALR解析器生成 - 從字符串輸入

我們開始修改在 http://code.google.com/p/lalr-scm/source/browse/trunk/calc.scm?r=52

包含在代碼計算器例子的問題似乎是以下行:

(let* ((location (make-source-location "*stdin*" 
(port-line (current-input-port)) 
(port-column (current-input-port)) -1 -1)) 

我們試圖定義一個新的輸入端口:

(let* ((location (make-source-location "*stdin*" 
(port-line (open-input-string program)) 
(port-column (open-input-string program)) -1 -1)) 

和變量程序被定義爲這樣:

(define program 
"int x = 2; 
int y = 0; 
y= x*(2+3);" 
)  

但它不起作用,它仍然等待標準輸入字符。

該文件缺乏細節,所以我們無法弄清楚我們如何解決這個問題。

謝謝

+1

Chris Jester-Young關於Scheme中大部分I/O如何使用當前輸入端口作爲默認設置的說明現在就位於此處。你需要顯式地將你的字符串端口傳遞給每個I/O函數。請參閱「read-char」文檔,例如:http://www.gnu.org/software/guile/manual/guile.html#Reading。請注意,'port'參數在括號中:這是「可選參數」的文檔記號。 – dyoo

回答

2

您非常非常接近解決方案!好吧,有點。但這是一個開始。看看原代碼,圍繞你在哪裏修改它:

(let* ((location (make-source-location "*stdin*" (port-line (current-input-port)) (port-column (current-input-port)) -1 -1)) 
     (c (read-char))) 
    ...) 

在這裏,你改變了你所有的(current-input-port)到您的字符串端口(順便說一句,不叫一次open-input-string更多,因爲你創建一個新的字符串端口每次都有獨立的遊標),但它不是唯一實際使用(current-input-port)的地方。

你看到了嗎?它實際上在撥打(read-char)!該函數實際上需要一個端口參數,默認爲(current-input-port)

事實上,如果你看看上面和搜索的(read-char)(peek-char)情況下,你會發現,使用(current-input-port)是相當多烤到全make-lexer功能。所以你需要改變它。

我建議你指定的輸入端口到make-lexer功能:

(define* (make-lexer errorp #:optional (input (current-input-port))) 
    ... 

然後更改(read-char)(peek-char)所有情況下使用的輸入端口。也不要忘記設置make-source-location電話太:現在

(let* ((location (make-source-location "*stdin*" (port-line input) (port-column input) -1 -1)) 
     (c (read-char input))) 
    ...) 

,你可以使用(make-lexer errorp (open-input-string program)),它應該工作。 (我還沒有測試過。)

+0

嗨,謝謝你的回答,我試着照你說的去做,但是我得到這個錯誤:在表達式中(define *(make-lexer errorp#...))Unbound變量:define *。你有什麼想法是什麼問題? – user1826438

+0

您使用的是哪種版本的Guile?如果它是1.x,則需要在程序的頂部使用'(use-modules(ice-9 optargs))'。 (Guile 2.x已經有'define *'內置的了。) –

+1

我使用1.8,而我的一個朋友使用2.0,它的工作原理...所以今天晚上我會導入(使用模塊(冰 - 9個optargs))..非常感謝Chris! – user1826438