2014-01-15 60 views
1

我正在嘗試編寫一個布爾表達式語法,它可以將WHITE_SPACE作爲隱式邏輯AND處理。例如「A B」意味着「A和B」。如何解決布爾表達式語法中電話號碼的歧義

但是,我還想將美國格式的電話號碼視爲一個單獨的toke,例如(123)456-7890。我的語法可以覆蓋大多數情況,但在AREA_CODE上仍然面臨着語法歧義。

這是我的語法:

grammar myBooleanExpr; 

options 
{ 
    language = Java; 
    output = AST; 
} 

tokens { 
    AND; 
} 

fragment DIGIT : '0'..'9'; 
fragment AREA_CODE : LPAREN DIGIT+ RPAREN; 
fragment NUMBER : (DIGIT | '-')+; 
LPAREN : '(' ; 
RPAREN : ')' ; 
WS : (' ' | '\t' | '\r' | '\n')+ { $channel = HIDDEN; }; 
L_AND: 'AND'| 'And' | 'and'; 
OR : 'OR' | 'Or' | 'or'; 
NOT : 'NOT' | 'Not' | 'not'; 
NAME : (~(' ' | '\t' | '\r' | '\n' | '(' | ')' | '"'))*; 
PHONE : AREA_CODE ' '? NUMBER?; 
QUOTED_NAME : '"'.*'"'; 

expression : orexpression; 
orexpression : andexpression (OR^ andexpression)*; 
andexpression : notexpression (L_AND? notexpression)* -> ^(AND notexpression+); 
notexpression : NOT^ atom | atom; 
atom : NAME | PHONE | QUOTED_NAME | LPAREN! orexpression RPAREN!; 

輸入與預期輸出:

(123)456-7890 - >(123)456-7890 //單令牌

(123)abc - > 123 AND abc //兩個標記

(123456)789 - > 123456 AND 789 //兩個標記###當前 不合格

(12 34) - > 12和34個//兩個令牌###目前 失敗

(123)456-AAAA - > 123和456-AAAA // 2個###當前 失敗令牌

ABC EFG和HIJ - > ABC和EFG和HIJ //三個令牌

這是我很難理解input.LA(1)左右的使用。非常感謝,如果有人可以在這個問題上跳躍幫助我。

回答

1

我認爲你正試圖把太多的詞法規則。分析這樣的電話號碼需要更多的靈活性,例如,一個空格字符可能不夠,標籤怎麼樣?相反,您應該像往常一樣抽出所有單個令牌(數字,標點符號等),並在解析器運行時擁有語法樹後進行語義檢查。

您可以決定兩個令牌之間的空間是正確還是可以解釋爲邏輯運算(此處爲AND)。解析器和詞法分析器都不知道,它取決於上下文。這就是爲什麼你不能使這種語法不受歧視的原因。