SQLのキーワードを強調表示
先日、強調表示のやり方がわかったので、VerticalViewerにSQLの強調表示をつけてみました。
http://d.hatena.ne.jp/a-san/20070908
SQLの強調表示は、ある程度の字句解析をやらなければならないのですが、そういえば昔やったのでそれが使えそう。
手元に当時のソースはあるけれど、その後、いがぴょんによって拡張されているのでそれを使ってみます。:−)
http://hp.vector.co.jp/authors/VA027994/blanco/blancosqleditorplugin.html
むむ。結構、手が入っているし、ANSI-SQLの予約語も有用です。
ただそのままだとトークンの位置が取れないので、BlancoSqlTokenにfPosを追加。
あとはサクッと作れました。
強調部分は以下の通り。ついでに、SQL整形もメニューに追加。
/** 強調表示を設定する. */ void setHighlight(StyledDocument doc) { // SQL文を取り出す。 String text = ""; try { text = doc.getText(0, doc.getLength()); } catch (BadLocationException e) { e.printStackTrace(); return; // フツー、ココには来ないけれど、来るようならば色づけなどしない。 } // SQL文を字句解析し、字句ごとにぶった切る。 ArrayList tokens = null; try { tokens = fParser.parse(text); } catch (RuntimeException e) { //e.printStackTrace(); return; // 不完全なSQLだと起こりえる。 } // 一旦、すべての属性を消す doc.setCharacterAttributes(0, text.length(), PLANE, true); // トークンごとに色分けする。 for (int i=0; i<tokens.size(); i++) { BlancoSqlToken t = (BlancoSqlToken) tokens.get(i); int pos = t.getPos(); String str = t.getString(); switch (t.getType()) { case BlancoSqlTokenConstants.SPACE: // 空白、TAB、改行など break; case BlancoSqlTokenConstants.SYMBOL: // 記号. " <="のような2つで1つの記号もある。 break; case BlancoSqlTokenConstants.KEYWORD: // キーワード. "SELECT", "ORDER"など. str = str.toUpperCase(); if (Arrays.binarySearch(BlancoSqlConstants.SQL89_RESERVED_WORDS, str) >= 0) { doc.setCharacterAttributes(pos, str.length(), SQL89, true); } else if (Arrays.binarySearch(BlancoSqlConstants.SQL92_RESERVED_WORDS, str) >= 0) { doc.setCharacterAttributes(pos, str.length(), SQL92, true); } else if (Arrays.binarySearch(BlancoSqlConstants.SQL99_RESERVED_WORDS, str) >= 0) { doc.setCharacterAttributes(pos, str.length(), SQL99, true); } else if (Arrays.binarySearch(BlancoSqlConstants.SQL_FAMOUS_WORDS, str) >= 0) { doc.setCharacterAttributes(pos, str.length(), SQL_FAMOUS, true); } else { doc.setCharacterAttributes(pos, str.length(), KEYWORD, true); // ココには来ないはず System.out.println("keyword="+str); } break; case BlancoSqlTokenConstants.NAME: // 名前.テーブル名、列名など。ダブルクォーテーションが付く場合がある。 doc.setCharacterAttributes(pos, str.length(), NAME, true); break; case BlancoSqlTokenConstants.VALUE: // 値. 数値(整数、実数)、文字列など。 doc.setCharacterAttributes(pos, str.length(), VALUE, true); break; case BlancoSqlTokenConstants.COMMENT: // コメント. シングルラインコメントとマルチラインコメントがある。 doc.setCharacterAttributes(pos, str.length(), COMMENT, true); break; case BlancoSqlTokenConstants.END: // SQL文の終わり. break; case BlancoSqlTokenConstants.UNKNOWN: // 解析不可能なトークン. 通常のSQLではありえない。 doc.setCharacterAttributes(pos, str.length(), UNKNOWN, true); break; default: assert false: t.getType(); // ありえない } } }