DFS */
| 215 | |
| 216 | /* DFS */ |
| 217 | static void show_tokens_aux(Node n, Node p, Node gp, FILE *fp) |
| 218 | { |
| 219 | if (token_startsWith(n->label, "cpp:")) |
| 220 | return; |
| 221 | |
| 222 | if (n->line) { /* leaf node */ |
| 223 | /* Forego sequence number; easy to add afterwards. */ |
| 224 | /* line, col, class, token */ |
| 225 | |
| 226 | /* A leaf node always has a parent! */ |
| 227 | assert(p); |
| 228 | /* The parent always has a non-empty label! */ |
| 229 | jsmntok_t *class = p->label; |
| 230 | |
| 231 | /* Do not consider some classes: */ |
| 232 | if (string_eq(class, "unit")) |
| 233 | return; |
| 234 | |
| 235 | enum { IDENTIFIER, STRING, CHARACTER, NUMBER, COMMENT, OTHER } kind = OTHER; |
| 236 | |
| 237 | if (string_eq(class, "comment")) { |
| 238 | if (!keep_comments) |
| 239 | return; |
| 240 | JSON_unescape(n->label); |
| 241 | kind = COMMENT; |
| 242 | } |
| 243 | |
| 244 | fprintf(fp, "%u,%u,", n->line, n->column); |
| 245 | |
| 246 | /* Analyze token literal (label is scalar): */ |
| 247 | char c = input[n->label->start]; |
| 248 | if (isalpha(c) || c == '_') |
| 249 | kind = IDENTIFIER; |
| 250 | else if (isdigit(c)) |
| 251 | kind = NUMBER; |
| 252 | else if (c == '\'') { |
| 253 | /* Undo JSON escaping in characters, e.g. '\\n' => '\n'; '\\\\' => '\\' */ |
| 254 | JSON_unescape(n->label); |
| 255 | kind = CHARACTER; |
| 256 | } |
| 257 | else if (c == '\\') { |
| 258 | /* Undo JSON escaping in strings: */ |
| 259 | /* e.g. \" \\\"graph\\\": {\\n\" => " \"graph\": {\n" */ |
| 260 | JSON_unescape(n->label); |
| 261 | kind = STRING; |
| 262 | } |
| 263 | |
| 264 | /* token class (C): |
| 265 | |
| 266 | [filename] |
| 267 | [comment] |
| 268 | keyword |
| 269 | string |
| 270 | character |
| 271 | number |
| 272 | operator |
| 273 | |
| 274 | identifiers: |
no test coverage detected