| // Copyright 2018 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package scanner_test |
| |
| import ( |
| "fmt" |
| "strings" |
| "text/scanner" |
| "unicode" |
| ) |
| |
| func Example() { |
| const src = ` |
| // This is scanned code. |
| if a > 10 { |
| someParsable = text |
| }` |
| |
| var s scanner.Scanner |
| s.Init(strings.NewReader(src)) |
| s.Filename = "example" |
| for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { |
| fmt.Printf("%s: %s\n", s.Position, s.TokenText()) |
| } |
| |
| // Output: |
| // example:3:1: if |
| // example:3:4: a |
| // example:3:6: > |
| // example:3:8: 10 |
| // example:3:11: { |
| // example:4:2: someParsable |
| // example:4:15: = |
| // example:4:17: text |
| // example:5:1: } |
| } |
| |
| func Example_isIdentRune() { |
| const src = "%var1 var2%" |
| |
| var s scanner.Scanner |
| s.Init(strings.NewReader(src)) |
| s.Filename = "default" |
| |
| for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { |
| fmt.Printf("%s: %s\n", s.Position, s.TokenText()) |
| } |
| |
| fmt.Println() |
| s.Init(strings.NewReader(src)) |
| s.Filename = "percent" |
| |
| // treat leading '%' as part of an identifier |
| s.IsIdentRune = func(ch rune, i int) bool { |
| return ch == '%' && i == 0 || unicode.IsLetter(ch) || unicode.IsDigit(ch) && i > 0 |
| } |
| |
| for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { |
| fmt.Printf("%s: %s\n", s.Position, s.TokenText()) |
| } |
| |
| // Output: |
| // default:1:1: % |
| // default:1:2: var1 |
| // default:1:7: var2 |
| // default:1:11: % |
| // |
| // percent:1:1: %var1 |
| // percent:1:7: var2 |
| // percent:1:11: % |
| } |
| |
| func Example_mode() { |
| const src = ` |
| // Comment begins at column 5. |
| |
| This line should not be included in the output. |
| |
| /* |
| This multiline comment |
| should be extracted in |
| its entirety. |
| */ |
| ` |
| |
| var s scanner.Scanner |
| s.Init(strings.NewReader(src)) |
| s.Filename = "comments" |
| s.Mode ^= scanner.SkipComments // don't skip comments |
| |
| for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { |
| txt := s.TokenText() |
| if strings.HasPrefix(txt, "//") || strings.HasPrefix(txt, "/*") { |
| fmt.Printf("%s: %s\n", s.Position, txt) |
| } |
| } |
| |
| // Output: |
| // comments:2:5: // Comment begins at column 5. |
| // comments:6:1: /* |
| // This multiline comment |
| // should be extracted in |
| // its entirety. |
| // */ |
| } |
| |
| func Example_whitespace() { |
| // tab-separated values |
| const src = `aa ab ac ad |
| ba bb bc bd |
| ca cb cc cd |
| da db dc dd` |
| |
| var ( |
| col, row int |
| s scanner.Scanner |
| tsv [4][4]string // large enough for example above |
| ) |
| s.Init(strings.NewReader(src)) |
| s.Whitespace ^= 1<<'\t' | 1<<'\n' // don't skip tabs and new lines |
| |
| for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { |
| switch tok { |
| case '\n': |
| row++ |
| col = 0 |
| case '\t': |
| col++ |
| default: |
| tsv[row][col] = s.TokenText() |
| } |
| } |
| |
| fmt.Print(tsv) |
| |
| // Output: |
| // [[aa ab ac ad] [ba bb bc bd] [ca cb cc cd] [da db dc dd]] |
| } |