2010-10-02 42 views
5

我在ANTLRWorks 1.4中有以下語法。我在文字冒險遊戲創作者中玩弄解析器的實現,在這裏用戶將爲他的遊戲指定各種允許的命令。是否有可能將「關鍵字」也視爲「非關鍵字」的語法?

grammar test; 

parse  : cmd EOF; 


cmd   : putSyn1 gameObject inSyn1 gameObject; 

putSyn1  : Put | Place | Drop ; 

inSyn1  : In | Into | Within; 


gameObject : det obj; 

det   : The | A | An | ; 

obj   : Word obj | Word; 


Space  :  (' ' | '\t' | '\r' | '\n'){$channel=HIDDEN;}; 
Put   : 'put'; 
Place  : 'place'; 
Drop  : 'drop'; 
In   : 'in'; 
Into  : 'into'; 
Within  : 'within'; 
The   : 'the'; 
A   : 'a'; 
An   : 'an'; 

Word  : ('a'..'z' | 'A'..'Z')+; 

我只是感受到了各種微妙之處(像我做的here)。

這一次,使用ANTLR,我想知道如果我可以分析的輸入,如:

put wood in fire place 

也就是說,「木」和「火的地方」都高於gameObjects。然而,「地點」也是「放」的同義詞。所以這同樣有效:

place wood in fire place 

當試圖解析最後的「地點」標記時,ANTLR給了我一個NoViableAltException。我想將「火場」識別爲一個遊戲對象。

在ANTLR中,這種事情是可能的嗎?語法可能嗎?

另一方面,我正在開發一個手動實現,它使用一個奇怪的自定義數據結構,包含NFA,Dictionary和whatnot。但是我仍然需要更多的時間,並且必須犧牲一些腦細胞來設計所需的搜索插入算法。

但是,如果這是可能的ANTLR,我可以使用生成的C#文件,呀?

+0

也許你的例子只是一個例子,但是,對於這個特別的,你可以使用'壁爐'(一個字)而不是'火的地方' – 2010-10-02 14:33:51

+0

嗯,這是一個文字冒險_creator_,而我希望能夠讓用戶在他創建的房間中擁有多個文字遊戲對象。 – Rao 2010-10-02 14:36:43

回答

4

當然。 PL/1是著名的沒有任何的保留字,例如,你可以使用關鍵字(例如,IF)作爲變量名的任何地方它不需要爲關鍵字:

IF IF = 1 THEN ELSE=3; ELSE END=4; 

構建一個解析器這是否更難?你不能在詞法分析器中「簡單地」這樣做,因爲它不知道標識符可能是關鍵字的上下文。

有幾種出路。當找到像實體這樣的標識符時:

1)讓詞法分析器詢問解析器,「你現在想要關鍵字嗎?」。在這種情況下,生成一個關鍵字。讓解析器在這裏合作可能會很困難。也可能是解析器不知道,因爲它必須看到更多的輸入來決定。考慮Fortran的著名的格式聲明:

 FORMAT (A1, I2, ...) X 

,當你看到「格式化」,如果它是一個關鍵字,或標識你不能告訴;你必須先向前掃描以檢查X.如果X只是語句的結尾,則FORMAT字是數組標識符的名稱;如果X是陳述結束,那麼它是一個FORMAT關鍵字和語句。

2)發出關鍵字(如果標識符匹配一個)和標識符,並使解析器嘗試兩者。大多數解析器都不能很好地處理這個問題,但如果設計合理,GLR parsers可以以合適的方式處理這個問題。這通過推入解析器的預見功能來輕鬆處理FORMAT問題。 (ANTLR不是GLR,我們的DMS Software Reengineering Toolkit有這樣一個GLR解析器,我們使用這個技巧很多)。 3)將所有類似標識符的東西放入散列表中。使用遞歸下降解析器(ANTLR是一個);當分析器需要一個關鍵字時,它只是檢查它獲得的標識符以驗證它是它需要的關鍵字。如果它不需要關鍵字,它只是使用該標識符作爲標識符。我不知道如何用ANTLR來實現這個技巧,因爲我不使用它。這不會很好地處理「無法預見」的情況。

+0

感謝您的好回答。選項2)在我的手動實現嘗試中有點不同。 – Rao 2010-10-02 18:39:30

1

我會用詞法分析器而不是解析器來處理這樣的事情 - 讓詞法分析器做一個「最大的蒙克」,因此它將「火場」識別爲一個單一的標記,並且只將「地點」識別爲如果它沒有立即以「火」開頭,則爲單獨的標記。

因此,解析器不必注意輸入中相同的字符序列恰好構成完全分離的兩個令牌的全部或部分。

+0

我需要考慮這一點。目前(沒有從ANTLR的角度考慮),我的目標是僅識別命令語法,例如「GO放入GO」,並允許GO成爲任何東西。然後每個GO將與房間中存在的物體相匹配。也就是說,實際遊戲對象的名字將不會出現在語法文件中。 – Rao 2010-10-02 14:41:56

相關問題