@willbooster/tree-sitter-c 1.2.0 → 1.4.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],
@@ -58,9 +67,14 @@ module.exports = Object.assign(
58
67
  [$._top_level_item, $._top_level_statement],
59
68
  [$.type_specifier, $._top_level_expression_statement],
60
69
  [$.type_qualifier, $.extension_expression],
70
+ [$.storage_class_specifier, $.type_specifier],
71
+ [$._compound_literal_storage_class_specifier, $.type_specifier],
72
+ [$._compound_literal_constexpr_specifier, $.type_qualifier],
61
73
  ],
62
74
 
63
- extras: ($) => [/\s|\\\r?\n/, $.comment],
75
+ externals: () => [sym('pragma_operator'), sym('preproc_arg'), sym('_preproc_newline')],
76
+
77
+ extras: ($) => [$.pragma_operator, /\s|\\\r?\n/, $.comment],
64
78
 
65
79
  inline: ($) => [
66
80
  $._type_identifier,
@@ -123,6 +137,23 @@ module.exports = Object.assign(
123
137
  $.preproc_call
124
138
  ),
125
139
 
140
+ // Derived grammars that replace externals still need this lexical fallback. Comment-rich spacing makes the
141
+ // lexer too large for the pinned Node Wasm optimizer; the external scanner handles those forms.
142
+ pragma_operator: () =>
143
+ token(
144
+ seq(
145
+ '_Pragma',
146
+ PRAGMA_SPACING,
147
+ '(',
148
+ PRAGMA_SPACING,
149
+ optional(choice('L', 'u8', 'u', 'U')),
150
+ '"',
151
+ repeat(choice(/[^\\"\n]/, seq('\\', choice(/./, /\r?\n/)))),
152
+ '"',
153
+ PRAGMA_SPACING,
154
+ ')'
155
+ )
156
+ ),
126
157
  // Preprocesser
127
158
 
128
159
  preproc_include: ($) =>
@@ -137,7 +168,7 @@ module.exports = Object.assign(
137
168
  alias($.preproc_call_expression, $.call_expression)
138
169
  )
139
170
  ),
140
- token.immediate(/\r?\n/)
171
+ sym('_preproc_newline')
141
172
  ),
142
173
 
143
174
  preproc_def: ($) =>
@@ -145,7 +176,7 @@ module.exports = Object.assign(
145
176
  preprocessor('define'),
146
177
  field('name', $.identifier),
147
178
  field('value', optional($.preproc_arg)),
148
- token.immediate(/\r?\n/)
179
+ sym('_preproc_newline')
149
180
  ),
150
181
 
151
182
  preproc_function_def: ($) =>
@@ -154,7 +185,7 @@ module.exports = Object.assign(
154
185
  field('name', $.identifier),
155
186
  field('parameters', $.preproc_params),
156
187
  field('value', optional($.preproc_arg)),
157
- token.immediate(/\r?\n/)
188
+ sym('_preproc_newline')
158
189
  ),
159
190
 
160
191
  preproc_params: ($) => seq(token.immediate('('), commaSep(choice($.identifier, '...')), ')'),
@@ -163,7 +194,7 @@ module.exports = Object.assign(
163
194
  seq(
164
195
  field('directive', $.preproc_directive),
165
196
  field('argument', optional($.preproc_arg)),
166
- token.immediate(/\r?\n/)
197
+ sym('_preproc_newline')
167
198
  ),
168
199
 
169
200
  ...preprocIf('', () => sym('_block_item')),
@@ -171,6 +202,8 @@ module.exports = Object.assign(
171
202
  ...preprocIf('_in_enumerator_list', () => seq(sym('enumerator'), ',')),
172
203
  ...preprocIf('_in_enumerator_list_no_comma', () => sym('enumerator'), -1),
173
204
 
205
+ _preproc_newline: () => token.immediate(/\r?\n/),
206
+
174
207
  preproc_arg: () => token(prec(-1, /\S([^/\n]|\/[^*]|\\\r?\n)*/)),
175
208
  preproc_directive: () => /#[ \t]*[a-zA-Z0-9]\w*/,
176
209
 
@@ -203,7 +236,8 @@ module.exports = Object.assign(
203
236
  seq(field('function', $.identifier), field('arguments', alias($.preproc_argument_list, $.argument_list)))
204
237
  ),
205
238
 
206
- preproc_argument_list: ($) => seq('(', commaSep($._preproc_expression), ')'),
239
+ preproc_argument_list: ($) =>
240
+ seq('(', commaSep(choice($._preproc_expression, $.system_lib_string, $.string_literal)), ')'),
207
241
 
208
242
  preproc_binary_expression: ($) => {
209
243
  /** @type {[string, number][]} */
@@ -264,7 +298,17 @@ module.exports = Object.assign(
264
298
 
265
299
  declaration: ($) =>
266
300
  seq(
267
- $._declaration_specifiers,
301
+ choice(
302
+ $._declaration_specifiers,
303
+ prec.dynamic(
304
+ PREC.PAREN_DECLARATOR - 1,
305
+ seq(
306
+ repeat($._declaration_modifiers),
307
+ alias('auto', $.storage_class_specifier),
308
+ repeat($._declaration_modifiers)
309
+ )
310
+ )
311
+ ),
268
312
  commaSep1(
269
313
  field(
270
314
  'declarator',
@@ -560,6 +604,7 @@ module.exports = Object.assign(
560
604
  '__inline__',
561
605
  '__forceinline',
562
606
  'thread_local',
607
+ '_Thread_local',
563
608
  '__thread'
564
609
  ),
565
610
 
@@ -585,26 +630,29 @@ module.exports = Object.assign(
585
630
  $.struct_specifier,
586
631
  $.union_specifier,
587
632
  $.enum_specifier,
633
+ $.typeof_specifier,
634
+ $.bit_int_specifier,
588
635
  $.macro_type_specifier,
589
636
  $.sized_type_specifier,
637
+ alias($._sized_bit_int_specifier, $.sized_type_specifier),
590
638
  $.primitive_type,
591
- $._type_identifier
639
+ $._type_identifier,
640
+ prec.dynamic(-1, alias('thread_local', sym('type_identifier')))
592
641
  ),
593
642
 
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
- )
643
+ typeof_specifier: ($) =>
644
+ seq(
645
+ choice('typeof', 'typeof_unqual', '__typeof__', '__typeof', '__typeof_unqual', '__typeof_unqual__'),
646
+ '(',
647
+ choice($.type_descriptor, $.expression, $.comma_expression),
648
+ ')'
607
649
  ),
650
+ bit_int_specifier: ($) => seq('_BitInt', '(', $.expression, ')'),
651
+
652
+ sized_type_specifier: ($) =>
653
+ sizedTypeSpecifier(optional(choice(prec.dynamic(-1, $._type_identifier), $.primitive_type))),
654
+
655
+ _sized_bit_int_specifier: ($) => sizedTypeSpecifier($.bit_int_specifier),
608
656
 
609
657
  primitive_type: () =>
610
658
  token(
@@ -635,10 +683,29 @@ module.exports = Object.assign(
635
683
  choice(
636
684
  seq(
637
685
  field('name', $._type_identifier),
638
- optional(seq(':', field('underlying_type', $.primitive_type))),
686
+ optional(
687
+ seq(
688
+ ':',
689
+ field(
690
+ 'underlying_type',
691
+ choice($.primitive_type, $.sized_type_specifier, $.typeof_specifier, $._type_identifier)
692
+ )
693
+ )
694
+ ),
639
695
  field('body', optional($.enumerator_list))
640
696
  ),
641
- field('body', $.enumerator_list)
697
+ seq(
698
+ optional(
699
+ seq(
700
+ ':',
701
+ field(
702
+ 'underlying_type',
703
+ choice($.primitive_type, $.sized_type_specifier, $.typeof_specifier, $._type_identifier)
704
+ )
705
+ )
706
+ ),
707
+ field('body', $.enumerator_list)
708
+ )
642
709
  ),
643
710
  optional($.attribute_specifier)
644
711
  ),
@@ -828,7 +895,15 @@ module.exports = Object.assign(
828
895
 
829
896
  continue_statement: () => seq('continue', ';'),
830
897
 
831
- goto_statement: ($) => seq('goto', field('label', $._statement_identifier), ';'),
898
+ goto_statement: ($) =>
899
+ seq(
900
+ 'goto',
901
+ choice(
902
+ field('label', $._statement_identifier),
903
+ seq('*', field('label', choice($.expression, $.comma_expression)))
904
+ ),
905
+ ';'
906
+ ),
832
907
 
833
908
  seh_try_statement: ($) =>
834
909
  seq('__try', field('body', $.compound_statement), choice($.seh_except_clause, $.seh_finally_clause)),
@@ -861,6 +936,7 @@ module.exports = Object.assign(
861
936
  $.field_expression,
862
937
  $.compound_literal_expression,
863
938
  $.identifier,
939
+ alias('thread_local', $.identifier),
864
940
  $.number_literal,
865
941
  $._string,
866
942
  $.true,
@@ -1074,12 +1150,69 @@ module.exports = Object.assign(
1074
1150
  ),
1075
1151
 
1076
1152
  compound_literal_expression: ($) =>
1077
- seq('(', field('type', $.type_descriptor), ')', field('value', $.initializer_list)),
1153
+ seq(
1154
+ '(',
1155
+ repeat(
1156
+ seq(
1157
+ optional(
1158
+ field('storage_class', alias($._compound_literal_constexpr_specifier, $.storage_class_specifier))
1159
+ ),
1160
+ field('storage_class', alias($._compound_literal_storage_class_specifier, $.storage_class_specifier))
1161
+ )
1162
+ ),
1163
+ field('type', $.type_descriptor),
1164
+ ')',
1165
+ field('value', $.initializer_list)
1166
+ ),
1167
+
1168
+ _compound_literal_constexpr_specifier: () => 'constexpr',
1169
+
1170
+ _compound_literal_storage_class_specifier: () =>
1171
+ choice('static', 'register', 'thread_local', '_Thread_local', '__thread'),
1078
1172
 
1079
1173
  parenthesized_expression: ($) => seq('(', choice($.expression, $.comma_expression, $.compound_statement), ')'),
1080
1174
 
1081
- initializer_list: ($) =>
1082
- seq('{', commaSep(choice($.initializer_pair, $.expression, $.initializer_list)), optional(','), '}'),
1175
+ initializer_list: ($) => seq('{', optional($._initializer_sequence), '}'),
1176
+
1177
+ _initializer_sequence: ($) =>
1178
+ choice(
1179
+ seq(
1180
+ $._initializer_element,
1181
+ optional(choice(seq(',', optional($._initializer_sequence)), $._initializer_directives))
1182
+ ),
1183
+ $._initializer_directives
1184
+ ),
1185
+
1186
+ _initializer_directives: ($) =>
1187
+ seq(
1188
+ $._initializer_directive,
1189
+ optional(choice($._initializer_sequence, seq(',', optional($._initializer_sequence))))
1190
+ ),
1191
+
1192
+ _initializer_directive: ($) =>
1193
+ choice(
1194
+ alias(sym('preproc_if_in_initializer_list'), sym('preproc_if')),
1195
+ alias(sym('preproc_ifdef_in_initializer_list'), sym('preproc_ifdef')),
1196
+ $.preproc_def,
1197
+ $.preproc_function_def,
1198
+ alias($._initializer_preproc_call, $.preproc_call)
1199
+ ),
1200
+
1201
+ _initializer_element: ($) => choice($.initializer_pair, $.expression, $.initializer_list),
1202
+
1203
+ _initializer_branch: ($) => choice(seq(',', optional($._initializer_sequence)), $._initializer_sequence),
1204
+
1205
+ _initializer_preproc_call: ($) =>
1206
+ seq(
1207
+ field(
1208
+ 'directive',
1209
+ alias(token(/#[ \t]*(embed|include|undef|error|warning|line|pragma)/), $.preproc_directive)
1210
+ ),
1211
+ field('argument', optional($.preproc_arg)),
1212
+ alias(sym('_preproc_newline'), '\n')
1213
+ ),
1214
+
1215
+ ...preprocIf('_in_initializer_list', () => sym('_initializer_branch'), 0, false),
1083
1216
 
1084
1217
  initializer_pair: ($) =>
1085
1218
  choice(
@@ -1153,7 +1286,22 @@ module.exports = Object.assign(
1153
1286
 
1154
1287
  escape_sequence: () =>
1155
1288
  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}/)))
1289
+ prec(
1290
+ 1,
1291
+ seq(
1292
+ '\\',
1293
+ choice(
1294
+ /[^xuU]/,
1295
+ /[xu]\{[0-9a-fA-F]+\}/,
1296
+ /o\{[0-7]+\}/,
1297
+ /N\{[^}\n]+\}/,
1298
+ /\d{2,3}/,
1299
+ /x[0-9a-fA-F]{1,4}/,
1300
+ /u[0-9a-fA-F]{4}/,
1301
+ /U[0-9a-fA-F]{8}/
1302
+ )
1303
+ )
1304
+ )
1157
1305
  ),
1158
1306
 
1159
1307
  system_lib_string: () => token(seq('<', repeat(choice(/[^>\n]/, String.raw`\>`)), '>')),
@@ -1169,18 +1317,29 @@ module.exports = Object.assign(
1169
1317
  _field_identifier: ($) => alias($.identifier, sym('field_identifier')),
1170
1318
  _statement_identifier: ($) => alias($.identifier, sym('statement_identifier')),
1171
1319
 
1172
- _empty_declaration: ($) => seq($.type_specifier, ';'),
1320
+ _empty_declaration: ($) => seq(repeat($.ms_declspec_modifier), $.type_specifier, ';'),
1173
1321
 
1174
1322
  macro_type_specifier: ($) =>
1175
1323
  prec.dynamic(-1, seq(field('name', $.identifier), '(', field('type', $.type_descriptor), ')')),
1176
1324
 
1177
1325
  // http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890
1178
- comment: () => token(choice(seq('//', /(\\+(.|\r?\n)|[^\\\n])*/), seq('/*', /[^*]*\*+([^/*][^*]*\*+)*/, '/'))),
1326
+ comment: () => token(choice(LINE_COMMENT, seq('/*', /[^*]*\*+([^/*][^*]*\*+)*/, '/'))),
1179
1327
  },
1180
1328
  }),
1181
1329
  { PREC, preprocIf, preprocessor, commaSep, commaSep1 }
1182
1330
  );
1183
1331
 
1332
+ /**
1333
+ * @param {import('./types/treeSitterDsl').RuleOrLiteral} type
1334
+ */
1335
+ function sizedTypeSpecifier(type) {
1336
+ const modifier = choice('signed', 'unsigned', 'long', 'short', '_Complex', '_Imaginary', '__complex__');
1337
+ return choice(
1338
+ seq(repeat(modifier), field('type', type), repeat1(modifier)),
1339
+ seq(repeat1(modifier), repeat(sym('type_qualifier')), field('type', type), repeat(modifier))
1340
+ );
1341
+ }
1342
+
1184
1343
  /**
1185
1344
  *
1186
1345
  * @param {string} suffix
@@ -1188,10 +1347,11 @@ module.exports = Object.assign(
1188
1347
  * @param {import('./types/treeSitterDsl').RuleBuilder<string>} content
1189
1348
  *
1190
1349
  * @param {number} precedence
1350
+ * @param {boolean} repeatContent
1191
1351
  *
1192
1352
  * @returns {import('./types/treeSitterDsl').RuleBuilders<string, string>}
1193
1353
  */
1194
- function preprocIf(suffix, content, precedence = 0) {
1354
+ function preprocIf(suffix, content, precedence = 0, repeatContent = true) {
1195
1355
  function alternativeBlock() {
1196
1356
  return choice(
1197
1357
  suffix ? alias(sym('preproc_else' + suffix), sym('preproc_else')) : sym('preproc_else'),
@@ -1207,8 +1367,8 @@ function preprocIf(suffix, content, precedence = 0) {
1207
1367
  seq(
1208
1368
  preprocessor('if'),
1209
1369
  field('condition', sym('_preproc_expression')),
1210
- '\n',
1211
- repeat(content($)),
1370
+ alias(sym('_preproc_newline'), '\n'),
1371
+ repeatContent ? repeat(content($)) : optional(content($)),
1212
1372
  field('alternative', optional(alternativeBlock())),
1213
1373
  preprocessor('endif')
1214
1374
  )
@@ -1220,13 +1380,14 @@ function preprocIf(suffix, content, precedence = 0) {
1220
1380
  seq(
1221
1381
  choice(preprocessor('ifdef'), preprocessor('ifndef')),
1222
1382
  field('name', sym('identifier')),
1223
- repeat(content($)),
1383
+ repeatContent ? repeat(content($)) : optional(content($)),
1224
1384
  field('alternative', optional(alternativeBlock())),
1225
1385
  preprocessor('endif')
1226
1386
  )
1227
1387
  ),
1228
1388
 
1229
- ['preproc_else' + suffix]: ($) => prec(precedence, seq(preprocessor('else'), repeat(content($)))),
1389
+ ['preproc_else' + suffix]: ($) =>
1390
+ prec(precedence, seq(preprocessor('else'), repeatContent ? repeat(content($)) : optional(content($)))),
1230
1391
 
1231
1392
  ['preproc_elif' + suffix]: ($) =>
1232
1393
  prec(
@@ -1234,8 +1395,8 @@ function preprocIf(suffix, content, precedence = 0) {
1234
1395
  seq(
1235
1396
  preprocessor('elif'),
1236
1397
  field('condition', sym('_preproc_expression')),
1237
- '\n',
1238
- repeat(content($)),
1398
+ alias(sym('_preproc_newline'), '\n'),
1399
+ repeatContent ? repeat(content($)) : optional(content($)),
1239
1400
  field('alternative', optional(alternativeBlock()))
1240
1401
  )
1241
1402
  ),
@@ -1246,7 +1407,7 @@ function preprocIf(suffix, content, precedence = 0) {
1246
1407
  seq(
1247
1408
  choice(preprocessor('elifdef'), preprocessor('elifndef')),
1248
1409
  field('name', sym('identifier')),
1249
- repeat(content($)),
1410
+ repeatContent ? repeat(content($)) : optional(content($)),
1250
1411
  field('alternative', optional(alternativeBlock()))
1251
1412
  )
1252
1413
  ),
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.4.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,
@@ -1118,6 +1145,16 @@
1118
1145
  "type": "compound_literal_expression",
1119
1146
  "named": true,
1120
1147
  "fields": {
1148
+ "storage_class": {
1149
+ "multiple": true,
1150
+ "required": false,
1151
+ "types": [
1152
+ {
1153
+ "type": "storage_class_specifier",
1154
+ "named": true
1155
+ }
1156
+ ]
1157
+ },
1121
1158
  "type": {
1122
1159
  "multiple": false,
1123
1160
  "required": true,
@@ -1160,6 +1197,10 @@
1160
1197
  "type": "linkage_specification",
1161
1198
  "named": true
1162
1199
  },
1200
+ {
1201
+ "type": "ms_declspec_modifier",
1202
+ "named": true
1203
+ },
1163
1204
  {
1164
1205
  "type": "preproc_call",
1165
1206
  "named": true
@@ -1311,7 +1352,7 @@
1311
1352
  },
1312
1353
  "type": {
1313
1354
  "multiple": false,
1314
- "required": true,
1355
+ "required": false,
1315
1356
  "types": [
1316
1357
  {
1317
1358
  "type": "type_specifier",
@@ -1367,6 +1408,10 @@
1367
1408
  "type": "linkage_specification",
1368
1409
  "named": true
1369
1410
  },
1411
+ {
1412
+ "type": "ms_declspec_modifier",
1413
+ "named": true
1414
+ },
1370
1415
  {
1371
1416
  "type": "preproc_call",
1372
1417
  "named": true
@@ -1478,6 +1523,18 @@
1478
1523
  {
1479
1524
  "type": "primitive_type",
1480
1525
  "named": true
1526
+ },
1527
+ {
1528
+ "type": "sized_type_specifier",
1529
+ "named": true
1530
+ },
1531
+ {
1532
+ "type": "type_identifier",
1533
+ "named": true
1534
+ },
1535
+ {
1536
+ "type": "typeof_specifier",
1537
+ "named": true
1481
1538
  }
1482
1539
  ]
1483
1540
  }
@@ -2156,6 +2213,14 @@
2156
2213
  "multiple": false,
2157
2214
  "required": true,
2158
2215
  "types": [
2216
+ {
2217
+ "type": "comma_expression",
2218
+ "named": true
2219
+ },
2220
+ {
2221
+ "type": "expression",
2222
+ "named": true
2223
+ },
2159
2224
  {
2160
2225
  "type": "statement_identifier",
2161
2226
  "named": true
@@ -2249,6 +2314,26 @@
2249
2314
  {
2250
2315
  "type": "initializer_pair",
2251
2316
  "named": true
2317
+ },
2318
+ {
2319
+ "type": "preproc_call",
2320
+ "named": true
2321
+ },
2322
+ {
2323
+ "type": "preproc_def",
2324
+ "named": true
2325
+ },
2326
+ {
2327
+ "type": "preproc_function_def",
2328
+ "named": true
2329
+ },
2330
+ {
2331
+ "type": "preproc_if",
2332
+ "named": true
2333
+ },
2334
+ {
2335
+ "type": "preproc_ifdef",
2336
+ "named": true
2252
2337
  }
2253
2338
  ]
2254
2339
  }
@@ -2875,6 +2960,10 @@
2875
2960
  "type": "enumerator",
2876
2961
  "named": true
2877
2962
  },
2963
+ {
2964
+ "type": "expression",
2965
+ "named": true
2966
+ },
2878
2967
  {
2879
2968
  "type": "field_declaration",
2880
2969
  "named": true
@@ -2883,10 +2972,22 @@
2883
2972
  "type": "function_definition",
2884
2973
  "named": true
2885
2974
  },
2975
+ {
2976
+ "type": "initializer_list",
2977
+ "named": true
2978
+ },
2979
+ {
2980
+ "type": "initializer_pair",
2981
+ "named": true
2982
+ },
2886
2983
  {
2887
2984
  "type": "linkage_specification",
2888
2985
  "named": true
2889
2986
  },
2987
+ {
2988
+ "type": "ms_declspec_modifier",
2989
+ "named": true
2990
+ },
2890
2991
  {
2891
2992
  "type": "preproc_call",
2892
2993
  "named": true
@@ -2971,6 +3072,10 @@
2971
3072
  "type": "enumerator",
2972
3073
  "named": true
2973
3074
  },
3075
+ {
3076
+ "type": "expression",
3077
+ "named": true
3078
+ },
2974
3079
  {
2975
3080
  "type": "field_declaration",
2976
3081
  "named": true
@@ -2979,10 +3084,22 @@
2979
3084
  "type": "function_definition",
2980
3085
  "named": true
2981
3086
  },
3087
+ {
3088
+ "type": "initializer_list",
3089
+ "named": true
3090
+ },
3091
+ {
3092
+ "type": "initializer_pair",
3093
+ "named": true
3094
+ },
2982
3095
  {
2983
3096
  "type": "linkage_specification",
2984
3097
  "named": true
2985
3098
  },
3099
+ {
3100
+ "type": "ms_declspec_modifier",
3101
+ "named": true
3102
+ },
2986
3103
  {
2987
3104
  "type": "preproc_call",
2988
3105
  "named": true
@@ -3038,6 +3155,10 @@
3038
3155
  "type": "enumerator",
3039
3156
  "named": true
3040
3157
  },
3158
+ {
3159
+ "type": "expression",
3160
+ "named": true
3161
+ },
3041
3162
  {
3042
3163
  "type": "field_declaration",
3043
3164
  "named": true
@@ -3046,10 +3167,22 @@
3046
3167
  "type": "function_definition",
3047
3168
  "named": true
3048
3169
  },
3170
+ {
3171
+ "type": "initializer_list",
3172
+ "named": true
3173
+ },
3174
+ {
3175
+ "type": "initializer_pair",
3176
+ "named": true
3177
+ },
3049
3178
  {
3050
3179
  "type": "linkage_specification",
3051
3180
  "named": true
3052
3181
  },
3182
+ {
3183
+ "type": "ms_declspec_modifier",
3184
+ "named": true
3185
+ },
3053
3186
  {
3054
3187
  "type": "preproc_call",
3055
3188
  "named": true
@@ -3198,6 +3331,10 @@
3198
3331
  "type": "enumerator",
3199
3332
  "named": true
3200
3333
  },
3334
+ {
3335
+ "type": "expression",
3336
+ "named": true
3337
+ },
3201
3338
  {
3202
3339
  "type": "field_declaration",
3203
3340
  "named": true
@@ -3206,10 +3343,22 @@
3206
3343
  "type": "function_definition",
3207
3344
  "named": true
3208
3345
  },
3346
+ {
3347
+ "type": "initializer_list",
3348
+ "named": true
3349
+ },
3350
+ {
3351
+ "type": "initializer_pair",
3352
+ "named": true
3353
+ },
3209
3354
  {
3210
3355
  "type": "linkage_specification",
3211
3356
  "named": true
3212
3357
  },
3358
+ {
3359
+ "type": "ms_declspec_modifier",
3360
+ "named": true
3361
+ },
3213
3362
  {
3214
3363
  "type": "preproc_call",
3215
3364
  "named": true
@@ -3294,6 +3443,10 @@
3294
3443
  "type": "enumerator",
3295
3444
  "named": true
3296
3445
  },
3446
+ {
3447
+ "type": "expression",
3448
+ "named": true
3449
+ },
3297
3450
  {
3298
3451
  "type": "field_declaration",
3299
3452
  "named": true
@@ -3302,10 +3455,22 @@
3302
3455
  "type": "function_definition",
3303
3456
  "named": true
3304
3457
  },
3458
+ {
3459
+ "type": "initializer_list",
3460
+ "named": true
3461
+ },
3462
+ {
3463
+ "type": "initializer_pair",
3464
+ "named": true
3465
+ },
3305
3466
  {
3306
3467
  "type": "linkage_specification",
3307
3468
  "named": true
3308
3469
  },
3470
+ {
3471
+ "type": "ms_declspec_modifier",
3472
+ "named": true
3473
+ },
3309
3474
  {
3310
3475
  "type": "preproc_call",
3311
3476
  "named": true
@@ -3492,6 +3657,10 @@
3492
3657
  "multiple": false,
3493
3658
  "required": false,
3494
3659
  "types": [
3660
+ {
3661
+ "type": "bit_int_specifier",
3662
+ "named": true
3663
+ },
3495
3664
  {
3496
3665
  "type": "primitive_type",
3497
3666
  "named": true
@@ -3762,6 +3931,10 @@
3762
3931
  "type": "linkage_specification",
3763
3932
  "named": true
3764
3933
  },
3934
+ {
3935
+ "type": "ms_declspec_modifier",
3936
+ "named": true
3937
+ },
3765
3938
  {
3766
3939
  "type": "preproc_call",
3767
3940
  "named": true
@@ -3900,6 +4073,29 @@
3900
4073
  ]
3901
4074
  }
3902
4075
  },
4076
+ {
4077
+ "type": "typeof_specifier",
4078
+ "named": true,
4079
+ "fields": {},
4080
+ "children": {
4081
+ "multiple": false,
4082
+ "required": true,
4083
+ "types": [
4084
+ {
4085
+ "type": "comma_expression",
4086
+ "named": true
4087
+ },
4088
+ {
4089
+ "type": "expression",
4090
+ "named": true
4091
+ },
4092
+ {
4093
+ "type": "type_descriptor",
4094
+ "named": true
4095
+ }
4096
+ ]
4097
+ }
4098
+ },
3903
4099
  {
3904
4100
  "type": "unary_expression",
3905
4101
  "named": true,
@@ -4299,10 +4495,22 @@
4299
4495
  "type": "_Atomic",
4300
4496
  "named": false
4301
4497
  },
4498
+ {
4499
+ "type": "_BitInt",
4500
+ "named": false
4501
+ },
4502
+ {
4503
+ "type": "_Complex",
4504
+ "named": false
4505
+ },
4302
4506
  {
4303
4507
  "type": "_Generic",
4304
4508
  "named": false
4305
4509
  },
4510
+ {
4511
+ "type": "_Imaginary",
4512
+ "named": false
4513
+ },
4306
4514
  {
4307
4515
  "type": "_Nonnull",
4308
4516
  "named": false
@@ -4311,6 +4519,10 @@
4311
4519
  "type": "_Noreturn",
4312
4520
  "named": false
4313
4521
  },
4522
+ {
4523
+ "type": "_Thread_local",
4524
+ "named": false
4525
+ },
4314
4526
  {
4315
4527
  "type": "__alignof",
4316
4528
  "named": false
@@ -4351,6 +4563,10 @@
4351
4563
  "type": "__clrcall",
4352
4564
  "named": false
4353
4565
  },
4566
+ {
4567
+ "type": "__complex__",
4568
+ "named": false
4569
+ },
4354
4570
  {
4355
4571
  "type": "__declspec",
4356
4572
  "named": false
@@ -4415,6 +4631,22 @@
4415
4631
  "type": "__try",
4416
4632
  "named": false
4417
4633
  },
4634
+ {
4635
+ "type": "__typeof",
4636
+ "named": false
4637
+ },
4638
+ {
4639
+ "type": "__typeof__",
4640
+ "named": false
4641
+ },
4642
+ {
4643
+ "type": "__typeof_unqual",
4644
+ "named": false
4645
+ },
4646
+ {
4647
+ "type": "__typeof_unqual__",
4648
+ "named": false
4649
+ },
4418
4650
  {
4419
4651
  "type": "__unaligned",
4420
4652
  "named": false
@@ -4568,6 +4800,11 @@
4568
4800
  "type": "offsetof",
4569
4801
  "named": false
4570
4802
  },
4803
+ {
4804
+ "type": "pragma_operator",
4805
+ "named": true,
4806
+ "extra": true
4807
+ },
4571
4808
  {
4572
4809
  "type": "preproc_arg",
4573
4810
  "named": true
@@ -4644,6 +4881,14 @@
4644
4881
  "type": "typedef",
4645
4882
  "named": false
4646
4883
  },
4884
+ {
4885
+ "type": "typeof",
4886
+ "named": false
4887
+ },
4888
+ {
4889
+ "type": "typeof_unqual",
4890
+ "named": false
4891
+ },
4647
4892
  {
4648
4893
  "type": "u\"",
4649
4894
  "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.4.0",
20
20
  "license": "MIT",
21
21
  "description": "C grammar for tree-sitter",
22
22
  "authors": [