@willbooster/tree-sitter-c 1.1.7 → 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
  ),
@@ -796,7 +859,10 @@ module.exports = Object.assign(
796
859
  case_statement: ($) =>
797
860
  prec.right(
798
861
  seq(
799
- choice(seq('case', field('value', $.expression)), 'default'),
862
+ choice(
863
+ seq('case', field('value', $.expression), optional(seq('...', field('end_value', $.expression)))),
864
+ 'default'
865
+ ),
800
866
  ':',
801
867
  repeat(choice($._non_case_statement, $.declaration, $.type_definition))
802
868
  )
@@ -825,7 +891,15 @@ module.exports = Object.assign(
825
891
 
826
892
  continue_statement: () => seq('continue', ';'),
827
893
 
828
- 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
+ ),
829
903
 
830
904
  seh_try_statement: ($) =>
831
905
  seq('__try', field('body', $.compound_statement), choice($.seh_except_clause, $.seh_finally_clause)),
@@ -1075,8 +1149,47 @@ module.exports = Object.assign(
1075
1149
 
1076
1150
  parenthesized_expression: ($) => seq('(', choice($.expression, $.comma_expression, $.compound_statement), ')'),
1077
1151
 
1078
- initializer_list: ($) =>
1079
- 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),
1080
1193
 
1081
1194
  initializer_pair: ($) =>
1082
1195
  choice(
@@ -1150,7 +1263,22 @@ module.exports = Object.assign(
1150
1263
 
1151
1264
  escape_sequence: () =>
1152
1265
  token(
1153
- 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
+ )
1154
1282
  ),
1155
1283
 
1156
1284
  system_lib_string: () => token(seq('<', repeat(choice(/[^>\n]/, String.raw`\>`)), '>')),
@@ -1166,18 +1294,29 @@ module.exports = Object.assign(
1166
1294
  _field_identifier: ($) => alias($.identifier, sym('field_identifier')),
1167
1295
  _statement_identifier: ($) => alias($.identifier, sym('statement_identifier')),
1168
1296
 
1169
- _empty_declaration: ($) => seq($.type_specifier, ';'),
1297
+ _empty_declaration: ($) => seq(repeat($.ms_declspec_modifier), $.type_specifier, ';'),
1170
1298
 
1171
1299
  macro_type_specifier: ($) =>
1172
1300
  prec.dynamic(-1, seq(field('name', $.identifier), '(', field('type', $.type_descriptor), ')')),
1173
1301
 
1174
1302
  // http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890
1175
- comment: () => token(choice(seq('//', /(\\+(.|\r?\n)|[^\\\n])*/), seq('/*', /[^*]*\*+([^/*][^*]*\*+)*/, '/'))),
1303
+ comment: () => token(choice(LINE_COMMENT, seq('/*', /[^*]*\*+([^/*][^*]*\*+)*/, '/'))),
1176
1304
  },
1177
1305
  }),
1178
1306
  { PREC, preprocIf, preprocessor, commaSep, commaSep1 }
1179
1307
  );
1180
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
+
1181
1320
  /**
1182
1321
  *
1183
1322
  * @param {string} suffix
@@ -1185,10 +1324,11 @@ module.exports = Object.assign(
1185
1324
  * @param {import('./types/treeSitterDsl').RuleBuilder<string>} content
1186
1325
  *
1187
1326
  * @param {number} precedence
1327
+ * @param {boolean} repeatContent
1188
1328
  *
1189
1329
  * @returns {import('./types/treeSitterDsl').RuleBuilders<string, string>}
1190
1330
  */
1191
- function preprocIf(suffix, content, precedence = 0) {
1331
+ function preprocIf(suffix, content, precedence = 0, repeatContent = true) {
1192
1332
  function alternativeBlock() {
1193
1333
  return choice(
1194
1334
  suffix ? alias(sym('preproc_else' + suffix), sym('preproc_else')) : sym('preproc_else'),
@@ -1204,8 +1344,8 @@ function preprocIf(suffix, content, precedence = 0) {
1204
1344
  seq(
1205
1345
  preprocessor('if'),
1206
1346
  field('condition', sym('_preproc_expression')),
1207
- '\n',
1208
- repeat(content($)),
1347
+ alias(sym('_preproc_newline'), '\n'),
1348
+ repeatContent ? repeat(content($)) : optional(content($)),
1209
1349
  field('alternative', optional(alternativeBlock())),
1210
1350
  preprocessor('endif')
1211
1351
  )
@@ -1217,13 +1357,14 @@ function preprocIf(suffix, content, precedence = 0) {
1217
1357
  seq(
1218
1358
  choice(preprocessor('ifdef'), preprocessor('ifndef')),
1219
1359
  field('name', sym('identifier')),
1220
- repeat(content($)),
1360
+ repeatContent ? repeat(content($)) : optional(content($)),
1221
1361
  field('alternative', optional(alternativeBlock())),
1222
1362
  preprocessor('endif')
1223
1363
  )
1224
1364
  ),
1225
1365
 
1226
- ['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($)))),
1227
1368
 
1228
1369
  ['preproc_elif' + suffix]: ($) =>
1229
1370
  prec(
@@ -1231,8 +1372,8 @@ function preprocIf(suffix, content, precedence = 0) {
1231
1372
  seq(
1232
1373
  preprocessor('elif'),
1233
1374
  field('condition', sym('_preproc_expression')),
1234
- '\n',
1235
- repeat(content($)),
1375
+ alias(sym('_preproc_newline'), '\n'),
1376
+ repeatContent ? repeat(content($)) : optional(content($)),
1236
1377
  field('alternative', optional(alternativeBlock()))
1237
1378
  )
1238
1379
  ),
@@ -1243,7 +1384,7 @@ function preprocIf(suffix, content, precedence = 0) {
1243
1384
  seq(
1244
1385
  choice(preprocessor('elifdef'), preprocessor('elifndef')),
1245
1386
  field('name', sym('identifier')),
1246
- repeat(content($)),
1387
+ repeatContent ? repeat(content($)) : optional(content($)),
1247
1388
  field('alternative', optional(alternativeBlock()))
1248
1389
  )
1249
1390
  ),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willbooster/tree-sitter-c",
3
- "version": "1.1.7",
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,
@@ -943,6 +970,16 @@
943
970
  "type": "case_statement",
944
971
  "named": true,
945
972
  "fields": {
973
+ "end_value": {
974
+ "multiple": false,
975
+ "required": false,
976
+ "types": [
977
+ {
978
+ "type": "expression",
979
+ "named": true
980
+ }
981
+ ]
982
+ },
946
983
  "value": {
947
984
  "multiple": false,
948
985
  "required": false,
@@ -1150,6 +1187,10 @@
1150
1187
  "type": "linkage_specification",
1151
1188
  "named": true
1152
1189
  },
1190
+ {
1191
+ "type": "ms_declspec_modifier",
1192
+ "named": true
1193
+ },
1153
1194
  {
1154
1195
  "type": "preproc_call",
1155
1196
  "named": true
@@ -1301,7 +1342,7 @@
1301
1342
  },
1302
1343
  "type": {
1303
1344
  "multiple": false,
1304
- "required": true,
1345
+ "required": false,
1305
1346
  "types": [
1306
1347
  {
1307
1348
  "type": "type_specifier",
@@ -1357,6 +1398,10 @@
1357
1398
  "type": "linkage_specification",
1358
1399
  "named": true
1359
1400
  },
1401
+ {
1402
+ "type": "ms_declspec_modifier",
1403
+ "named": true
1404
+ },
1360
1405
  {
1361
1406
  "type": "preproc_call",
1362
1407
  "named": true
@@ -1468,6 +1513,18 @@
1468
1513
  {
1469
1514
  "type": "primitive_type",
1470
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
1471
1528
  }
1472
1529
  ]
1473
1530
  }
@@ -2146,6 +2203,14 @@
2146
2203
  "multiple": false,
2147
2204
  "required": true,
2148
2205
  "types": [
2206
+ {
2207
+ "type": "comma_expression",
2208
+ "named": true
2209
+ },
2210
+ {
2211
+ "type": "expression",
2212
+ "named": true
2213
+ },
2149
2214
  {
2150
2215
  "type": "statement_identifier",
2151
2216
  "named": true
@@ -2239,6 +2304,26 @@
2239
2304
  {
2240
2305
  "type": "initializer_pair",
2241
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
2242
2327
  }
2243
2328
  ]
2244
2329
  }
@@ -2865,6 +2950,10 @@
2865
2950
  "type": "enumerator",
2866
2951
  "named": true
2867
2952
  },
2953
+ {
2954
+ "type": "expression",
2955
+ "named": true
2956
+ },
2868
2957
  {
2869
2958
  "type": "field_declaration",
2870
2959
  "named": true
@@ -2873,10 +2962,22 @@
2873
2962
  "type": "function_definition",
2874
2963
  "named": true
2875
2964
  },
2965
+ {
2966
+ "type": "initializer_list",
2967
+ "named": true
2968
+ },
2969
+ {
2970
+ "type": "initializer_pair",
2971
+ "named": true
2972
+ },
2876
2973
  {
2877
2974
  "type": "linkage_specification",
2878
2975
  "named": true
2879
2976
  },
2977
+ {
2978
+ "type": "ms_declspec_modifier",
2979
+ "named": true
2980
+ },
2880
2981
  {
2881
2982
  "type": "preproc_call",
2882
2983
  "named": true
@@ -2961,6 +3062,10 @@
2961
3062
  "type": "enumerator",
2962
3063
  "named": true
2963
3064
  },
3065
+ {
3066
+ "type": "expression",
3067
+ "named": true
3068
+ },
2964
3069
  {
2965
3070
  "type": "field_declaration",
2966
3071
  "named": true
@@ -2969,10 +3074,22 @@
2969
3074
  "type": "function_definition",
2970
3075
  "named": true
2971
3076
  },
3077
+ {
3078
+ "type": "initializer_list",
3079
+ "named": true
3080
+ },
3081
+ {
3082
+ "type": "initializer_pair",
3083
+ "named": true
3084
+ },
2972
3085
  {
2973
3086
  "type": "linkage_specification",
2974
3087
  "named": true
2975
3088
  },
3089
+ {
3090
+ "type": "ms_declspec_modifier",
3091
+ "named": true
3092
+ },
2976
3093
  {
2977
3094
  "type": "preproc_call",
2978
3095
  "named": true
@@ -3028,6 +3145,10 @@
3028
3145
  "type": "enumerator",
3029
3146
  "named": true
3030
3147
  },
3148
+ {
3149
+ "type": "expression",
3150
+ "named": true
3151
+ },
3031
3152
  {
3032
3153
  "type": "field_declaration",
3033
3154
  "named": true
@@ -3036,10 +3157,22 @@
3036
3157
  "type": "function_definition",
3037
3158
  "named": true
3038
3159
  },
3160
+ {
3161
+ "type": "initializer_list",
3162
+ "named": true
3163
+ },
3164
+ {
3165
+ "type": "initializer_pair",
3166
+ "named": true
3167
+ },
3039
3168
  {
3040
3169
  "type": "linkage_specification",
3041
3170
  "named": true
3042
3171
  },
3172
+ {
3173
+ "type": "ms_declspec_modifier",
3174
+ "named": true
3175
+ },
3043
3176
  {
3044
3177
  "type": "preproc_call",
3045
3178
  "named": true
@@ -3188,6 +3321,10 @@
3188
3321
  "type": "enumerator",
3189
3322
  "named": true
3190
3323
  },
3324
+ {
3325
+ "type": "expression",
3326
+ "named": true
3327
+ },
3191
3328
  {
3192
3329
  "type": "field_declaration",
3193
3330
  "named": true
@@ -3196,10 +3333,22 @@
3196
3333
  "type": "function_definition",
3197
3334
  "named": true
3198
3335
  },
3336
+ {
3337
+ "type": "initializer_list",
3338
+ "named": true
3339
+ },
3340
+ {
3341
+ "type": "initializer_pair",
3342
+ "named": true
3343
+ },
3199
3344
  {
3200
3345
  "type": "linkage_specification",
3201
3346
  "named": true
3202
3347
  },
3348
+ {
3349
+ "type": "ms_declspec_modifier",
3350
+ "named": true
3351
+ },
3203
3352
  {
3204
3353
  "type": "preproc_call",
3205
3354
  "named": true
@@ -3284,6 +3433,10 @@
3284
3433
  "type": "enumerator",
3285
3434
  "named": true
3286
3435
  },
3436
+ {
3437
+ "type": "expression",
3438
+ "named": true
3439
+ },
3287
3440
  {
3288
3441
  "type": "field_declaration",
3289
3442
  "named": true
@@ -3292,10 +3445,22 @@
3292
3445
  "type": "function_definition",
3293
3446
  "named": true
3294
3447
  },
3448
+ {
3449
+ "type": "initializer_list",
3450
+ "named": true
3451
+ },
3452
+ {
3453
+ "type": "initializer_pair",
3454
+ "named": true
3455
+ },
3295
3456
  {
3296
3457
  "type": "linkage_specification",
3297
3458
  "named": true
3298
3459
  },
3460
+ {
3461
+ "type": "ms_declspec_modifier",
3462
+ "named": true
3463
+ },
3299
3464
  {
3300
3465
  "type": "preproc_call",
3301
3466
  "named": true
@@ -3482,6 +3647,10 @@
3482
3647
  "multiple": false,
3483
3648
  "required": false,
3484
3649
  "types": [
3650
+ {
3651
+ "type": "bit_int_specifier",
3652
+ "named": true
3653
+ },
3485
3654
  {
3486
3655
  "type": "primitive_type",
3487
3656
  "named": true
@@ -3752,6 +3921,10 @@
3752
3921
  "type": "linkage_specification",
3753
3922
  "named": true
3754
3923
  },
3924
+ {
3925
+ "type": "ms_declspec_modifier",
3926
+ "named": true
3927
+ },
3755
3928
  {
3756
3929
  "type": "preproc_call",
3757
3930
  "named": true
@@ -3890,6 +4063,29 @@
3890
4063
  ]
3891
4064
  }
3892
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
+ },
3893
4089
  {
3894
4090
  "type": "unary_expression",
3895
4091
  "named": true,
@@ -4289,10 +4485,22 @@
4289
4485
  "type": "_Atomic",
4290
4486
  "named": false
4291
4487
  },
4488
+ {
4489
+ "type": "_BitInt",
4490
+ "named": false
4491
+ },
4492
+ {
4493
+ "type": "_Complex",
4494
+ "named": false
4495
+ },
4292
4496
  {
4293
4497
  "type": "_Generic",
4294
4498
  "named": false
4295
4499
  },
4500
+ {
4501
+ "type": "_Imaginary",
4502
+ "named": false
4503
+ },
4296
4504
  {
4297
4505
  "type": "_Nonnull",
4298
4506
  "named": false
@@ -4301,6 +4509,10 @@
4301
4509
  "type": "_Noreturn",
4302
4510
  "named": false
4303
4511
  },
4512
+ {
4513
+ "type": "_Thread_local",
4514
+ "named": false
4515
+ },
4304
4516
  {
4305
4517
  "type": "__alignof",
4306
4518
  "named": false
@@ -4341,6 +4553,10 @@
4341
4553
  "type": "__clrcall",
4342
4554
  "named": false
4343
4555
  },
4556
+ {
4557
+ "type": "__complex__",
4558
+ "named": false
4559
+ },
4344
4560
  {
4345
4561
  "type": "__declspec",
4346
4562
  "named": false
@@ -4405,6 +4621,22 @@
4405
4621
  "type": "__try",
4406
4622
  "named": false
4407
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
+ },
4408
4640
  {
4409
4641
  "type": "__unaligned",
4410
4642
  "named": false
@@ -4558,6 +4790,11 @@
4558
4790
  "type": "offsetof",
4559
4791
  "named": false
4560
4792
  },
4793
+ {
4794
+ "type": "pragma_operator",
4795
+ "named": true,
4796
+ "extra": true
4797
+ },
4561
4798
  {
4562
4799
  "type": "preproc_arg",
4563
4800
  "named": true
@@ -4634,6 +4871,14 @@
4634
4871
  "type": "typedef",
4635
4872
  "named": false
4636
4873
  },
4874
+ {
4875
+ "type": "typeof",
4876
+ "named": false
4877
+ },
4878
+ {
4879
+ "type": "typeof_unqual",
4880
+ "named": false
4881
+ },
4637
4882
  {
4638
4883
  "type": "u\"",
4639
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.1.7",
19
+ "version": "1.3.0",
20
20
  "license": "MIT",
21
21
  "description": "C grammar for tree-sitter",
22
22
  "authors": [