2012-07-18 79 views
3

我有一個令牌OR:'OR';我用於評估布爾表達式(a == b OR a == c)我有另一個解析狀態縮寫的規則,它們在char列表AZ,AK,OR,GA ... 我發現的是ANTLR對狀態列表思維錯誤,或者應該是一個or令牌而不是解決antlr中的令牌衝突

stateName 
    : CHAR CHAR (','|EOF) ->^(STATE CHAR+) 
    ; 

我怎麼會去解決這種不確定性?

這裏有一些規則,我試圖解析

  • THEN STATE_LICENSE AL,AK,AS,AZ,AR,CT,DE,DC,FM,佛羅里達州,喬治亞州,GU,HI, ID,IL,IN,IA,KS,KY,LA,ME,MH,MD,MA,MI,MN,MS,MO,MT,NE,NV,NH,NJ,NM,NY,NC,ND,MP, OH,OK,OR,PW,PA
  • IF 1198 == 「X」 或1190!= 「X」 則禁止800
  • IF 801> = 「1000000」 THEN DISPLAY_ERROR「這+ 00 +昂貴。+轉到+和+得+便宜+一個+ !!!」

這裏是我使用

grammar PointFieldRule; 


options 
{ 
//language = 'CSharp3'; 
output=AST; 
ASTLabelType=CommonTree; 
} 
tokens{ 
STATE; 

} 


rule : ifExpression? actionExpression EOF! 
; 
ifExpression 
    :'IF'! logicalConditionExpression 
    ; 

logicalConditionExpression 
    : booleanAndConditionExpression (BigOR^ booleanAndConditionExpression)* 
    ; 


booleanAndConditionExpression 
    : logicalCondition (BigAND^ logicalCondition)* 
    ; 

BigAND : 'and'|'AND'; 

logicalCondition 
    : booleanAndCondition (OR^ booleanAndCondition)* 
    ; 

OR:'||'; 

booleanAndCondition 
    : evalCondition (AND^ evalCondition)* 
    ; 

AND: '&&'; 

evalCondition 
    : FieldID OPERATOR^ (FieldID|STRING) 
    ; 

actionExpression 
    : 'THEN'! (actionMessage | fieldAction | stateAction) 
    ; 

actionMessage 
    : ('DISPLAY_WARNING' | 'DISPLAY_ERROR')^ STRING 
    ; 

fieldAction 
    : ('DISABLE' | 'REQUIRED')^ FieldID (','! FieldID)* 
    ; 


stateAction 
    : 'STATE_LICENSE'^ stateName+ //(','! stateName)* 
    ; 

FieldID 
    :'0'..'9'+; 

/* item : FIELD 
    | CHAR CHAR 
    ; 
*/ 
//class csharpTestLexer extends Lexer; 

stateName 
    : CHAR CHAR (','|EOF) ->^(STATE CHAR+) 
    ; 
CHAR: ('a'..'z'|'A'..'Z') 
    ; 

WS : (' ' 
| '\t' 
| '\n' 
| '\r') 
{ $channel = HIDDEN; } 
//{ $channel = Hidden; } 
; 



OPERATOR 
    : '==' 
    | '!=' 
    | '<=' 
    | '>=' 
    | '<' 
    | '>' 
    | 'TD' 
    | 'FD' 
    | 'PD' 
    | 'TY' 
    | 'LY' 
    | 'TM' 
    | 'LM' 
    | '+(DELTA%)>' 
    | '-(DELTA%)>' 
    | '+(DELTA)>' 
    | '-(DELTA)>' 
    | 'LIKE' 
    ; 


STRING 
    : '"' (ESC_SEQ | ~('\\'|'"'))* '"' 
    ; 


fragment 
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ; 

fragment 
ESC_SEQ 
    : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') 
    | UNICODE_ESC 
    | OCTAL_ESC 
    ; 

fragment 
OCTAL_ESC 
    : '\\' ('0'..'3') ('0'..'7') ('0'..'7') 
    | '\\' ('0'..'7') ('0'..'7') 
    | '\\' ('0'..'7') 
    ; 

fragment 
UNICODE_ESC 
    : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT 
    ; 

//fragment 
BigOR: 'or'|'OR'; 

回答

4

詞法分析器從解析器獨立創建令牌gramar。因此,解析器在給定點可能「需要」兩個CHAR標記並不重要,如果詞法分析器「看到」文本"OR",它將始終創建一個BigOR標記。對此你無能爲力。

在你的情況,你可以簡單地讓stateName匹配兩個CHAR記號,或單OR令牌是這樣的:

stateName 
: name (','|EOF) ->^(STATE name) 
; 

name 
: CHAR CHAR 
| BigOR 
; 

解析輸入"THEN STATE_LICENSE AL,OR,PA"會導致以下AST:

enter image description here

請注意,OR是一個單一的令牌,與其他類型不同,其類型爲CHAR並且其字符爲se parated。如果你希望你的OR節點會那樣,也做這樣的事情:

name 
: CHAR CHAR 
| BigOR  -> CHAR[""+$BigOR.text.charAt(0)] CHAR[""+$BigOR.text.charAt(1)] 
; 

導致:

enter image description here

或者,如果你想在兩個不同的字符將被連接起來,這樣做:

name 
: (CHAR CHAR | BigOR) -> CHAR[$text] 
; 

導致:

enter image description here