2010-08-02 76 views
4

我試圖建立一個解釋用戶輸入的文本,搜索引擎式的語法。它將支持AND,OR,NOT和ANDNOT布爾運算符。我幾乎所有的工作,但我想添加一個規則,隱式引用的字符串之外的兩個相鄰的關鍵字被視爲在一個AND子句。例如:(左,右)ANTLR - 隱和令牌在樹

奶酪和餅乾=奶酪和餅乾

(上下),或=(上下)OR(左,右)

貓狗「大肚子豬」 =貓與狗‘大肚子豬’

我在與最後一個麻煩,我希望有人能指出我在正確的方向。這是我的* .G文件迄今爲止,並請很好,我ANTLR經驗涵蓋不到一天的工作:

grammar SearchEngine; 

options { language = CSharp2; output = AST; } 

@lexer::namespace { Demo.SearchEngine } 
@parser::namespace { Demo.SearchEngine } 

LPARENTHESIS : '('; 
RPARENTHESIS : ')'; 

AND : ('A'|'a')('N'|'n')('D'|'d'); 
OR  : ('O'|'o')('R'|'r'); 
ANDNOT : ('A'|'a')('N'|'n')('D'|'d')('N'|'n')('O'|'o')('T'|'t'); 
NOT : ('N'|'n')('O'|'o')('T'|'t'); 

fragment CHARACTER : ('a'..'z'|'A'..'Z'|'0'..'9'); 
fragment QUOTE  : ('"'); 
fragment SPACE  : (' '|'\n'|'\r'|'\t'|'\u000C'); 

WS  : (SPACE) { $channel=HIDDEN; }; 
PHRASE : (QUOTE)(CHARACTER)+((SPACE)+(CHARACTER)+)+(QUOTE); 
WORD : (CHARACTER)+; 

startExpression : andExpression; 
andExpression : andnotExpression (AND^ andnotExpression)*; 
andnotExpression : orExpression (ANDNOT^ orExpression)*; 
orExpression  : notExpression (OR^ notExpression)*; 
notExpression : (NOT^)? atomicExpression; 
atomicExpression : PHRASE | WORD | LPARENTHESIS! andExpression RPARENTHESIS!; 

回答

6

因爲你而治之具有可選的關鍵字,你應該創建一個虛構的AND-令牌並使用重寫規則在該樹中「注入」該令牌。在這種情況下,你不能使用ANTLR的短手^根運算符。您將不得不使用->重寫操作符。

andExpression應該是這樣的:

andExpression 
    : (andnotExpression  -> andnotExpression) 
    (AND? a=andnotExpression -> ^(AndNode $andExpression $a))* 
    ; 

這(或許隱蔽)符號的詳細描述在第7章中給出,部分重寫規則中的子規則,由173-174頁The Definitive ANTLR Reference特倫斯帕爾。

我跑了一個快速的測試,看看是否語法產生新andExpression規則正確的AST。解析字符串cat dog "potbelly and pig" and FOO後,將生成的解析器產生以下AST:

alt text http://img580.imageshack.us/img580/7370/andtree.png

注意,AndNodeRootimaginary tokens

如果你想知道如何創建AST上面圖片中,看到這個線程:Visualizing an AST created with ANTLR (in a .Net environment)

編輯

當解析兩個one two three(one two) three,將創建下列AST:

alt text http://img203.imageshack.us/img203/2558/69551879.png

和解析(one two) OR three時,以下是AST創建:

alt text http://img340.imageshack.us/img340/8779/73390353.png

這似乎是在所有情況下的正確方法。

+0

謝謝!那就是訣竅。我的後續關注(現在已被刪除,以及您的編輯被指向)是由於某些封閉的C#代碼中的錯誤。 – user409108 2010-08-03 18:31:23

+0

@highbeammeup,很高興聽到這一點。不客氣! – 2010-08-03 18:39:29

+0

@BartKiers Iam理解你的重寫規則有問題,儘管我在這裏有參考。你能解釋爲什麼需要(..)(..)部分和美元操作員做什麼? – 2012-11-28 13:31:10