github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/text/scanner/scanner.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // パッケージscannerは、UTF-8エンコードされたテキストのスキャナとトークナイザを提供します。
     6  // それはソースを提供するio.Readerを取り、その後、Scan関数を繰り返し呼び出すことでトークン化できます。
     7  // 既存のツールとの互換性のため、NUL文字は許可されていません。ソースの最初の文字が
     8  // UTF-8エンコードされたバイトオーダーマーク(BOM)である場合、それは破棄されます。
     9  //
    10  // デフォルトでは、[Scanner] は空白とGoのコメントをスキップし、Go言語仕様によって定義されたすべての
    11  // リテラルを認識します。それは、それらのリテラルの一部のみを認識し、異なる識別子と空白文字を認識するように
    12  // カスタマイズすることができます。
    13  package scanner
    14  
    15  import (
    16  	"github.com/shogo82148/std/bytes"
    17  	"github.com/shogo82148/std/io"
    18  )
    19  
    20  // Positionはソース位置を表す値です。
    21  // Line > 0 の場合、位置は有効です。
    22  type Position struct {
    23  	Filename string
    24  	Offset   int
    25  	Line     int
    26  	Column   int
    27  }
    28  
    29  // IsValidは位置が有効かどうかを報告します。
    30  func (pos *Position) IsValid() bool
    31  
    32  func (pos Position) String() string
    33  
    34  // トークンの認識を制御するための事前定義されたモードビット。
    35  // 例えば、(Goの)識別子と整数のみを認識し、コメントをスキップするように
    36  // [Scanner] を設定するには、ScannerのModeフィールドを次のように設定します:
    37  //
    38  //	ScanIdents | ScanInts | SkipComments
    39  //
    40  // SkipCommentsが設定されている場合、コメントはスキップされるを除いて、
    41  // 認識されないトークンは無視されません。代わりに、スキャナは単に
    42  // それぞれの個々の文字(または可能性のあるサブトークン)を返します。
    43  // 例えば、モードがScanIdents(ScanStringsではない)の場合、文字列
    44  // "foo"はトークンシーケンス '"' [Ident] '"'としてスキャンされます。
    45  //
    46  // GoTokensを使用してScannerを設定すると、Goの識別子を含むすべてのGoリテラルトークンが受け入れられます。
    47  // コメントはスキップされます。
    48  const (
    49  	ScanIdents     = 1 << -Ident
    50  	ScanInts       = 1 << -Int
    51  	ScanFloats     = 1 << -Float
    52  	ScanChars      = 1 << -Char
    53  	ScanStrings    = 1 << -String
    54  	ScanRawStrings = 1 << -RawString
    55  	ScanComments   = 1 << -Comment
    56  	SkipComments   = 1 << -skipComment
    57  	GoTokens       = ScanIdents | ScanFloats | ScanChars | ScanStrings | ScanRawStrings | ScanComments | SkipComments
    58  )
    59  
    60  // Scanの結果は、これらのトークンのいずれか、またはUnicode文字です。
    61  const (
    62  	EOF = -(iota + 1)
    63  	Ident
    64  	Int
    65  	Float
    66  	Char
    67  	String
    68  	RawString
    69  	Comment
    70  )
    71  
    72  // TokenStringは、トークンまたはUnicode文字の印刷可能な文字列を返します。
    73  func TokenString(tok rune) string
    74  
    75  // GoWhitespaceは、[Scanner] のWhitespaceフィールドのデフォルト値です。
    76  // その値はGoの空白文字を選択します。
    77  const GoWhitespace = 1<<'\t' | 1<<'\n' | 1<<'\r' | 1<<' '
    78  
    79  // Scannerは、io.ReaderからのUnicode文字とトークンの読み取りを実装します。
    80  type Scanner struct {
    81  	// Input
    82  	src io.Reader
    83  
    84  	// Source buffer
    85  	srcBuf [bufLen + 1]byte
    86  	srcPos int
    87  	srcEnd int
    88  
    89  	// Source position
    90  	srcBufOffset int
    91  	line         int
    92  	column       int
    93  	lastLineLen  int
    94  	lastCharLen  int
    95  
    96  	// Token text buffer
    97  	// Typically, token text is stored completely in srcBuf, but in general
    98  	// the token text's head may be buffered in tokBuf while the token text's
    99  	// tail is stored in srcBuf.
   100  	tokBuf bytes.Buffer
   101  	tokPos int
   102  	tokEnd int
   103  
   104  	// One character look-ahead
   105  	ch rune
   106  
   107  	// Errorは、発生した各エラーに対して呼び出されます。Error
   108  	// 関数が設定されていない場合、エラーはos.Stderrに報告されます。
   109  	Error func(s *Scanner, msg string)
   110  
   111  	// ErrorCountは、発生した各エラーごとに1ずつ増加します。
   112  	ErrorCount int
   113  
   114  	// Modeフィールドは、どのトークンが認識されるかを制御します。例えば、
   115  	// Intsを認識するには、ModeのScanIntsビットを設定します。このフィールドは
   116  	// いつでも変更することができます。
   117  	Mode uint
   118  
   119  	// Whitespaceフィールドは、どの文字が空白として認識されるかを制御します。
   120  	// 文字ch <= ' 'を空白として認識するには、Whitespaceのch番目のビットを設定します
   121  	// (ch > ' 'の値に対するScannerの挙動は未定義です)。このフィールドはいつでも変更できます。
   122  	Whitespace uint64
   123  
   124  	// IsIdentRuneは、識別子のithルーンとして受け入れられる文字を制御する述語です。
   125  	// 有効な文字のセットは、空白文字のセットと交差してはなりません。
   126  	// IsIdentRune関数が設定されていない場合、代わりに通常のGoの識別子が受け入れられます。
   127  	// このフィールドはいつでも変更することができます。
   128  	IsIdentRune func(ch rune, i int) bool
   129  
   130  	// 最近スキャンされたトークンの開始位置。Scanによって設定されます。
   131  	// InitまたはNextを呼び出すと、位置が無効になります(Line == 0)。
   132  	// Filenameフィールドは常にScannerによって untouched のままです。
   133  	// エラーが報告され(Error経由で)かつPositionが無効な場合、
   134  	// スキャナはトークンの内部にはありません。その場合、または最近スキャンされたトークンの
   135  	// 直後の位置を取得するには、Posを呼び出します。
   136  	Position
   137  }
   138  
   139  // Initは新しいソースで [Scanner] を初期化し、sを返します。
   140  // [Scanner.Error] はnilに設定され、[Scanner.ErrorCount] は0に設定され、[Scanner.Mode] は [GoTokens] に設定され、
   141  // [Scanner.Whitespace] は [GoWhitespace] に設定されます。
   142  func (s *Scanner) Init(src io.Reader) *Scanner
   143  
   144  // Nextは次のUnicode文字を読み取り、返します。
   145  // ソースの終わりで [EOF] を返します。読み取りエラーが発生した場合、
   146  // s.Errorがnilでない場合はs.Errorを呼び出して報告します。それ以外の場合は
   147  // [os.Stderr] にエラーメッセージを出力します。Nextは [Scanner.Position] フィールドを
   148  // 更新しません。現在の位置を取得するには、[Scanner.Pos]()を使用します。
   149  func (s *Scanner) Next() rune
   150  
   151  // Peekは、スキャナを進めずにソースの次のUnicode文字を返します。
   152  // スキャナの位置がソースの最後の文字にある場合、[EOF] を返します。
   153  func (s *Scanner) Peek() rune
   154  
   155  // Scanは、ソースから次のトークンまたはUnicode文字を読み取り、それを返します。
   156  // それは、それぞれの [Scanner.Mode] ビット(1<<-t)が設定されているトークンtのみを認識します。
   157  // ソースの終わりで [EOF] を返します。スキャナのエラー(読み取りエラーとトークンエラー)は、
   158  // s.Errorがnilでない場合にはs.Errorを呼び出すことで報告します。それ以外の場合は、
   159  // [os.Stderr] にエラーメッセージを出力します。
   160  func (s *Scanner) Scan() rune
   161  
   162  // Posは、最後の [Scanner.Next] または [Scanner.Scan] の呼び出しによって返された文字またはトークンの直後の文字の位置を返します。
   163  // 最近スキャンされたトークンの開始位置には、Scannerの [Scanner.Position] フィールドを使用します。
   164  func (s *Scanner) Pos() (pos Position)
   165  
   166  // TokenTextは、最近スキャンされたトークンに対応する文字列を返します。
   167  // [Scanner.Scan] の呼び出し後、および [Scanner.Error] の呼び出し中に有効です。
   168  func (s *Scanner) TokenText() string