OLD | NEW |
| (Empty) |
1 part of petitparser; | |
2 | |
3 /** | |
4 * A token represents a parsed part of the input stream. | |
5 * | |
6 * The token holds the resulting value of the input, the input buffer, | |
7 * and the start and stop position in the input buffer. It provides many | |
8 * convenience methods to access the state of the token. | |
9 */ | |
10 class Token { | |
11 | |
12 /** | |
13 * The parsed value of the token. | |
14 */ | |
15 final value; | |
16 | |
17 /** | |
18 * The parsed buffer of the token. | |
19 */ | |
20 final buffer; | |
21 | |
22 /** | |
23 * The start position of the token in the buffer. | |
24 */ | |
25 final int start; | |
26 | |
27 /** | |
28 * The stop position of the token in the buffer. | |
29 */ | |
30 final int stop; | |
31 | |
32 /** | |
33 * Constructs a token from the parsed value, the input buffer, and the | |
34 * start and stop position in the input buffer. | |
35 */ | |
36 const Token(this.value, this.buffer, this.start, this.stop); | |
37 | |
38 /** | |
39 * The consumed input of the token. | |
40 */ | |
41 get input => buffer is String | |
42 ? buffer.substring(start, stop) | |
43 : buffer.sublist(start, stop); | |
44 | |
45 /** | |
46 * The length of the token. | |
47 */ | |
48 int get length => stop - start; | |
49 | |
50 /** | |
51 * The line number of the token (only works for [String] buffers). | |
52 */ | |
53 int get line => Token.lineAndColumnOf(buffer, start)[0]; | |
54 | |
55 /** | |
56 * The column number of this token (only works for [String] buffers). | |
57 */ | |
58 int get column => Token.lineAndColumnOf(buffer, start)[1]; | |
59 | |
60 @override | |
61 String toString() => 'Token[${positionString(buffer, start)}]: $value'; | |
62 | |
63 @override | |
64 bool operator ==(other) { | |
65 return other is Token | |
66 && value == other.value | |
67 && start == other.start | |
68 && stop == other.stop; | |
69 } | |
70 | |
71 @override | |
72 int get hashCode => value.hashCode + start.hashCode + stop.hashCode; | |
73 | |
74 static final Parser _NEWLINE_PARSER = | |
75 char('\n').or(char('\r').seq(char('\n').optional())); | |
76 | |
77 /** | |
78 * Returns a parser for that detects newlines platform independently. | |
79 */ | |
80 static Parser newlineParser() => _NEWLINE_PARSER; | |
81 | |
82 /** | |
83 * Converts the [position] index in a [buffer] to a line and column tuple. | |
84 */ | |
85 static List<int> lineAndColumnOf(String buffer, int position) { | |
86 var line = 1, offset = 0; | |
87 for (var token in newlineParser().token().matchesSkipping(buffer)) { | |
88 if (position < token.stop) { | |
89 return [line, position - offset + 1]; | |
90 } | |
91 line++; | |
92 offset = token.stop; | |
93 } | |
94 return [line, position - offset + 1]; | |
95 } | |
96 | |
97 /** | |
98 * Returns a human readable string representing the [position] index in a [buf
fer]. | |
99 */ | |
100 static String positionString(buffer, int position) { | |
101 if (buffer is String) { | |
102 var lineAndColumn = Token.lineAndColumnOf(buffer, position); | |
103 return '${lineAndColumn[0]}:${lineAndColumn[1]}'; | |
104 } else { | |
105 return '${position}'; | |
106 } | |
107 } | |
108 } | |
OLD | NEW |