diff --git a/grammar.js b/grammar.js index 896042f..e8cb50b 100644 --- a/grammar.js +++ b/grammar.js @@ -69,6 +69,7 @@ module.exports = grammar({ [$.class_list], [$.attr_value_list], [$._text_block_attrs], + [$._identifier], ], rules: { @@ -93,12 +94,24 @@ module.exports = grammar({ connection: ($) => seq( - $._connection_path, - repeat1(seq($.arrow, $._connection_path)), + choice( + $._full_connection_path, + alias($._referencing_full_connection_path, $.referencing) + ), optional(seq($._colon, optional($.label))), optional(seq(alias($._connection_block, $.block))) ), + _referencing_full_connection_path: ($) => + seq("(", $._full_connection_path, $._referencing_end, optional($.index)), + + _referencing_end: ($) => token(prec(PREC.IDENTIFIER + 1, ")")), + + index: ($) => seq("[", $.integer, "]"), + + _full_connection_path: ($) => + seq($._connection_path, repeat1(seq($.arrow, $._connection_path))), + _connection_path: ($) => seq( repeat( @@ -201,11 +214,17 @@ module.exports = grammar({ repeat( choice( $.escape_sequence, - token(prec(PREC.IDENTIFIER, /[\w\d'"$(),]+/)), - token(prec(PREC.IDENTIFIER, /( +|-)[\w\d'"$()]+/)) + token(prec(PREC.IDENTIFIER, /[\w\d'"$(,]+/)), + token(prec(PREC.IDENTIFIER, /( +|-)[\w\d'"$(]+/)), + token(prec(PREC.IDENTIFIER, ")")) + ) + ), + optional( + choice( + token(prec(PREC.IDENTIFIER, /[\w\d'"$(]+/)), + token(prec(PREC.IDENTIFIER + 1, ")")) ) ), - optional(token(prec(PREC.IDENTIFIER, /[\w\d'"$()]+/))), optional($._dash) ), diff --git a/src/grammar.json b/src/grammar.json index 90a9fb0..e6a0560 100644 --- a/src/grammar.json +++ b/src/grammar.json @@ -69,24 +69,22 @@ "type": "SEQ", "members": [ { - "type": "SYMBOL", - "name": "_connection_path" - }, - { - "type": "REPEAT1", - "content": { - "type": "SEQ", - "members": [ - { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "_full_connection_path" + }, + { + "type": "ALIAS", + "content": { "type": "SYMBOL", - "name": "arrow" + "name": "_referencing_full_connection_path" }, - { - "type": "SYMBOL", - "name": "_connection_path" - } - ] - } + "named": true, + "value": "referencing" + } + ] }, { "type": "CHOICE", @@ -141,6 +139,88 @@ } ] }, + "_referencing_full_connection_path": { + "type": "SEQ", + "members": [ + { + "type": "STRING", + "value": "(" + }, + { + "type": "SYMBOL", + "name": "_full_connection_path" + }, + { + "type": "SYMBOL", + "name": "_referencing_end" + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "index" + }, + { + "type": "BLANK" + } + ] + } + ] + }, + "_referencing_end": { + "type": "TOKEN", + "content": { + "type": "PREC", + "value": 1, + "content": { + "type": "STRING", + "value": ")" + } + } + }, + "index": { + "type": "SEQ", + "members": [ + { + "type": "STRING", + "value": "[" + }, + { + "type": "SYMBOL", + "name": "integer" + }, + { + "type": "STRING", + "value": "]" + } + ] + }, + "_full_connection_path": { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_connection_path" + }, + { + "type": "REPEAT1", + "content": { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "arrow" + }, + { + "type": "SYMBOL", + "name": "_connection_path" + } + ] + } + } + ] + }, "_connection_path": { "type": "SEQ", "members": [ @@ -893,7 +973,7 @@ "value": 0, "content": { "type": "PATTERN", - "value": "[\\w\\d'\"$(),]+" + "value": "[\\w\\d'\"$(,]+" } } }, @@ -904,7 +984,18 @@ "value": 0, "content": { "type": "PATTERN", - "value": "( +|-)[\\w\\d'\"$()]+" + "value": "( +|-)[\\w\\d'\"$(]+" + } + } + }, + { + "type": "TOKEN", + "content": { + "type": "PREC", + "value": 0, + "content": { + "type": "STRING", + "value": ")" } } } @@ -915,15 +1006,31 @@ "type": "CHOICE", "members": [ { - "type": "TOKEN", - "content": { - "type": "PREC", - "value": 0, - "content": { - "type": "PATTERN", - "value": "[\\w\\d'\"$()]+" + "type": "CHOICE", + "members": [ + { + "type": "TOKEN", + "content": { + "type": "PREC", + "value": 0, + "content": { + "type": "PATTERN", + "value": "[\\w\\d'\"$(]+" + } + } + }, + { + "type": "TOKEN", + "content": { + "type": "PREC", + "value": 1, + "content": { + "type": "STRING", + "value": ")" + } + } } - } + ] }, { "type": "BLANK" @@ -2287,6 +2394,9 @@ ], [ "_text_block_attrs" + ], + [ + "_identifier" ] ], "precedences": [], diff --git a/src/node-types.json b/src/node-types.json index 307e03b..5193755 100644 --- a/src/node-types.json +++ b/src/node-types.json @@ -261,7 +261,7 @@ "fields": {}, "children": { "multiple": true, - "required": true, + "required": false, "types": [ { "type": "arrow", @@ -283,6 +283,10 @@ "type": "label", "named": true }, + { + "type": "referencing", + "named": true + }, { "type": "shape_key", "named": true @@ -348,6 +352,21 @@ ] } }, + { + "type": "index", + "named": true, + "fields": {}, + "children": { + "multiple": false, + "required": true, + "types": [ + { + "type": "integer", + "named": true + } + ] + } + }, { "type": "label", "named": true, @@ -367,6 +386,37 @@ ] } }, + { + "type": "referencing", + "named": true, + "fields": {}, + "children": { + "multiple": true, + "required": false, + "types": [ + { + "type": "arrow", + "named": true + }, + { + "type": "container_key", + "named": true + }, + { + "type": "dot", + "named": true + }, + { + "type": "index", + "named": true + }, + { + "type": "shape_key", + "named": true + } + ] + } + }, { "type": "reserved", "named": true, @@ -511,6 +561,14 @@ "type": "'", "named": false }, + { + "type": "(", + "named": false + }, + { + "type": ")", + "named": false + }, { "type": "3d", "named": false diff --git a/src/parser.c b/src/parser.c index be0e836..497b52a 100644 Binary files a/src/parser.c and b/src/parser.c differ diff --git a/test/corpus/connection.txt b/test/corpus/connection.txt index 205c0c0..4c68529 100644 --- a/test/corpus/connection.txt +++ b/test/corpus/connection.txt @@ -248,7 +248,7 @@ Connection with espaced key fragments ================================================================================ -Connection with espaced key fragments +Diclare a connection with espaced key fragments ================================================================================ \#hello\[\] -- \[world\] @@ -268,3 +268,111 @@ Connection with espaced key fragments ) ) ) + +================================================================================ +Declare a referencing connection +================================================================================ +(x() -> y()) +(x() -> y())[0] + +-------------------------------------------------------------------------------- + +(source_file + (connection + (referencing + (shape_key) + (arrow) + (shape_key) + ) + ) + (connection + (referencing + (shape_key) + (arrow) + (shape_key) + (index (integer)) + ) + ) +) + +================================================================================ +Declare a referencing connection with label +================================================================================ +(x -> y): label +(x -> y)[0]: label + +-------------------------------------------------------------------------------- + +(source_file + (connection + (referencing + (shape_key) + (arrow) + (shape_key) + ) + (label) + ) + (connection + (referencing + (shape_key) + (arrow) + (shape_key) + (index (integer)) + ) + (label) + ) +) + +================================================================================ +Declare a referencing connection with block +================================================================================ +(x() -> y()): { + style.stroke: \#ff0000 +} +(x -> y)[0]: { + style.stroke: \#ff0000 +} + +-------------------------------------------------------------------------------- + +(source_file + (connection + (referencing + (shape_key) + (arrow) + (shape_key) + ) + (block + (attribute + (keyword_style) + (dot) + (attribute + (attr_key) + (attr_value + (escape_sequence) + ) + ) + ) + ) + ) + (connection + (referencing + (shape_key) + (arrow) + (shape_key) + (index (integer)) + ) + (block + (attribute + (keyword_style) + (dot) + (attribute + (attr_key) + (attr_value + (escape_sequence) + ) + ) + ) + ) + ) +) diff --git a/tree-sitter-d2.wasm b/tree-sitter-d2.wasm index bb6e05b..3efa1ad 100755 Binary files a/tree-sitter-d2.wasm and b/tree-sitter-d2.wasm differ