diff --git a/grammar.js b/grammar.js index 5a822ba..9b8fae1 100644 --- a/grammar.js +++ b/grammar.js @@ -1,8 +1,10 @@ const PREC = { COMMENT: -2, - IDENTIFIER: 11, - SHAPE: 10, CONTAINER: 9, + CONNECTION: 9, + SHAPE: 11, + IDENTIFIER: 12, + ARROW: 13, }; spaces = /[ \t]/; @@ -18,6 +20,7 @@ module.exports = grammar({ word: ($) => $._word, conflicts: ($) => [ + [$._connection_path, $.container], //[$.shape_key], /* [$._shape_path], @@ -32,7 +35,26 @@ module.exports = grammar({ rules: { source_file: ($) => repeat($._new_root_definition), - _new_root_definition: ($) => choice($._eol, $.shape, $.container), + _new_root_definition: ($) => + choice($._eol, seq(choice($.shape, $.container, $.connection), $._end)), + + connection: ($) => + seq( + $._connection_path, + repeat1(seq($._arrow, $._connection_path)), + optional(seq($._colon, $.label)) + ), + + _connection_path: ($) => + seq( + repeat( + prec( + PREC.CONNECTION, + seq(alias($.shape_key, $.container_key), $._dot) + ) + ), + $.shape_key + ), container: ($) => prec( @@ -40,7 +62,7 @@ module.exports = grammar({ seq( alias($.shape_key, $.container_key), choice( - seq($._dot, $.shape), + seq($._dot, choice($.shape, $.container)), seq( seq( optional(seq($._colon, optional($.label))), @@ -61,23 +83,16 @@ module.exports = grammar({ optional(seq($._colon, optional($.label))), optional(seq(alias($._new_shape_block, $.block))) ) - ), - $._end + ) ) ), shape_key: ($) => choice( $.string, - prec.left( - seq( - optional($._dash), - choice( - $._word, - token(prec(PREC.IDENTIFIER, /([\w\d]+( +|\-)[\w\d]+)+/)) - ), - optional($._dash) - ) + seq( + token(prec(PREC.IDENTIFIER, /\-?([\w\d]+|([\w\d]+( +|\-)[\w\d]+)+)/)), + optional($._dash) ) ), @@ -93,7 +108,10 @@ module.exports = grammar({ ), _new_container_block_definition: ($) => - prec(PREC.CONTAINER, choice($._eol, $.shape, $.container)), + prec( + PREC.CONTAINER, + choice($._eol, seq(choice($.shape, $.container), $._end)) + ), // -------------------------------------------- @@ -107,16 +125,6 @@ module.exports = grammar({ $._shape_definition ), - connection: ($) => - seq( - $._shape_path, - repeat1(seq($._arrow, $._shape_path)), - optional( - choice(seq($.dot, $._connection_attribute), seq($._colon, $.label)) - ), - $._end - ), - _shape_definition: ($) => seq( $._shape_path, @@ -237,14 +245,14 @@ module.exports = grammar({ _colon: ($) => seq(":"), - _arrow: ($) => seq(spaces, $.arrow), + _arrow: ($) => seq($.arrow), - arrow: ($) => choice(/-+>/, /--+/, /<-+/, /<-+>/), + arrow: ($) => token(prec(PREC.ARROW, choice(/-+>/, /--+/, /<-+/, /<-+>/))), _dot: ($) => seq($.dot), dot: ($) => token("."), - _unquoted_string: ($) => token(prec(5, /[\w\-]([^'"`\n;{}]*[\w\-])?/)), + _unquoted_string: ($) => token(prec(5, /[\w\-?!]([^'"`\n;{}]*[\w\-?!])?/)), string: ($) => choice( diff --git a/src/grammar.json b/src/grammar.json index d6bdea1..ad1a7f4 100644 --- a/src/grammar.json +++ b/src/grammar.json @@ -16,13 +16,111 @@ "type": "SYMBOL", "name": "_eol" }, + { + "type": "SEQ", + "members": [ + { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "shape" + }, + { + "type": "SYMBOL", + "name": "container" + }, + { + "type": "SYMBOL", + "name": "connection" + } + ] + }, + { + "type": "SYMBOL", + "name": "_end" + } + ] + } + ] + }, + "connection": { + "type": "SEQ", + "members": [ { "type": "SYMBOL", - "name": "shape" + "name": "_connection_path" + }, + { + "type": "REPEAT1", + "content": { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_arrow" + }, + { + "type": "SYMBOL", + "name": "_connection_path" + } + ] + } + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_colon" + }, + { + "type": "SYMBOL", + "name": "label" + } + ] + }, + { + "type": "BLANK" + } + ] + } + ] + }, + "_connection_path": { + "type": "SEQ", + "members": [ + { + "type": "REPEAT", + "content": { + "type": "PREC", + "value": 9, + "content": { + "type": "SEQ", + "members": [ + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "shape_key" + }, + "named": true, + "value": "container_key" + }, + { + "type": "SYMBOL", + "name": "_dot" + } + ] + } + } }, { "type": "SYMBOL", - "name": "container" + "name": "shape_key" } ] }, @@ -52,8 +150,17 @@ "name": "_dot" }, { - "type": "SYMBOL", - "name": "shape" + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "shape" + }, + { + "type": "SYMBOL", + "name": "container" + } + ] } ] }, @@ -125,7 +232,7 @@ }, "shape": { "type": "PREC", - "value": 10, + "value": 11, "content": { "type": "SEQ", "members": [ @@ -196,10 +303,6 @@ "type": "BLANK" } ] - }, - { - "type": "SYMBOL", - "name": "_end" } ] } @@ -212,63 +315,38 @@ "name": "string" }, { - "type": "PREC_LEFT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_dash" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_word" - }, - { - "type": "TOKEN", - "content": { - "type": "PREC", - "value": 11, - "content": { - "type": "PATTERN", - "value": "([\\w\\d]+( +|\\-)[\\w\\d]+)+" - } - } - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_dash" - }, - { - "type": "BLANK" - } - ] + "type": "SEQ", + "members": [ + { + "type": "TOKEN", + "content": { + "type": "PREC", + "value": 12, + "content": { + "type": "PATTERN", + "value": "\\-?([\\w\\d]+|([\\w\\d]+( +|\\-)[\\w\\d]+)+)" + } } - ] - } + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "_dash" + }, + { + "type": "BLANK" + } + ] + } + ] } ] }, "_new_shape_block": { "type": "PREC", - "value": 10, + "value": 11, "content": { "type": "SEQ", "members": [ @@ -292,7 +370,7 @@ }, "_new_shape_block_definition": { "type": "PREC", - "value": 10, + "value": 11, "content": { "type": "CHOICE", "members": [ @@ -338,12 +416,26 @@ "name": "_eol" }, { - "type": "SYMBOL", - "name": "shape" - }, - { - "type": "SYMBOL", - "name": "container" + "type": "SEQ", + "members": [ + { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "shape" + }, + { + "type": "SYMBOL", + "name": "container" + } + ] + }, + { + "type": "SYMBOL", + "name": "_end" + } + ] } ] } @@ -369,74 +461,6 @@ } ] }, - "connection": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_shape_path" - }, - { - "type": "REPEAT1", - "content": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_arrow" - }, - { - "type": "SYMBOL", - "name": "_shape_path" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "dot" - }, - { - "type": "SYMBOL", - "name": "_connection_attribute" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_colon" - }, - { - "type": "SYMBOL", - "name": "label" - } - ] - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "SYMBOL", - "name": "_end" - } - ] - }, "_shape_definition": { "type": "SEQ", "members": [ @@ -1084,10 +1108,6 @@ "_arrow": { "type": "SEQ", "members": [ - { - "type": "PATTERN", - "value": "[ \\t]" - }, { "type": "SYMBOL", "name": "arrow" @@ -1095,25 +1115,32 @@ ] }, "arrow": { - "type": "CHOICE", - "members": [ - { - "type": "PATTERN", - "value": "-+>" - }, - { - "type": "PATTERN", - "value": "--+" - }, - { - "type": "PATTERN", - "value": "<-+" - }, - { - "type": "PATTERN", - "value": "<-+>" + "type": "TOKEN", + "content": { + "type": "PREC", + "value": 13, + "content": { + "type": "CHOICE", + "members": [ + { + "type": "PATTERN", + "value": "-+>" + }, + { + "type": "PATTERN", + "value": "--+" + }, + { + "type": "PATTERN", + "value": "<-+" + }, + { + "type": "PATTERN", + "value": "<-+>" + } + ] } - ] + } }, "_dot": { "type": "SEQ", @@ -1138,7 +1165,7 @@ "value": 5, "content": { "type": "PATTERN", - "value": "[\\w\\-]([^'\"`\\n;{}]*[\\w\\-])?" + "value": "[\\w\\-?!]([^'\"`\\n;{}]*[\\w\\-?!])?" } } }, @@ -1299,7 +1326,12 @@ "name": "line_comment" } ], - "conflicts": [], + "conflicts": [ + [ + "_connection_path", + "container" + ] + ], "precedences": [], "externals": [], "inline": [], diff --git a/src/node-types.json b/src/node-types.json index 08d15be..3c813bb 100644 --- a/src/node-types.json +++ b/src/node-types.json @@ -1,9 +1,4 @@ [ - { - "type": "arrow", - "named": true, - "fields": {} - }, { "type": "attr_key", "named": true, @@ -87,14 +82,6 @@ "type": "arrow", "named": true }, - { - "type": "attr_key", - "named": true - }, - { - "type": "attr_value", - "named": true - }, { "type": "container_key", "named": true @@ -126,6 +113,10 @@ "type": "block", "named": true }, + { + "type": "container", + "named": true + }, { "type": "container_key", "named": true @@ -248,6 +239,10 @@ "multiple": true, "required": false, "types": [ + { + "type": "connection", + "named": true + }, { "type": "container", "named": true @@ -300,6 +295,10 @@ "type": "animated", "named": false }, + { + "type": "arrow", + "named": true + }, { "type": "border-radius", "named": false diff --git a/src/parser.c b/src/parser.c index a0e3f0f..bc35e88 100644 Binary files a/src/parser.c and b/src/parser.c differ diff --git a/test/corpus/container.txt b/test/corpus/container.txt index d0b5691..dbfa5ea 100644 --- a/test/corpus/container.txt +++ b/test/corpus/container.txt @@ -2,11 +2,22 @@ Declare a shape inside a container ================================================================================ foo.baz +foo.bar.biz -------------------------------------------------------------------------------- (source_file - (container_key) (dot) (shape_key) + (container + (container_key) (dot) + (shape (shape_key)) + ) + (container + (container_key) (dot) + (container + (container_key) (dot) + (shape (shape_key)) + ) + ) ) ================================================================================ @@ -17,7 +28,10 @@ Use quoted string as a shape key -------------------------------------------------------------------------------- (source_file - (container_key (string)) (dot) (shape_key (string)) + (container + (container_key (string)) (dot) + (shape (shape_key (string))) + ) ) ================================================================================ @@ -35,20 +49,59 @@ foo: { -------------------------------------------------------------------------------- (source_file - (shape_key) - (block - (shape_key) + (container + (container_key) (block - (shape_key) - (block - (shape_key) + (container + (container_key) + (block + (container + (container_key) + (block + (shape (shape_key)) + ) + ) + ) ) ) ) ) ================================================================================ -Declare labaled container inside a labeled container using block +Declare a container with complex keys +================================================================================ + +Foo biz bar: { + bar biz baz: { + -biz-baz-Baz-: { + Helo world + } + } +} + +-------------------------------------------------------------------------------- + +(source_file + (container + (container_key) + (block + (container + (container_key) + (block + (container + (container_key) + (block + (shape (shape_key)) + ) + ) + ) + ) + ) + ) +) + +================================================================================ +Declare labeled container inside a labeled container using block ================================================================================ foo: Foo { @@ -62,13 +115,22 @@ foo: Foo { -------------------------------------------------------------------------------- (source_file - (shape_key) (label) - (block - (shape_key) (label) + (container + (container_key) + (label) (block - (shape_key) (label) - (block - (shape_key) (label) + (container + (container_key) + (label) + (block + (container + (container_key) + (label) + (block + (shape (shape_key) (label)) + ) + ) + ) ) ) ) @@ -87,11 +149,13 @@ foo: { -------------------------------------------------------------------------------- (source_file - (shape_key) - (block - (shape_key) - (shape_key) - (shape_key) + (container + (container_key) + (block + (shape (shape_key)) + (shape (shape_key)) + (shape (shape_key)) + ) ) ) diff --git a/test/corpus/shape.txt b/test/corpus/shape.txt index c73d2f7..9db5732 100644 --- a/test/corpus/shape.txt +++ b/test/corpus/shape.txt @@ -7,8 +7,8 @@ bar -------------------------------------------------------------------------------- (source_file - (shape_key) - (shape_key) + (shape (shape_key)) + (shape (shape_key)) ) ================================================================================ @@ -20,8 +20,8 @@ Complex shape key -------------------------------------------------------------------------------- (source_file - (shape_key) - (shape_key) + (shape (shape_key)) + (shape (shape_key)) ) ================================================================================ @@ -32,7 +32,7 @@ Use quoted string as a shape key -------------------------------------------------------------------------------- (source_file - (shape_key (string)) + (shape (shape_key (string))) ) ================================================================================ @@ -43,9 +43,9 @@ a;b;c -------------------------------------------------------------------------------- (source_file - (shape_key) - (shape_key) - (shape_key) + (shape (shape_key)) + (shape (shape_key)) + (shape (shape_key)) ) ================================================================================ @@ -57,9 +57,9 @@ a: Foo Bar; b: Biz Baz -------------------------------------------------------------------------------- (source_file - (shape_key) (label) - (shape_key) (label) - (shape_key) (label) + (shape (shape_key) (label)) + (shape (shape_key) (label)) + (shape (shape_key) (label)) ) ================================================================================ @@ -73,62 +73,34 @@ bar : Foo Bar; baz -------------------------------------------------------------------------------- (source_file - (shape_key) - (shape_key) (label) - (shape_key) + (shape (shape_key)) + (shape (shape_key) (label)) + (shape (shape_key)) ) ================================================================================ Shape block ================================================================================ -foo: { - bar: { - baz: { - biz - } - } -} +foo: {} +bar {} -------------------------------------------------------------------------------- (source_file - (shape_key) - (block - (shape_key) - (block - (shape_key) - (block - (shape_key) - ) - ) - ) + (shape (shape_key) (block)) + (shape (shape_key) (block)) ) ================================================================================ -Aliased shape block +Labeled shape block ================================================================================ -foo: Foo { - bar: Bar { - baz: Baz { - biz: Biz - } - } -} +foo: Foo {} -------------------------------------------------------------------------------- (source_file - (shape_key) (label) - (block - (shape_key) (label) - (block - (shape_key) (label) - (block - (shape_key) (label) - ) - ) - ) + (shape (shape_key) (label) (block)) ) diff --git a/test/corpus/attributes.txt b/test/old_corpus/attributes.txt similarity index 100% rename from test/corpus/attributes.txt rename to test/old_corpus/attributes.txt diff --git a/test/old_corpus/connection.txt b/test/old_corpus/connection.txt new file mode 100644 index 0000000..f1d8b64 --- /dev/null +++ b/test/old_corpus/connection.txt @@ -0,0 +1,198 @@ +================================================================================ +Simple connection +================================================================================ +foo--bar +biz->baz +biz<->baz +biz<-baz + +-------------------------------------------------------------------------------- + +(source_file + (connection + (shape_key) + (arrow) + (shape_key) + ) + (connection + (shape_key) + (arrow) + (shape_key) + ) + (connection + (shape_key) + (arrow) + (shape_key) + ) + (connection + (shape_key) + (arrow) + (shape_key) + ) +) + +================================================================================ +Formatted connection +================================================================================ +foo -- bar +biz -> baz +biz <-> baz +biz <- baz + +-------------------------------------------------------------------------------- + +(source_file + (connection + (shape_key) + (arrow) + (shape_key) + ) + (connection + (shape_key) + (arrow) + (shape_key) + ) + (connection + (shape_key) + (arrow) + (shape_key) + ) + (connection + (shape_key) + (arrow) + (shape_key) + ) +) + +================================================================================ +Connection with looooong arrow +================================================================================ +foo ----------- bar +biz ----------> baz +biz <---------> baz +biz <---------- baz + +-------------------------------------------------------------------------------- + +(source_file + (connection + (shape_key) + (arrow) + (shape_key) + ) + (connection + (shape_key) + (arrow) + (shape_key) + ) + (connection + (shape_key) + (arrow) + (shape_key) + ) + (connection + (shape_key) + (arrow) + (shape_key) + ) +) + + +================================================================================ +Complex identifier connection +================================================================================ +Foo Bar -- Biz Baz +-Bar-Foo- <- -Baz-Biz- + +-------------------------------------------------------------------------------- + +(source_file + (connection + (shape_key) + (arrow) + (shape_key) + ) + (connection + (shape_key) + (arrow) + (shape_key) + ) +) + +================================================================================ +Inline connection +================================================================================ +foo--bar->biz->baz + +-------------------------------------------------------------------------------- + +(source_file + (connection + (shape_key) + (arrow) + (shape_key) + (arrow) + (shape_key) + (arrow) + (shape_key) + ) +) + +================================================================================ +Many connections inline +================================================================================ +foo--bar;biz->baz + +-------------------------------------------------------------------------------- + +(source_file + (connection + (shape_key) + (arrow) + (shape_key) + ) + (connection + (shape_key) + (arrow) + (shape_key) + ) +) + +================================================================================ +Labeled connections +================================================================================ +foo--bar: Question? +bar -> baz: Yes + +-------------------------------------------------------------------------------- + +(source_file + (connection + (shape_key) + (arrow) + (shape_key) + (label) + ) + (connection + (shape_key) + (arrow) + (shape_key) + (label) + ) +) + +================================================================================ +Connection of shapes inside a containers +================================================================================ +foo.biz.baz -> bar.baz.biz: Label + +-------------------------------------------------------------------------------- + +(source_file + (connection + (container_key) (dot) (container_key) (dot) (shape_key) + (arrow) + (container_key) (dot) (container_key) (dot) (shape_key) + (label) + ) +) diff --git a/test/old_corpus/container.txt b/test/old_corpus/container.txt new file mode 100644 index 0000000..d0b5691 --- /dev/null +++ b/test/old_corpus/container.txt @@ -0,0 +1,97 @@ +================================================================================ +Declare a shape inside a container +================================================================================ +foo.baz + +-------------------------------------------------------------------------------- + +(source_file + (container_key) (dot) (shape_key) +) + +================================================================================ +Use quoted string as a shape key +================================================================================ +'foo'.'baz' + +-------------------------------------------------------------------------------- + +(source_file + (container_key (string)) (dot) (shape_key (string)) +) + +================================================================================ +Declare container inside a container using block +================================================================================ + +foo: { + bar: { + baz: { + biz + } + } +} + +-------------------------------------------------------------------------------- + +(source_file + (shape_key) + (block + (shape_key) + (block + (shape_key) + (block + (shape_key) + ) + ) + ) +) + +================================================================================ +Declare labaled container inside a labeled container using block +================================================================================ + +foo: Foo { + bar: Bar { + baz: Baz { + biz: Biz + } + } +} + +-------------------------------------------------------------------------------- + +(source_file + (shape_key) (label) + (block + (shape_key) (label) + (block + (shape_key) (label) + (block + (shape_key) (label) + ) + ) + ) +) + +================================================================================ +Declare many shapes inside a container +================================================================================ + +foo: { + bar + biz + baz +} + +-------------------------------------------------------------------------------- + +(source_file + (shape_key) + (block + (shape_key) + (shape_key) + (shape_key) + ) +) + diff --git a/test/old_corpus/shape.txt b/test/old_corpus/shape.txt new file mode 100644 index 0000000..c73d2f7 --- /dev/null +++ b/test/old_corpus/shape.txt @@ -0,0 +1,134 @@ +================================================================================ +Simple shape key +================================================================================ +foo +bar + +-------------------------------------------------------------------------------- + +(source_file + (shape_key) + (shape_key) +) + +================================================================================ +Complex shape key +================================================================================ + Foo bar +-Biz-baz- + +-------------------------------------------------------------------------------- + +(source_file + (shape_key) + (shape_key) +) + +================================================================================ +Use quoted string as a shape key +================================================================================ +'foo' + +-------------------------------------------------------------------------------- + +(source_file + (shape_key (string)) +) + +================================================================================ +Define multiple shapes using semicolons +================================================================================ +a;b;c + +-------------------------------------------------------------------------------- + +(source_file + (shape_key) + (shape_key) + (shape_key) +) + +================================================================================ +Labeled shapes +================================================================================ +a: Foo Bar +a: Foo Bar; b: Biz Baz + +-------------------------------------------------------------------------------- + +(source_file + (shape_key) (label) + (shape_key) (label) + (shape_key) (label) +) + +================================================================================ +It should skip white spaces +================================================================================ + +foo + +bar : Foo Bar; baz + +-------------------------------------------------------------------------------- + +(source_file + (shape_key) + (shape_key) (label) + (shape_key) +) + +================================================================================ +Shape block +================================================================================ + +foo: { + bar: { + baz: { + biz + } + } +} + +-------------------------------------------------------------------------------- + +(source_file + (shape_key) + (block + (shape_key) + (block + (shape_key) + (block + (shape_key) + ) + ) + ) +) + +================================================================================ +Aliased shape block +================================================================================ + +foo: Foo { + bar: Bar { + baz: Baz { + biz: Biz + } + } +} + +-------------------------------------------------------------------------------- + +(source_file + (shape_key) (label) + (block + (shape_key) (label) + (block + (shape_key) (label) + (block + (shape_key) (label) + ) + ) + ) +) + diff --git a/tree-sitter-d2.wasm b/tree-sitter-d2.wasm index e91ec96..ad324c5 100755 Binary files a/tree-sitter-d2.wasm and b/tree-sitter-d2.wasm differ