2013-04-24 60 views
0

我使用的是JavaCC模擬SQL語法的一小部分,並且在定義密碼時遇到問題。JavaCC:定義*密碼*令牌或語法規則

我書面方式語法規則的

CREATE USER user_name IDENTIFIED BY a_password 

語句,我被困。由於密碼可以與任何類似asdkj*[email protected]#[email protected]%^%ASDjnkj,[email protected]#&等匹配。請注意,在Oracle中,輸入不帶單引號(')的密碼是完全合法的。如果引號是強制性的,我可以很容易地解決這個問題,但不幸的是他們不是。

我試過許多方法來定義這個密碼令牌/語法規則,但正如我預料它沒有工作,我已經試過了最新的規則是:

TOKEN : { 
< S_PASSWORD: (<DIGIT> | <LETTER> |<S_PASSCHAR>)+ > 
| <#S_PASSCHAR : "!"|"@"|"#"|"$"|"%"|"^"|"&"|"*" > 
| <#LETTER: ["a"-"z", "A"-"Z", "_"]> 
| <#DIGIT: ["0" - "9"]> 
} 

但由於<S_PASSWORD>可以匹配任何內容,我在前面定義的任何其他標記將匹配它,我總是得到一個JavaCC的警告是這樣的:

警告:「#」不能作爲一個字符串文字令牌在行33515匹配,第13列。它將被匹配爲< S_PASSWORD>。

我的朋友也有類似的建議,但他們也沒有工作。 有人可以幫助我嗎?

回答

1

假設有一些詞法分析密碼開始和結束的方式,您可以使用詞法狀態。例如,如果序列IDENTIFIED BY後面只有一個空格後跟一個密碼,那麼您將創建一個狀態機,以便IDENTIFIED從DEFAULT轉換到S0。在S0中,跳過空格,BY跳轉到S1。在S1中,跳過空格並且一系列密碼字符是一個PASSWORD標記;密碼令牌轉換回默認值。當然,這隻有在IDENTIFIED BY只能跟隨一個密碼後纔有效。同樣在S0中,你需要能夠處理所有正常的東西,所以大多數令牌規則應該適用於狀態S0和DEFAULT,但是應該轉換爲DEFAULT。有關詞彙狀態的更多信息,請參閱FAQ。

如果BY只有後面跟着一個密碼,那麼它更容易,因爲你不需要S0。


編輯

這裏有一些例子規則。如果關鍵字BY只會被後面一個密碼,你只需要兩個狀態

TOKEN : { <BY : "BY"> : S1> 
<S1> TOKEN : { <PASSWORD : (<PASSWORDCHAR>)+ } : DEFAULT } 
<DEFAULT, S1> : SKIP { " " } // Stays in the same state. 

如果你可以使用標識,然後通過那麼你就需要三個州

<DEFAULT, S0> TOKEN : { <CREATE : "CREATE"> : DEFAULT } // And similar for most token rules. 
<DEFAULT, S0> TOKEN : { <IDENTIFIED : "IDENTIFIED"> : S1 } 
<S0> TOKEN : { <BY : "BY"> : S1> // BYs that follow IDENTIFIED 
<DEFAULT> TOKEN : { <BY : "BY"> : DEFAULT } BYs that don't follow IDENTIFIED. 
<S1> TOKEN : { <PASSWORD : (<PASSWORDCHAR>)+ } : DEFAULT } 
<DEFAULT, S0, S1> : SKIP { " " } // Stays in the same state.