()
| 133 | } |
| 134 | |
| 135 | private readToken(): Token { |
| 136 | this.skipWhitespaceAndComments(); |
| 137 | |
| 138 | const position = this.scanner.position; |
| 139 | const byte = this.scanner.peek(); |
| 140 | |
| 141 | if (byte === -1) { |
| 142 | return { type: "eof", position }; |
| 143 | } |
| 144 | |
| 145 | // Name: /... |
| 146 | if (byte === CHAR_SLASH) { |
| 147 | return this.readName(position); |
| 148 | } |
| 149 | |
| 150 | // Literal string: (...) |
| 151 | if (byte === CHAR_PARENTHESIS_OPEN) { |
| 152 | return this.readLiteralString(position); |
| 153 | } |
| 154 | |
| 155 | // Hex string or dict delimiter: < or << |
| 156 | if (byte === CHAR_ANGLE_BRACKET_OPEN) { |
| 157 | return this.readAngleBracket(position); |
| 158 | } |
| 159 | |
| 160 | // Dict end or unexpected > |
| 161 | if (byte === CHAR_ANGLE_BRACKET_CLOSE) { |
| 162 | return this.readClosingAngle(position); |
| 163 | } |
| 164 | |
| 165 | // Array delimiters |
| 166 | if (byte === CHAR_SQUARE_BRACKET_OPEN) { |
| 167 | this.scanner.advance(); |
| 168 | |
| 169 | return { type: "delimiter", value: "[", position }; |
| 170 | } |
| 171 | |
| 172 | if (byte === CHAR_SQUARE_BRACKET_CLOSE) { |
| 173 | this.scanner.advance(); |
| 174 | |
| 175 | return { type: "delimiter", value: "]", position }; |
| 176 | } |
| 177 | |
| 178 | // Number: digit, +, -, or . |
| 179 | if (this.isNumberStart(byte)) { |
| 180 | return this.readNumber(position); |
| 181 | } |
| 182 | |
| 183 | // Keyword or unknown |
| 184 | return this.readKeyword(position); |
| 185 | } |
| 186 | |
| 187 | private isNumberStart(byte: number): boolean { |
| 188 | return ( |
no test coverage detected