0

JavaCC を使用して SQL 文法のごく一部をシミュレートしていますが、パスワードの定義に問題があります。

私は文法規則を書いています

CREATE USER user_name IDENTIFIED BY a_password

声明、そして私は立ち往生しています。asdkj*!@#パスワードは、!@%^%ASDjnkj、などと一致する可能性があるため、_ASDJLJK@#&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 > として一致します。

私の友人からも同様の提案がありますが、どちらもうまくいきませんでした。誰かがこれで私を助けることができますか?

4

1 に答える 1

1

パスワードの開始位置と終了位置を特定する字句的な方法があると仮定すると、字句状態を使用できます。たとえば、シーケンス IDENTIFIED BY の後にパスワードが続くスペースしか続かない場合、IDENTIFIED が DEFAULT から S0 に遷移するようにステート マシンを作成します。S0 では、スペースはスキップされ、BY は S1 に遷移します。S1 ではスペースはスキップされ、一連のパスワード文字は PASSWORD トークンです。PASSWORD トークンは DEFAULT に戻ります。もちろん、これは IDENTIFIED BY の後にパスワードしか続かない場合にのみ機能します。また、S0 ではすべての通常のものを処理できるようにする必要があるため、ほとんどのトークン ルールは S0 と DEFAULT の両方の状態に適用されますが、DEFAULT に移行する必要があります。字句状態の詳細については、FAQ を参照してください。

BY の後にパスワードのみが続く場合は、S0 が必要ないため、さらに簡単です。


編集

ルールの例をいくつか示します。キーワード BY の後にパスワードしか続かない場合は、2 つの状態だけが必要です。

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

IDENTIFIED の後に BY を使用できる場合は、3 つの状態が必要です。

<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.
于 2013-04-27T18:56:39.570 に答える