Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ Subject: Allow to parse macro identifiers in variable decls

---
grammar.js | 2 +
src/scanner.c | 128 +++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 103 insertions(+), 27 deletions(-)
src/scanner.c | 141 +++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 119 insertions(+), 24 deletions(-)

diff --git a/grammar.js b/grammar.js
index 6e79004..40ac8b7 100644
Expand All @@ -29,7 +29,7 @@ index 6e79004..40ac8b7 100644
optional(seq(',',
commaSep1(
diff --git a/src/scanner.c b/src/scanner.c
index b768d99..e477df4 100644
index b768d99..e5a37ee 100644
--- a/src/scanner.c
+++ b/src/scanner.c
@@ -1,4 +1,5 @@
Expand Down Expand Up @@ -65,10 +65,23 @@ index b768d99..e477df4 100644
+// Returns NULL on error, otherwise an allocated char array for an identifier
+static String *scan_identifier(TSLexer *lexer) {
if (!iswalpha(lexer->lookahead)) {
- return false;
+ return NULL;
+ }
}
-
- lexer->result_symbol = STRING_LITERAL_KIND;
-
- // We need two characters of lookahead to see `_"`
- char current_char = '\0';
-
+ String *possible_identifier = ts_calloc(1, sizeof(String));
+ while (is_identifier_char(lexer->lookahead) && !lexer->eof(lexer)) {
while (is_identifier_char(lexer->lookahead) && !lexer->eof(lexer)) {
- current_char = lexer->lookahead;
- // Don't capture the trailing underscore as part of the kind identifier
- if (lexer->lookahead == '_') {
- lexer->mark_end(lexer);
- }
- advance(lexer);
+ array_push(possible_identifier, lexer->lookahead);
+ // Don't capture the trailing underscore as part of the kind identifier
+ // If another user of this function wants to mark the end again after
Expand All @@ -91,32 +104,16 @@ index b768d99..e477df4 100644
+static bool scan_string_literal_kind(TSLexer *lexer, String *identifier) {
+ if (identifier->size == 0) {
+ return false;
+ }
+
}

- if ((current_char != '_') || (lexer->lookahead != '"' && lexer->lookahead != '\'')) {
+ char last_char = identifier->contents[identifier->size - 1];
+ if ((last_char != '_') ||
+ (lexer->lookahead != '"' && lexer->lookahead != '\'')) {
return false;
}

lexer->result_symbol = STRING_LITERAL_KIND;
-
- // We need two characters of lookahead to see `_"`
- char current_char = '\0';
-
- while (is_identifier_char(lexer->lookahead) && !lexer->eof(lexer)) {
- current_char = lexer->lookahead;
- // Don't capture the trailing underscore as part of the kind identifier
- if (lexer->lookahead == '_') {
- lexer->mark_end(lexer);
- }
- advance(lexer);
- }
-
- if ((current_char != '_') || (lexer->lookahead != '"' && lexer->lookahead != '\'')) {
- return false;
- }
-
+ lexer->result_symbol = STRING_LITERAL_KIND;
return true;
}

Expand Down
177 changes: 177 additions & 0 deletions codee/patches/0021-Parse-multiline-preprocessor-comments.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?I=C3=B1aki=20Amatria=20Barral?= <inaki.amatria@appentra.com>
Date: Fri, 4 Jul 2025 10:23:30 +0200
Subject: Parse multiline preprocessor comments

---
grammar.js | 32 +++++++++++++++-----
test/corpus/preprocessor.txt | 57 ++++++++++++++++++++++++++++++++++--
2 files changed, 79 insertions(+), 10 deletions(-)

diff --git a/grammar.js b/grammar.js
index 40ac8b7..b5c11d1 100644
--- a/grammar.js
+++ b/grammar.js
@@ -75,6 +75,7 @@ module.exports = grammar({
// preprocessor statements
/\s|\\\r?\n/,
$.comment,
+ $.multiline_preproc_comment,
'&',
],

@@ -248,7 +249,8 @@ module.exports = grammar({
')',
),

- preproc_comment: $ => choice(/\/\*.*\*\//, /\/\/.*/),
+ inline_preproc_comment: $ => /\/\/.*/,
+ multiline_preproc_comment: $ => /\/\*([^*]|\*+[^*/])*\*+\//,

preproc_binary_expression: $ => {
const table = [
@@ -2466,36 +2468,50 @@ function preprocIf(suffix, content, precedence = 0) {
);
}

+ /**
+ *
+ * @param {GrammarSymbols<string>} $
+ *
+ * @return {ChoiceRule}
+ *
+ */
+ function preprocComment($) {
+ return choice(
+ $.inline_preproc_comment,
+ $.multiline_preproc_comment,
+ );
+ }
+
return {
['preproc_if' + suffix]: $ => prec(precedence, seq(
preprocessor('if'),
field('condition', $._preproc_expression),
- optional($.preproc_comment),
+ optional(preprocComment($)),
field('content', content($)),
field('alternative', optional(alternativeBlock($))),
preprocessor('endif'),
- optional($.preproc_comment),
+ optional(preprocComment($)),
)),

['preproc_ifdef' + suffix]: $ => prec(precedence, seq(
choice(preprocessor('ifdef'), preprocessor('ifndef')),
field('name', $.identifier),
- optional($.preproc_comment),
+ optional(preprocComment($)),
field('content', content($)),
field('alternative', optional(alternativeBlock($))),
preprocessor('endif'),
- optional($.preproc_comment),
+ optional(preprocComment($)),
)),

['preproc_else' + suffix]: $ => prec(precedence, seq(
preprocessor('else'),
- optional($.preproc_comment),
+ optional(preprocComment($)),
field('content', content($)),
)),

['preproc_elif' + suffix]: $ => prec(precedence, seq(
preprocessor('elif'),
- optional($.preproc_comment),
+ optional(preprocComment($)),
field('condition', $._preproc_expression),
field('content', content($)),
field('alternative', optional(alternativeBlock($))),
@@ -2504,7 +2520,7 @@ function preprocIf(suffix, content, precedence = 0) {
['preproc_elifdef' + suffix]: $ => prec(precedence, seq(
choice(preprocessor('elifdef'), preprocessor('elifndef')),
field('name', $.identifier),
- optional($.preproc_comment),
+ optional(preprocComment($)),
field('content', content($)),
field('alternative', optional(alternativeBlock($))),
)),
diff --git a/test/corpus/preprocessor.txt b/test/corpus/preprocessor.txt
index 02c61bb..b0b35bd 100644
--- a/test/corpus/preprocessor.txt
+++ b/test/corpus/preprocessor.txt
@@ -169,7 +169,7 @@ end subroutine foo4
content: (preproc_def
name: (identifier)
value: (preproc_arg))))
- (preproc_comment))
+ (multiline_preproc_comment))
(preproc_ifdef
name: (identifier)
content: (subroutine
@@ -179,7 +179,7 @@ end subroutine foo4
(end_subroutine_statement
(name)
(end_of_statement)))
- (preproc_comment)))
+ (inline_preproc_comment)))

================================================================================
Elifdefs
@@ -991,3 +991,56 @@ Preprocessor in specification part
(end_subroutine_statement
(name)
(end_of_statement))))
+
+================================================================================
+Multiline preprocessor comments
+================================================================================
+
+/* Foo */
+#ifdef FOO
+#endif
+
+ PROGRAM MAIN
+ INTEGER /* FOO */ FOO
+ INTEGER BAR /* BAR */
+ INTEGER /* B
+ A
+ Z */ BAZ
+ END
+
+/* Foo
+// Bar
+Baz */
+#ifdef BAR
+#endif
+
+--------------------------------------------------------------------------------
+
+(translation_unit
+ (multiline_preproc_comment)
+ (preproc_ifdef
+ (identifier))
+ (program
+ (program_statement
+ (name)
+ (end_of_statement))
+ (variable_declaration
+ (intrinsic_type)
+ (multiline_preproc_comment)
+ (identifier))
+ (end_of_statement)
+ (variable_declaration
+ (intrinsic_type)
+ (identifier))
+ (multiline_preproc_comment)
+ (end_of_statement)
+ (variable_declaration
+ (intrinsic_type)
+ (multiline_preproc_comment)
+ (identifier))
+ (end_of_statement)
+ (end_program_statement
+ (end_of_statement)))
+ (multiline_preproc_comment)
+ (preproc_ifdef
+ (identifier)))
32 changes: 24 additions & 8 deletions grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ module.exports = grammar({
// preprocessor statements
/\s|\\\r?\n/,
$.comment,
$.multiline_preproc_comment,
'&',
],

Expand Down Expand Up @@ -248,7 +249,8 @@ module.exports = grammar({
')',
),

preproc_comment: $ => choice(/\/\*.*\*\//, /\/\/.*/),
inline_preproc_comment: $ => /\/\/.*/,
multiline_preproc_comment: $ => /\/\*([^*]|\*+[^*/])*\*+\//,

preproc_binary_expression: $ => {
const table = [
Expand Down Expand Up @@ -2466,36 +2468,50 @@ function preprocIf(suffix, content, precedence = 0) {
);
}

/**
*
* @param {GrammarSymbols<string>} $
*
* @return {ChoiceRule}
*
*/
function preprocComment($) {
return choice(
$.inline_preproc_comment,
$.multiline_preproc_comment,
);
}

return {
['preproc_if' + suffix]: $ => prec(precedence, seq(
preprocessor('if'),
field('condition', $._preproc_expression),
optional($.preproc_comment),
optional(preprocComment($)),
field('content', content($)),
field('alternative', optional(alternativeBlock($))),
preprocessor('endif'),
optional($.preproc_comment),
optional(preprocComment($)),
)),

['preproc_ifdef' + suffix]: $ => prec(precedence, seq(
choice(preprocessor('ifdef'), preprocessor('ifndef')),
field('name', $.identifier),
optional($.preproc_comment),
optional(preprocComment($)),
field('content', content($)),
field('alternative', optional(alternativeBlock($))),
preprocessor('endif'),
optional($.preproc_comment),
optional(preprocComment($)),
)),

['preproc_else' + suffix]: $ => prec(precedence, seq(
preprocessor('else'),
optional($.preproc_comment),
optional(preprocComment($)),
field('content', content($)),
)),

['preproc_elif' + suffix]: $ => prec(precedence, seq(
preprocessor('elif'),
optional($.preproc_comment),
optional(preprocComment($)),
field('condition', $._preproc_expression),
field('content', content($)),
field('alternative', optional(alternativeBlock($))),
Expand All @@ -2504,7 +2520,7 @@ function preprocIf(suffix, content, precedence = 0) {
['preproc_elifdef' + suffix]: $ => prec(precedence, seq(
choice(preprocessor('elifdef'), preprocessor('elifndef')),
field('name', $.identifier),
optional($.preproc_comment),
optional(preprocComment($)),
field('content', content($)),
field('alternative', optional(alternativeBlock($))),
)),
Expand Down
Loading