Diary?

2009-06-23
Tue

(17:52)

2.x 系統の Python 版 ANTLR で生成したコードにマルチバイト文字を含んだファイルを食わせると、以下のようなエラーが出ることがある。

File "<path/to/lexer>", line XX, in nextToken
    elif la1 and la1 in 
        u'\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\t\n\u000b\u000c\r\u000e\u000f
        \u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d
        \u001e\u001f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]
        ^_`abcdefghijklmnopqrstuvwxyz|}~\u007f':
TypeError: 'in <string>' requires string as left operand

これはファイル内のマルチバイト文字が \u0000..\001f の間に収まっていないことに起因する。諸事情により ANTLR では字句・構文解析で需要可能な文字の集合を options 節の charVocabulary で指定しないと、デフォルトで上記のエラーメッセージにある範囲の文字しか受け付けない。まあ、 charVocabulary = '\u0000'..'\uFFFE'; と指定しておけば、まず大丈夫だ。

ちなみに Python の処理系の方から UnicodeWarning が出るようになったりするが、その場合も codes モジュールの getreader 関数でファイルオブジェクトをラップして unicode で文字をを読み取れるようにすれば凌げる。確か Python 3.0 以降ではファイルを開くときにエンコーディングを指定できるので、もしも Python 3.0 以降で ANTLR が使えるならそっちを使った方がいい。

Creative Commons
この怪文書はクリエイティブ・コモンズ・ライセンスの元でライセンスされています。引用した文章など Kuwata Chikara に著作権のないものについては、それらの著作権保持者に帰属します。