"tokenize" — Pythonソースのためのトークナイザ
*********************************************

**ソースコード:** Lib/tokenize.py

======================================================================

"tokenize" モジュールでは、Python で実装された Python ソースコードの字
句解析器を提供します。さらに、このモジュールの字句解析器はコメントもト
ークンとして返します。このため、このモジュールはスクリーン上で表示する
際の色付け機能 (colorizers) を含む 「清書出力器 (pretty-printer)」 を
実装する上で便利です。

To simplify token stream handling, all 演算子 and デリミタ (delimiter)
tokens are returned using the generic "token.OP" token type.  The
exact type can be determined by checking the second field (containing
the actual token string matched) of the tuple returned from
"tokenize.generate_tokens()" for the character sequence that
identifies a specific operator token.

第一のエントリポイントはジェネレータ(*generator*)です:

tokenize.generate_tokens(readline)

   The "generate_tokens()" generator requires one argument,
   *readline*, which must be a callable object which provides the same
   interface as the "readline()" method of built-in file objects (see
   section File Objects).  Each call to the function should return one
   line of input as a string. Alternately, *readline* may be a
   callable object that signals completion by raising "StopIteration".

   The generator produces 5-tuples with these members: the token type;
   the token string; a 2-tuple "(srow, scol)" of ints specifying the
   row and column where the token begins in the source; a 2-tuple
   "(erow, ecol)" of ints specifying the row and column where the
   token ends in the source; and the line on which the token was
   found.  The line passed (the last tuple item) is the *logical*
   line; continuation lines are included.

   バージョン 2.2 で追加.

An older entry point is retained for backward compatibility:

tokenize.tokenize(readline[, tokeneater])

   The "tokenize()" function accepts two parameters: one representing
   the input stream, and one providing an output mechanism for
   "tokenize()".

   The first parameter, *readline*, must be a callable object which
   provides the same interface as the "readline()" method of built-in
   file objects (see section File Objects).  Each call to the function
   should return one line of input as a string. Alternately,
   *readline* may be a callable object that signals completion by
   raising "StopIteration".

   バージョン 2.5 で変更: Added "StopIteration" support.

   The second parameter, *tokeneater*, must also be a callable object.
   It is called once for each token, with five arguments,
   corresponding to the tuples generated by "generate_tokens()".

All constants from the "token" module are also exported from
"tokenize", as are two additional token type values that might be
passed to the *tokeneater* function by "tokenize()":

tokenize.COMMENT

   コメントであることを表すために使われるトークン値です。

tokenize.NL

   終わりではない改行を表すために使われるトークン値。NEWLINE トークン
   は Pythonコードの論理行の終わりを表します。NLトークンはコードの論理
   行が複数の物理行にわたって続いているときに作られます。

もう一つの関数がトークン化プロセスを逆転するために提供されています。こ
れは、スクリプトを字句解析し、トークンのストリームに変更を加え、変更さ
れたスクリプトを書き戻すようなツールを作成する際に便利です。

tokenize.untokenize(iterable)

   Converts tokens back into Python source code.  The *iterable* must
   return sequences with at least two elements, the token type and the
   token string.  Any additional sequence elements are ignored.

   再構築されたスクリプトは一つの文字列として返されます。得られる結果
   はもう一度字句解析すると入力と一致することが保証されるので、変換が
   ロスレスでありラウンドトリップできることは間違いありません。この保
   証はトークン型およびトークン文字列に対してのものでトークン間のスペ
   ース (コラム位置)のようなものは変わることがあり得ます。

   バージョン 2.5 で追加.

exception tokenize.TokenError

   docstring や複数行にわたることが許される式がファイル内のどこかで終
   わっていない場合に送出されます。例えば:

      """Beginning of
      docstring

   もしくは:

      [1,
       2,
       3

閉じていないシングルクォート文字列は送出されるべきエラーの原因とならな
いことに注意してください。それらは "ERRORTOKEN" とトークン化され、続い
てその内容がトークン化されます。

Example of a script re-writer that transforms float literals into
Decimal objects:

   def decistmt(s):
       """Substitute Decimals for floats in a string of statements.

       >>> from decimal import Decimal
       >>> s = 'print +21.3e-5*-.1234/81.7'
       >>> decistmt(s)
       "print +Decimal ('21.3e-5')*-Decimal ('.1234')/Decimal ('81.7')"

       >>> exec(s)
       -3.21716034272e-007
       >>> exec(decistmt(s))
       -3.217160342717258261933904529E-7

       """
       result = []
       g = generate_tokens(StringIO(s).readline)   # tokenize the string
       for toknum, tokval, _, _, _  in g:
           if toknum == NUMBER and '.' in tokval:  # replace NUMBER tokens
               result.extend([
                   (NAME, 'Decimal'),
                   (OP, '('),
                   (STRING, repr(tokval)),
                   (OP, ')')
               ])
           else:
               result.append((toknum, tokval))
       return untokenize(result)
