@willbooster/tree-sitter-c 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -57,8 +57,8 @@ const parser = new Parser();
57
57
  parser.setLanguage(await Language.load(c));
58
58
  ```
59
59
 
60
- The package also ships `grammar.js`, the queries in `queries/`, and the node types in `src/node-types.json` for grammars
61
- extending C (such as C++).
60
+ The package also ships `grammar.js`, the scanner sources `src/scanner.c` and `src/pragma.h`, the queries in `queries/`,
61
+ and the node types in `src/node-types.json` for grammars extending C (such as C++).
62
62
 
63
63
  In Rust, depend on the [crate](https://crates.io/crates/willbooster-tree-sitter-c) and on
64
64
  [willbooster-tree-sitter](https://crates.io/crates/willbooster-tree-sitter), the runtime this package is tested and
package/grammar.js CHANGED
@@ -35,19 +35,28 @@ const PREC = {
35
35
  SUBSCRIPT: 17,
36
36
  };
37
37
 
38
+ const LINE_COMMENT = seq('//', /(\\+(.|\r?\n)|[^\\\n])*/);
39
+ const PRAGMA_SPACING = repeat(choice(/\s/, /\\\r?\n/));
40
+
38
41
  // oxlint-disable-next-line unicorn/prefer-module -- This package is CommonJS, so tree-sitter loads grammar.js as CommonJS.
39
42
  module.exports = Object.assign(
40
43
  grammar({
41
44
  name: 'c',
42
45
 
43
46
  conflicts: ($) => [
47
+ [$._declaration_modifiers, $._empty_declaration],
48
+ [$.declaration, $.storage_class_specifier],
49
+ [$.sized_type_specifier, $.enum_specifier],
44
50
  [$.type_specifier, $._declarator],
45
51
  [$.type_specifier, $._declarator, $.macro_type_specifier],
46
52
  [$.type_specifier, $.expression],
47
53
  [$.type_specifier, $.expression, $.macro_type_specifier],
48
54
  [$.type_specifier, $.macro_type_specifier],
49
55
  [$.type_specifier, $.sized_type_specifier],
56
+ [$.type_specifier, $._sized_bit_int_specifier],
50
57
  [$.sized_type_specifier],
58
+ [$._sized_bit_int_specifier],
59
+ [$.sized_type_specifier, $._sized_bit_int_specifier],
51
60
  [$.attributed_statement],
52
61
  [$._declaration_modifiers, $.attributed_statement],
53
62
  [$.enum_specifier],
@@ -60,7 +69,9 @@ module.exports = Object.assign(
60
69
  [$.type_qualifier, $.extension_expression],
61
70
  ],
62
71
 
63
- extras: ($) => [/\s|\\\r?\n/, $.comment],
72
+ externals: () => [sym('pragma_operator'), sym('preproc_arg'), sym('_preproc_newline')],
73
+
74
+ extras: ($) => [$.pragma_operator, /\s|\\\r?\n/, $.comment],
64
75
 
65
76
  inline: ($) => [
66
77
  $._type_identifier,
@@ -123,6 +134,23 @@ module.exports = Object.assign(
123
134
  $.preproc_call
124
135
  ),
125
136
 
137
+ // Derived grammars that replace externals still need this lexical fallback. Comment-rich spacing makes the
138
+ // lexer too large for the pinned Node Wasm optimizer; the external scanner handles those forms.
139
+ pragma_operator: () =>
140
+ token(
141
+ seq(
142
+ '_Pragma',
143
+ PRAGMA_SPACING,
144
+ '(',
145
+ PRAGMA_SPACING,
146
+ optional(choice('L', 'u8', 'u', 'U')),
147
+ '"',
148
+ repeat(choice(/[^\\"\n]/, seq('\\', choice(/./, /\r?\n/)))),
149
+ '"',
150
+ PRAGMA_SPACING,
151
+ ')'
152
+ )
153
+ ),
126
154
  // Preprocesser
127
155
 
128
156
  preproc_include: ($) =>
@@ -137,7 +165,7 @@ module.exports = Object.assign(
137
165
  alias($.preproc_call_expression, $.call_expression)
138
166
  )
139
167
  ),
140
- token.immediate(/\r?\n/)
168
+ sym('_preproc_newline')
141
169
  ),
142
170
 
143
171
  preproc_def: ($) =>
@@ -145,7 +173,7 @@ module.exports = Object.assign(
145
173
  preprocessor('define'),
146
174
  field('name', $.identifier),
147
175
  field('value', optional($.preproc_arg)),
148
- token.immediate(/\r?\n/)
176
+ sym('_preproc_newline')
149
177
  ),
150
178
 
151
179
  preproc_function_def: ($) =>
@@ -154,7 +182,7 @@ module.exports = Object.assign(
154
182
  field('name', $.identifier),
155
183
  field('parameters', $.preproc_params),
156
184
  field('value', optional($.preproc_arg)),
157
- token.immediate(/\r?\n/)
185
+ sym('_preproc_newline')
158
186
  ),
159
187
 
160
188
  preproc_params: ($) => seq(token.immediate('('), commaSep(choice($.identifier, '...')), ')'),
@@ -163,7 +191,7 @@ module.exports = Object.assign(
163
191
  seq(
164
192
  field('directive', $.preproc_directive),
165
193
  field('argument', optional($.preproc_arg)),
166
- token.immediate(/\r?\n/)
194
+ sym('_preproc_newline')
167
195
  ),
168
196
 
169
197
  ...preprocIf('', () => sym('_block_item')),
@@ -171,6 +199,8 @@ module.exports = Object.assign(
171
199
  ...preprocIf('_in_enumerator_list', () => seq(sym('enumerator'), ',')),
172
200
  ...preprocIf('_in_enumerator_list_no_comma', () => sym('enumerator'), -1),
173
201
 
202
+ _preproc_newline: () => token.immediate(/\r?\n/),
203
+
174
204
  preproc_arg: () => token(prec(-1, /\S([^/\n]|\/[^*]|\\\r?\n)*/)),
175
205
  preproc_directive: () => /#[ \t]*[a-zA-Z0-9]\w*/,
176
206
 
@@ -203,7 +233,8 @@ module.exports = Object.assign(
203
233
  seq(field('function', $.identifier), field('arguments', alias($.preproc_argument_list, $.argument_list)))
204
234
  ),
205
235
 
206
- preproc_argument_list: ($) => seq('(', commaSep($._preproc_expression), ')'),
236
+ preproc_argument_list: ($) =>
237
+ seq('(', commaSep(choice($._preproc_expression, $.system_lib_string, $.string_literal)), ')'),
207
238
 
208
239
  preproc_binary_expression: ($) => {
209
240
  /** @type {[string, number][]} */
@@ -264,7 +295,17 @@ module.exports = Object.assign(
264
295
 
265
296
  declaration: ($) =>
266
297
  seq(
267
- $._declaration_specifiers,
298
+ choice(
299
+ $._declaration_specifiers,
300
+ prec.dynamic(
301
+ PREC.PAREN_DECLARATOR - 1,
302
+ seq(
303
+ repeat($._declaration_modifiers),
304
+ alias('auto', $.storage_class_specifier),
305
+ repeat($._declaration_modifiers)
306
+ )
307
+ )
308
+ ),
268
309
  commaSep1(
269
310
  field(
270
311
  'declarator',
@@ -560,6 +601,7 @@ module.exports = Object.assign(
560
601
  '__inline__',
561
602
  '__forceinline',
562
603
  'thread_local',
604
+ '_Thread_local',
563
605
  '__thread'
564
606
  ),
565
607
 
@@ -585,26 +627,28 @@ module.exports = Object.assign(
585
627
  $.struct_specifier,
586
628
  $.union_specifier,
587
629
  $.enum_specifier,
630
+ $.typeof_specifier,
631
+ $.bit_int_specifier,
588
632
  $.macro_type_specifier,
589
633
  $.sized_type_specifier,
634
+ alias($._sized_bit_int_specifier, $.sized_type_specifier),
590
635
  $.primitive_type,
591
636
  $._type_identifier
592
637
  ),
593
638
 
594
- sized_type_specifier: ($) =>
595
- choice(
596
- seq(
597
- repeat(choice('signed', 'unsigned', 'long', 'short')),
598
- field('type', optional(choice(prec.dynamic(-1, $._type_identifier), $.primitive_type))),
599
- repeat1(choice('signed', 'unsigned', 'long', 'short'))
600
- ),
601
- seq(
602
- repeat1(choice('signed', 'unsigned', 'long', 'short')),
603
- repeat($.type_qualifier),
604
- field('type', optional(choice(prec.dynamic(-1, $._type_identifier), $.primitive_type))),
605
- repeat(choice('signed', 'unsigned', 'long', 'short'))
606
- )
639
+ typeof_specifier: ($) =>
640
+ seq(
641
+ choice('typeof', 'typeof_unqual', '__typeof__', '__typeof', '__typeof_unqual', '__typeof_unqual__'),
642
+ '(',
643
+ choice($.type_descriptor, $.expression, $.comma_expression),
644
+ ')'
607
645
  ),
646
+ bit_int_specifier: ($) => seq('_BitInt', '(', $.expression, ')'),
647
+
648
+ sized_type_specifier: ($) =>
649
+ sizedTypeSpecifier(optional(choice(prec.dynamic(-1, $._type_identifier), $.primitive_type))),
650
+
651
+ _sized_bit_int_specifier: ($) => sizedTypeSpecifier($.bit_int_specifier),
608
652
 
609
653
  primitive_type: () =>
610
654
  token(
@@ -635,10 +679,29 @@ module.exports = Object.assign(
635
679
  choice(
636
680
  seq(
637
681
  field('name', $._type_identifier),
638
- optional(seq(':', field('underlying_type', $.primitive_type))),
682
+ optional(
683
+ seq(
684
+ ':',
685
+ field(
686
+ 'underlying_type',
687
+ choice($.primitive_type, $.sized_type_specifier, $.typeof_specifier, $._type_identifier)
688
+ )
689
+ )
690
+ ),
639
691
  field('body', optional($.enumerator_list))
640
692
  ),
641
- field('body', $.enumerator_list)
693
+ seq(
694
+ optional(
695
+ seq(
696
+ ':',
697
+ field(
698
+ 'underlying_type',
699
+ choice($.primitive_type, $.sized_type_specifier, $.typeof_specifier, $._type_identifier)
700
+ )
701
+ )
702
+ ),
703
+ field('body', $.enumerator_list)
704
+ )
642
705
  ),
643
706
  optional($.attribute_specifier)
644
707
  ),
@@ -828,7 +891,15 @@ module.exports = Object.assign(
828
891
 
829
892
  continue_statement: () => seq('continue', ';'),
830
893
 
831
- goto_statement: ($) => seq('goto', field('label', $._statement_identifier), ';'),
894
+ goto_statement: ($) =>
895
+ seq(
896
+ 'goto',
897
+ choice(
898
+ field('label', $._statement_identifier),
899
+ seq('*', field('label', choice($.expression, $.comma_expression)))
900
+ ),
901
+ ';'
902
+ ),
832
903
 
833
904
  seh_try_statement: ($) =>
834
905
  seq('__try', field('body', $.compound_statement), choice($.seh_except_clause, $.seh_finally_clause)),
@@ -1078,8 +1149,47 @@ module.exports = Object.assign(
1078
1149
 
1079
1150
  parenthesized_expression: ($) => seq('(', choice($.expression, $.comma_expression, $.compound_statement), ')'),
1080
1151
 
1081
- initializer_list: ($) =>
1082
- seq('{', commaSep(choice($.initializer_pair, $.expression, $.initializer_list)), optional(','), '}'),
1152
+ initializer_list: ($) => seq('{', optional($._initializer_sequence), '}'),
1153
+
1154
+ _initializer_sequence: ($) =>
1155
+ choice(
1156
+ seq(
1157
+ $._initializer_element,
1158
+ optional(choice(seq(',', optional($._initializer_sequence)), $._initializer_directives))
1159
+ ),
1160
+ $._initializer_directives
1161
+ ),
1162
+
1163
+ _initializer_directives: ($) =>
1164
+ seq(
1165
+ $._initializer_directive,
1166
+ optional(choice($._initializer_sequence, seq(',', optional($._initializer_sequence))))
1167
+ ),
1168
+
1169
+ _initializer_directive: ($) =>
1170
+ choice(
1171
+ alias(sym('preproc_if_in_initializer_list'), sym('preproc_if')),
1172
+ alias(sym('preproc_ifdef_in_initializer_list'), sym('preproc_ifdef')),
1173
+ $.preproc_def,
1174
+ $.preproc_function_def,
1175
+ alias($._initializer_preproc_call, $.preproc_call)
1176
+ ),
1177
+
1178
+ _initializer_element: ($) => choice($.initializer_pair, $.expression, $.initializer_list),
1179
+
1180
+ _initializer_branch: ($) => choice(seq(',', optional($._initializer_sequence)), $._initializer_sequence),
1181
+
1182
+ _initializer_preproc_call: ($) =>
1183
+ seq(
1184
+ field(
1185
+ 'directive',
1186
+ alias(token(/#[ \t]*(embed|include|undef|error|warning|line|pragma)/), $.preproc_directive)
1187
+ ),
1188
+ field('argument', optional($.preproc_arg)),
1189
+ alias(sym('_preproc_newline'), '\n')
1190
+ ),
1191
+
1192
+ ...preprocIf('_in_initializer_list', () => sym('_initializer_branch'), 0, false),
1083
1193
 
1084
1194
  initializer_pair: ($) =>
1085
1195
  choice(
@@ -1153,7 +1263,22 @@ module.exports = Object.assign(
1153
1263
 
1154
1264
  escape_sequence: () =>
1155
1265
  token(
1156
- prec(1, seq('\\', choice(/[^xuU]/, /\d{2,3}/, /x[0-9a-fA-F]{1,4}/, /u[0-9a-fA-F]{4}/, /U[0-9a-fA-F]{8}/)))
1266
+ prec(
1267
+ 1,
1268
+ seq(
1269
+ '\\',
1270
+ choice(
1271
+ /[^xuU]/,
1272
+ /[xu]\{[0-9a-fA-F]+\}/,
1273
+ /o\{[0-7]+\}/,
1274
+ /N\{[^}\n]+\}/,
1275
+ /\d{2,3}/,
1276
+ /x[0-9a-fA-F]{1,4}/,
1277
+ /u[0-9a-fA-F]{4}/,
1278
+ /U[0-9a-fA-F]{8}/
1279
+ )
1280
+ )
1281
+ )
1157
1282
  ),
1158
1283
 
1159
1284
  system_lib_string: () => token(seq('<', repeat(choice(/[^>\n]/, String.raw`\>`)), '>')),
@@ -1169,18 +1294,29 @@ module.exports = Object.assign(
1169
1294
  _field_identifier: ($) => alias($.identifier, sym('field_identifier')),
1170
1295
  _statement_identifier: ($) => alias($.identifier, sym('statement_identifier')),
1171
1296
 
1172
- _empty_declaration: ($) => seq($.type_specifier, ';'),
1297
+ _empty_declaration: ($) => seq(repeat($.ms_declspec_modifier), $.type_specifier, ';'),
1173
1298
 
1174
1299
  macro_type_specifier: ($) =>
1175
1300
  prec.dynamic(-1, seq(field('name', $.identifier), '(', field('type', $.type_descriptor), ')')),
1176
1301
 
1177
1302
  // http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890
1178
- comment: () => token(choice(seq('//', /(\\+(.|\r?\n)|[^\\\n])*/), seq('/*', /[^*]*\*+([^/*][^*]*\*+)*/, '/'))),
1303
+ comment: () => token(choice(LINE_COMMENT, seq('/*', /[^*]*\*+([^/*][^*]*\*+)*/, '/'))),
1179
1304
  },
1180
1305
  }),
1181
1306
  { PREC, preprocIf, preprocessor, commaSep, commaSep1 }
1182
1307
  );
1183
1308
 
1309
+ /**
1310
+ * @param {import('./types/treeSitterDsl').RuleOrLiteral} type
1311
+ */
1312
+ function sizedTypeSpecifier(type) {
1313
+ const modifier = choice('signed', 'unsigned', 'long', 'short', '_Complex', '_Imaginary', '__complex__');
1314
+ return choice(
1315
+ seq(repeat(modifier), field('type', type), repeat1(modifier)),
1316
+ seq(repeat1(modifier), repeat(sym('type_qualifier')), field('type', type), repeat(modifier))
1317
+ );
1318
+ }
1319
+
1184
1320
  /**
1185
1321
  *
1186
1322
  * @param {string} suffix
@@ -1188,10 +1324,11 @@ module.exports = Object.assign(
1188
1324
  * @param {import('./types/treeSitterDsl').RuleBuilder<string>} content
1189
1325
  *
1190
1326
  * @param {number} precedence
1327
+ * @param {boolean} repeatContent
1191
1328
  *
1192
1329
  * @returns {import('./types/treeSitterDsl').RuleBuilders<string, string>}
1193
1330
  */
1194
- function preprocIf(suffix, content, precedence = 0) {
1331
+ function preprocIf(suffix, content, precedence = 0, repeatContent = true) {
1195
1332
  function alternativeBlock() {
1196
1333
  return choice(
1197
1334
  suffix ? alias(sym('preproc_else' + suffix), sym('preproc_else')) : sym('preproc_else'),
@@ -1207,8 +1344,8 @@ function preprocIf(suffix, content, precedence = 0) {
1207
1344
  seq(
1208
1345
  preprocessor('if'),
1209
1346
  field('condition', sym('_preproc_expression')),
1210
- '\n',
1211
- repeat(content($)),
1347
+ alias(sym('_preproc_newline'), '\n'),
1348
+ repeatContent ? repeat(content($)) : optional(content($)),
1212
1349
  field('alternative', optional(alternativeBlock())),
1213
1350
  preprocessor('endif')
1214
1351
  )
@@ -1220,13 +1357,14 @@ function preprocIf(suffix, content, precedence = 0) {
1220
1357
  seq(
1221
1358
  choice(preprocessor('ifdef'), preprocessor('ifndef')),
1222
1359
  field('name', sym('identifier')),
1223
- repeat(content($)),
1360
+ repeatContent ? repeat(content($)) : optional(content($)),
1224
1361
  field('alternative', optional(alternativeBlock())),
1225
1362
  preprocessor('endif')
1226
1363
  )
1227
1364
  ),
1228
1365
 
1229
- ['preproc_else' + suffix]: ($) => prec(precedence, seq(preprocessor('else'), repeat(content($)))),
1366
+ ['preproc_else' + suffix]: ($) =>
1367
+ prec(precedence, seq(preprocessor('else'), repeatContent ? repeat(content($)) : optional(content($)))),
1230
1368
 
1231
1369
  ['preproc_elif' + suffix]: ($) =>
1232
1370
  prec(
@@ -1234,8 +1372,8 @@ function preprocIf(suffix, content, precedence = 0) {
1234
1372
  seq(
1235
1373
  preprocessor('elif'),
1236
1374
  field('condition', sym('_preproc_expression')),
1237
- '\n',
1238
- repeat(content($)),
1375
+ alias(sym('_preproc_newline'), '\n'),
1376
+ repeatContent ? repeat(content($)) : optional(content($)),
1239
1377
  field('alternative', optional(alternativeBlock()))
1240
1378
  )
1241
1379
  ),
@@ -1246,7 +1384,7 @@ function preprocIf(suffix, content, precedence = 0) {
1246
1384
  seq(
1247
1385
  choice(preprocessor('elifdef'), preprocessor('elifndef')),
1248
1386
  field('name', sym('identifier')),
1249
- repeat(content($)),
1387
+ repeatContent ? repeat(content($)) : optional(content($)),
1250
1388
  field('alternative', optional(alternativeBlock()))
1251
1389
  )
1252
1390
  ),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willbooster/tree-sitter-c",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "C grammar for tree-sitter",
5
5
  "keywords": [
6
6
  "incremental",
@@ -20,7 +20,9 @@
20
20
  "queries/*.scm",
21
21
  "src/node-types.json",
22
22
  "tree-sitter.json",
23
- "*.wasm"
23
+ "*.wasm",
24
+ "src/pragma.h",
25
+ "src/scanner.c"
24
26
  ],
25
27
  "scripts": {
26
28
  "build-wasm": "script/tree-sitter build --wasm",
@@ -3,6 +3,9 @@
3
3
  ((identifier) @constant
4
4
  (#match? @constant "^[A-Z][A-Z\\d_]*$"))
5
5
 
6
+ ((storage_class_specifier) @keyword
7
+ (#eq? @keyword "auto"))
8
+ "_Thread_local" @keyword
6
9
  "break" @keyword
7
10
  "case" @keyword
8
11
  "const" @keyword
@@ -79,3 +82,8 @@
79
82
  name: (identifier) @function.special)
80
83
 
81
84
  (comment) @comment
85
+
86
+ (typeof_specifier
87
+ ["typeof" "typeof_unqual" "__typeof__" "__typeof" "__typeof_unqual" "__typeof_unqual__"] @keyword)
88
+ (bit_int_specifier "_BitInt" @type)
89
+ (pragma_operator) @keyword
@@ -303,6 +303,10 @@
303
303
  "type": "type_specifier",
304
304
  "named": true,
305
305
  "subtypes": [
306
+ {
307
+ "type": "bit_int_specifier",
308
+ "named": true
309
+ },
306
310
  {
307
311
  "type": "enum_specifier",
308
312
  "named": true
@@ -327,6 +331,10 @@
327
331
  "type": "type_identifier",
328
332
  "named": true
329
333
  },
334
+ {
335
+ "type": "typeof_specifier",
336
+ "named": true
337
+ },
330
338
  {
331
339
  "type": "union_specifier",
332
340
  "named": true
@@ -506,6 +514,10 @@
506
514
  {
507
515
  "type": "preproc_defined",
508
516
  "named": true
517
+ },
518
+ {
519
+ "type": "system_lib_string",
520
+ "named": true
509
521
  }
510
522
  ]
511
523
  }
@@ -878,6 +890,21 @@
878
890
  }
879
891
  }
880
892
  },
893
+ {
894
+ "type": "bit_int_specifier",
895
+ "named": true,
896
+ "fields": {},
897
+ "children": {
898
+ "multiple": false,
899
+ "required": true,
900
+ "types": [
901
+ {
902
+ "type": "expression",
903
+ "named": true
904
+ }
905
+ ]
906
+ }
907
+ },
881
908
  {
882
909
  "type": "bitfield_clause",
883
910
  "named": true,
@@ -1160,6 +1187,10 @@
1160
1187
  "type": "linkage_specification",
1161
1188
  "named": true
1162
1189
  },
1190
+ {
1191
+ "type": "ms_declspec_modifier",
1192
+ "named": true
1193
+ },
1163
1194
  {
1164
1195
  "type": "preproc_call",
1165
1196
  "named": true
@@ -1311,7 +1342,7 @@
1311
1342
  },
1312
1343
  "type": {
1313
1344
  "multiple": false,
1314
- "required": true,
1345
+ "required": false,
1315
1346
  "types": [
1316
1347
  {
1317
1348
  "type": "type_specifier",
@@ -1367,6 +1398,10 @@
1367
1398
  "type": "linkage_specification",
1368
1399
  "named": true
1369
1400
  },
1401
+ {
1402
+ "type": "ms_declspec_modifier",
1403
+ "named": true
1404
+ },
1370
1405
  {
1371
1406
  "type": "preproc_call",
1372
1407
  "named": true
@@ -1478,6 +1513,18 @@
1478
1513
  {
1479
1514
  "type": "primitive_type",
1480
1515
  "named": true
1516
+ },
1517
+ {
1518
+ "type": "sized_type_specifier",
1519
+ "named": true
1520
+ },
1521
+ {
1522
+ "type": "type_identifier",
1523
+ "named": true
1524
+ },
1525
+ {
1526
+ "type": "typeof_specifier",
1527
+ "named": true
1481
1528
  }
1482
1529
  ]
1483
1530
  }
@@ -2156,6 +2203,14 @@
2156
2203
  "multiple": false,
2157
2204
  "required": true,
2158
2205
  "types": [
2206
+ {
2207
+ "type": "comma_expression",
2208
+ "named": true
2209
+ },
2210
+ {
2211
+ "type": "expression",
2212
+ "named": true
2213
+ },
2159
2214
  {
2160
2215
  "type": "statement_identifier",
2161
2216
  "named": true
@@ -2249,6 +2304,26 @@
2249
2304
  {
2250
2305
  "type": "initializer_pair",
2251
2306
  "named": true
2307
+ },
2308
+ {
2309
+ "type": "preproc_call",
2310
+ "named": true
2311
+ },
2312
+ {
2313
+ "type": "preproc_def",
2314
+ "named": true
2315
+ },
2316
+ {
2317
+ "type": "preproc_function_def",
2318
+ "named": true
2319
+ },
2320
+ {
2321
+ "type": "preproc_if",
2322
+ "named": true
2323
+ },
2324
+ {
2325
+ "type": "preproc_ifdef",
2326
+ "named": true
2252
2327
  }
2253
2328
  ]
2254
2329
  }
@@ -2875,6 +2950,10 @@
2875
2950
  "type": "enumerator",
2876
2951
  "named": true
2877
2952
  },
2953
+ {
2954
+ "type": "expression",
2955
+ "named": true
2956
+ },
2878
2957
  {
2879
2958
  "type": "field_declaration",
2880
2959
  "named": true
@@ -2883,10 +2962,22 @@
2883
2962
  "type": "function_definition",
2884
2963
  "named": true
2885
2964
  },
2965
+ {
2966
+ "type": "initializer_list",
2967
+ "named": true
2968
+ },
2969
+ {
2970
+ "type": "initializer_pair",
2971
+ "named": true
2972
+ },
2886
2973
  {
2887
2974
  "type": "linkage_specification",
2888
2975
  "named": true
2889
2976
  },
2977
+ {
2978
+ "type": "ms_declspec_modifier",
2979
+ "named": true
2980
+ },
2890
2981
  {
2891
2982
  "type": "preproc_call",
2892
2983
  "named": true
@@ -2971,6 +3062,10 @@
2971
3062
  "type": "enumerator",
2972
3063
  "named": true
2973
3064
  },
3065
+ {
3066
+ "type": "expression",
3067
+ "named": true
3068
+ },
2974
3069
  {
2975
3070
  "type": "field_declaration",
2976
3071
  "named": true
@@ -2979,10 +3074,22 @@
2979
3074
  "type": "function_definition",
2980
3075
  "named": true
2981
3076
  },
3077
+ {
3078
+ "type": "initializer_list",
3079
+ "named": true
3080
+ },
3081
+ {
3082
+ "type": "initializer_pair",
3083
+ "named": true
3084
+ },
2982
3085
  {
2983
3086
  "type": "linkage_specification",
2984
3087
  "named": true
2985
3088
  },
3089
+ {
3090
+ "type": "ms_declspec_modifier",
3091
+ "named": true
3092
+ },
2986
3093
  {
2987
3094
  "type": "preproc_call",
2988
3095
  "named": true
@@ -3038,6 +3145,10 @@
3038
3145
  "type": "enumerator",
3039
3146
  "named": true
3040
3147
  },
3148
+ {
3149
+ "type": "expression",
3150
+ "named": true
3151
+ },
3041
3152
  {
3042
3153
  "type": "field_declaration",
3043
3154
  "named": true
@@ -3046,10 +3157,22 @@
3046
3157
  "type": "function_definition",
3047
3158
  "named": true
3048
3159
  },
3160
+ {
3161
+ "type": "initializer_list",
3162
+ "named": true
3163
+ },
3164
+ {
3165
+ "type": "initializer_pair",
3166
+ "named": true
3167
+ },
3049
3168
  {
3050
3169
  "type": "linkage_specification",
3051
3170
  "named": true
3052
3171
  },
3172
+ {
3173
+ "type": "ms_declspec_modifier",
3174
+ "named": true
3175
+ },
3053
3176
  {
3054
3177
  "type": "preproc_call",
3055
3178
  "named": true
@@ -3198,6 +3321,10 @@
3198
3321
  "type": "enumerator",
3199
3322
  "named": true
3200
3323
  },
3324
+ {
3325
+ "type": "expression",
3326
+ "named": true
3327
+ },
3201
3328
  {
3202
3329
  "type": "field_declaration",
3203
3330
  "named": true
@@ -3206,10 +3333,22 @@
3206
3333
  "type": "function_definition",
3207
3334
  "named": true
3208
3335
  },
3336
+ {
3337
+ "type": "initializer_list",
3338
+ "named": true
3339
+ },
3340
+ {
3341
+ "type": "initializer_pair",
3342
+ "named": true
3343
+ },
3209
3344
  {
3210
3345
  "type": "linkage_specification",
3211
3346
  "named": true
3212
3347
  },
3348
+ {
3349
+ "type": "ms_declspec_modifier",
3350
+ "named": true
3351
+ },
3213
3352
  {
3214
3353
  "type": "preproc_call",
3215
3354
  "named": true
@@ -3294,6 +3433,10 @@
3294
3433
  "type": "enumerator",
3295
3434
  "named": true
3296
3435
  },
3436
+ {
3437
+ "type": "expression",
3438
+ "named": true
3439
+ },
3297
3440
  {
3298
3441
  "type": "field_declaration",
3299
3442
  "named": true
@@ -3302,10 +3445,22 @@
3302
3445
  "type": "function_definition",
3303
3446
  "named": true
3304
3447
  },
3448
+ {
3449
+ "type": "initializer_list",
3450
+ "named": true
3451
+ },
3452
+ {
3453
+ "type": "initializer_pair",
3454
+ "named": true
3455
+ },
3305
3456
  {
3306
3457
  "type": "linkage_specification",
3307
3458
  "named": true
3308
3459
  },
3460
+ {
3461
+ "type": "ms_declspec_modifier",
3462
+ "named": true
3463
+ },
3309
3464
  {
3310
3465
  "type": "preproc_call",
3311
3466
  "named": true
@@ -3492,6 +3647,10 @@
3492
3647
  "multiple": false,
3493
3648
  "required": false,
3494
3649
  "types": [
3650
+ {
3651
+ "type": "bit_int_specifier",
3652
+ "named": true
3653
+ },
3495
3654
  {
3496
3655
  "type": "primitive_type",
3497
3656
  "named": true
@@ -3762,6 +3921,10 @@
3762
3921
  "type": "linkage_specification",
3763
3922
  "named": true
3764
3923
  },
3924
+ {
3925
+ "type": "ms_declspec_modifier",
3926
+ "named": true
3927
+ },
3765
3928
  {
3766
3929
  "type": "preproc_call",
3767
3930
  "named": true
@@ -3900,6 +4063,29 @@
3900
4063
  ]
3901
4064
  }
3902
4065
  },
4066
+ {
4067
+ "type": "typeof_specifier",
4068
+ "named": true,
4069
+ "fields": {},
4070
+ "children": {
4071
+ "multiple": false,
4072
+ "required": true,
4073
+ "types": [
4074
+ {
4075
+ "type": "comma_expression",
4076
+ "named": true
4077
+ },
4078
+ {
4079
+ "type": "expression",
4080
+ "named": true
4081
+ },
4082
+ {
4083
+ "type": "type_descriptor",
4084
+ "named": true
4085
+ }
4086
+ ]
4087
+ }
4088
+ },
3903
4089
  {
3904
4090
  "type": "unary_expression",
3905
4091
  "named": true,
@@ -4299,10 +4485,22 @@
4299
4485
  "type": "_Atomic",
4300
4486
  "named": false
4301
4487
  },
4488
+ {
4489
+ "type": "_BitInt",
4490
+ "named": false
4491
+ },
4492
+ {
4493
+ "type": "_Complex",
4494
+ "named": false
4495
+ },
4302
4496
  {
4303
4497
  "type": "_Generic",
4304
4498
  "named": false
4305
4499
  },
4500
+ {
4501
+ "type": "_Imaginary",
4502
+ "named": false
4503
+ },
4306
4504
  {
4307
4505
  "type": "_Nonnull",
4308
4506
  "named": false
@@ -4311,6 +4509,10 @@
4311
4509
  "type": "_Noreturn",
4312
4510
  "named": false
4313
4511
  },
4512
+ {
4513
+ "type": "_Thread_local",
4514
+ "named": false
4515
+ },
4314
4516
  {
4315
4517
  "type": "__alignof",
4316
4518
  "named": false
@@ -4351,6 +4553,10 @@
4351
4553
  "type": "__clrcall",
4352
4554
  "named": false
4353
4555
  },
4556
+ {
4557
+ "type": "__complex__",
4558
+ "named": false
4559
+ },
4354
4560
  {
4355
4561
  "type": "__declspec",
4356
4562
  "named": false
@@ -4415,6 +4621,22 @@
4415
4621
  "type": "__try",
4416
4622
  "named": false
4417
4623
  },
4624
+ {
4625
+ "type": "__typeof",
4626
+ "named": false
4627
+ },
4628
+ {
4629
+ "type": "__typeof__",
4630
+ "named": false
4631
+ },
4632
+ {
4633
+ "type": "__typeof_unqual",
4634
+ "named": false
4635
+ },
4636
+ {
4637
+ "type": "__typeof_unqual__",
4638
+ "named": false
4639
+ },
4418
4640
  {
4419
4641
  "type": "__unaligned",
4420
4642
  "named": false
@@ -4568,6 +4790,11 @@
4568
4790
  "type": "offsetof",
4569
4791
  "named": false
4570
4792
  },
4793
+ {
4794
+ "type": "pragma_operator",
4795
+ "named": true,
4796
+ "extra": true
4797
+ },
4571
4798
  {
4572
4799
  "type": "preproc_arg",
4573
4800
  "named": true
@@ -4644,6 +4871,14 @@
4644
4871
  "type": "typedef",
4645
4872
  "named": false
4646
4873
  },
4874
+ {
4875
+ "type": "typeof",
4876
+ "named": false
4877
+ },
4878
+ {
4879
+ "type": "typeof_unqual",
4880
+ "named": false
4881
+ },
4647
4882
  {
4648
4883
  "type": "u\"",
4649
4884
  "named": false
package/src/pragma.h ADDED
@@ -0,0 +1,130 @@
1
+ #ifndef TREE_SITTER_C_PRAGMA_H_
2
+ #define TREE_SITTER_C_PRAGMA_H_
3
+
4
+ #include "tree_sitter/parser.h"
5
+
6
+ static bool scan_pragma_spacing(TSLexer *lexer);
7
+ static bool pragma_space(int32_t c);
8
+ static bool scan_pragma_word(TSLexer *lexer);
9
+
10
+ static bool scan_pragma(TSLexer *lexer) {
11
+ while (pragma_space(lexer->lookahead)) {
12
+ lexer->advance(lexer, true);
13
+ }
14
+ if (!scan_pragma_word(lexer)) return false;
15
+ if (!scan_pragma_spacing(lexer) || lexer->lookahead != '(') return false;
16
+ lexer->advance(lexer, false);
17
+ if (!scan_pragma_spacing(lexer)) return false;
18
+ if (lexer->lookahead == 'L' || lexer->lookahead == 'u' || lexer->lookahead == 'U') {
19
+ bool utf8 = lexer->lookahead == 'u';
20
+ lexer->advance(lexer, false);
21
+ if (utf8 && lexer->lookahead == '8') lexer->advance(lexer, false);
22
+ }
23
+ if (lexer->lookahead != '"') return false;
24
+ lexer->advance(lexer, false);
25
+ while (lexer->lookahead != '"') {
26
+ if (lexer->eof(lexer) || lexer->lookahead == '\n' || lexer->lookahead == '\r') return false;
27
+ if (lexer->lookahead == '\\') {
28
+ lexer->advance(lexer, false);
29
+ if (lexer->eof(lexer)) return false;
30
+ if (lexer->lookahead == '\r') {
31
+ lexer->advance(lexer, false);
32
+ if (lexer->lookahead != '\n') return false;
33
+ }
34
+ }
35
+ lexer->advance(lexer, false);
36
+ }
37
+ lexer->advance(lexer, false);
38
+ if (!scan_pragma_spacing(lexer) || lexer->lookahead != ')') return false;
39
+ lexer->advance(lexer, false);
40
+ lexer->mark_end(lexer);
41
+ return true;
42
+ }
43
+
44
+ static bool scan_pragma_spacing(TSLexer *lexer) {
45
+ for (;;) {
46
+ if (pragma_space(lexer->lookahead)) {
47
+ lexer->advance(lexer, false);
48
+ } else if (lexer->lookahead == '\\') {
49
+ lexer->advance(lexer, false);
50
+ if (lexer->lookahead == '\r') lexer->advance(lexer, false);
51
+ if (lexer->lookahead != '\n') return false;
52
+ lexer->advance(lexer, false);
53
+ } else if (lexer->lookahead == '/') {
54
+ lexer->advance(lexer, false);
55
+ if (lexer->lookahead == '/') {
56
+ lexer->advance(lexer, false);
57
+ while (!lexer->eof(lexer) && lexer->lookahead != '\n') {
58
+ if (lexer->lookahead == '\\') {
59
+ do {
60
+ lexer->advance(lexer, false);
61
+ } while (lexer->lookahead == '\\');
62
+ if (lexer->lookahead == '\r') lexer->advance(lexer, false);
63
+ if (lexer->eof(lexer)) return false;
64
+ }
65
+ lexer->advance(lexer, false);
66
+ }
67
+ } else if (lexer->lookahead == '*') {
68
+ lexer->advance(lexer, false);
69
+ bool star = false;
70
+ for (;;) {
71
+ if (lexer->eof(lexer)) return false;
72
+ if (star && lexer->lookahead == '/') {
73
+ lexer->advance(lexer, false);
74
+ break;
75
+ }
76
+ star = lexer->lookahead == '*';
77
+ lexer->advance(lexer, false);
78
+ }
79
+ } else {
80
+ return false;
81
+ }
82
+ } else {
83
+ return true;
84
+ }
85
+ }
86
+ }
87
+
88
+ static bool scan_pragma_preproc_arg(TSLexer *lexer) {
89
+ while (pragma_space(lexer->lookahead) && lexer->lookahead != '\n' && lexer->lookahead != '\r') {
90
+ lexer->advance(lexer, true);
91
+ }
92
+ if (!scan_pragma_word(lexer)) return false;
93
+ bool backslash = false;
94
+ lexer->mark_end(lexer);
95
+ while (!lexer->eof(lexer)) {
96
+ if (lexer->lookahead == '\n') {
97
+ if (!backslash) break;
98
+ lexer->advance(lexer, false);
99
+ backslash = false;
100
+ } else if (lexer->lookahead == '/') {
101
+ lexer->advance(lexer, false);
102
+ if (lexer->lookahead == '*') break;
103
+ if (lexer->eof(lexer)) break;
104
+ backslash = lexer->lookahead == '\\';
105
+ lexer->advance(lexer, false);
106
+ } else {
107
+ if (lexer->lookahead != '\r') backslash = lexer->lookahead == '\\';
108
+ lexer->advance(lexer, false);
109
+ }
110
+ lexer->mark_end(lexer);
111
+ }
112
+ return true;
113
+ }
114
+
115
+ static bool scan_pragma_word(TSLexer *lexer) {
116
+ const char *word = "_Pragma";
117
+ for (; *word; word++) {
118
+ if (lexer->lookahead != *word) return false;
119
+ lexer->advance(lexer, false);
120
+ }
121
+ return true;
122
+ }
123
+
124
+ static bool pragma_space(int32_t c) {
125
+ return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f' || c == '\v' ||
126
+ c == 0x85 || c == 0xA0 || c == 0x1680 || (c >= 0x2000 && c <= 0x200A) ||
127
+ c == 0x2028 || c == 0x2029 || c == 0x202F || c == 0x205F || c == 0x3000;
128
+ }
129
+
130
+ #endif
package/src/scanner.c ADDED
@@ -0,0 +1,45 @@
1
+ #include "pragma.h"
2
+
3
+ enum TokenType { PRAGMA_OPERATOR, PREPROC_ARG, PREPROC_NEWLINE };
4
+
5
+ void *tree_sitter_c_external_scanner_create(void) {
6
+ return NULL;
7
+ }
8
+
9
+ void tree_sitter_c_external_scanner_destroy(void *payload) {
10
+ (void)payload;
11
+ }
12
+
13
+ unsigned tree_sitter_c_external_scanner_serialize(void *payload, char *buffer) {
14
+ (void)payload;
15
+ (void)buffer;
16
+ return 0;
17
+ }
18
+
19
+ void tree_sitter_c_external_scanner_deserialize(void *payload, const char *buffer, unsigned length) {
20
+ (void)payload;
21
+ (void)buffer;
22
+ (void)length;
23
+ }
24
+
25
+ bool tree_sitter_c_external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols) {
26
+ (void)payload;
27
+ if (valid_symbols[PREPROC_NEWLINE]) {
28
+ while (pragma_space(lexer->lookahead) && lexer->lookahead != '\n' && lexer->lookahead != '\r') {
29
+ lexer->advance(lexer, true);
30
+ }
31
+ if (lexer->lookahead == '\r') lexer->advance(lexer, false);
32
+ if (lexer->lookahead == '\n') {
33
+ lexer->advance(lexer, false);
34
+ lexer->mark_end(lexer);
35
+ lexer->result_symbol = PREPROC_NEWLINE;
36
+ return true;
37
+ }
38
+ }
39
+ if (valid_symbols[PREPROC_ARG]) {
40
+ lexer->result_symbol = PREPROC_ARG;
41
+ return scan_pragma_preproc_arg(lexer);
42
+ }
43
+ lexer->result_symbol = PRAGMA_OPERATOR;
44
+ return valid_symbols[PRAGMA_OPERATOR] && scan_pragma(lexer);
45
+ }
Binary file
package/tree-sitter.json CHANGED
@@ -16,7 +16,7 @@
16
16
  }
17
17
  ],
18
18
  "metadata": {
19
- "version": "1.2.0",
19
+ "version": "1.3.0",
20
20
  "license": "MIT",
21
21
  "description": "C grammar for tree-sitter",
22
22
  "authors": [