From be8db7ca48cd475e1620491f6e7d04ee1c379b7a Mon Sep 17 00:00:00 2001 From: Dmitriy Pleshevskiy Date: Fri, 9 Dec 2022 12:36:31 +0300 Subject: [PATCH] Add structure for container and shapes (#1) ![image](/attachments/5bf879cc-b94c-414e-b69b-92cbc018671e) Co-authored-by: Dmitriy Pleshevskiy Reviewed-on: https://git.pleshevski.ru/pleshevskiy/tree-sitter-d2/pulls/1 --- .gitignore | 2 + grammar.js | 272 ++-- queries/highlights.scm | 7 +- src/grammar.json | 1541 ++++++++----------- src/node-types.json | 198 +-- src/parser.c | Bin 199538 -> 113709 bytes test/corpus/attributes.txt | 236 ++- test/corpus/connection.txt | 26 + test/corpus/container.txt | 171 +- test/corpus/shape.txt | 77 +- test/highlight/{keyword.d2 => attribute.d2} | 2 +- test/highlight/shape.d2 | 2 +- tree-sitter-d2.wasm | Bin 33162 -> 25898 bytes 13 files changed, 1296 insertions(+), 1238 deletions(-) rename test/highlight/{keyword.d2 => attribute.d2} (95%) diff --git a/.gitignore b/.gitignore index 42d67a4..74045d4 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,7 @@ .envrc .direnv +# test data +test.d2 # produced by d2 *.svg diff --git a/grammar.js b/grammar.js index 7e6bf9d..bd702d7 100644 --- a/grammar.js +++ b/grammar.js @@ -1,155 +1,194 @@ -const spaces = repeat(choice(" ", "\t")); +const PREC = { + COMMENT: -2, + EOL: -1, + UNQUOTED_STRING: 0, + CONTAINER: 2, + CONNECTION: 2, + SHAPE: 3, + IDENTIFIER: 0, + ARROW: 0, + ATTRIBUTE: 0, + ATTRIBUTE_KEY: 0, +}; module.exports = grammar({ name: "d2", - extras: ($) => [$.line_comment], - - word: ($) => $._word, - - conflicts: ($) => [ - [$.shape_key], - [$._shape_path], - [$._shape_block], - [$._shape_block_definition], - [$._style_attr_block], - [$._inner_style_attribute], - [$._emptyline], + extras: ($) => [ + /[ \f\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/, + $.line_comment, ], + word: ($) => $._identifier, + + conflicts: ($) => [[$._connection_path, $.container]], + rules: { source_file: ($) => repeat($._root_definition), _root_definition: ($) => choice( - $._emptyline, - $._root_attribute, - $.connection, - $._shape_definition + $._eol, + seq( + choice( + alias($._root_attribute, $.attribute), + $.shape, + $.container, + $.connection + ), + $._end + ) ), + // connections + connection: ($) => seq( - $._shape_path, - repeat1(seq($._arrow, $._shape_path)), - optional( - choice(seq($.dot, $._connection_attribute), seq($._colon, $.label)) - ), - $._end + $._connection_path, + repeat1(seq($.arrow, $._connection_path)), + optional(seq($._colon, $.label)) ), - _shape_definition: ($) => + _connection_path: ($) => seq( - $._shape_path, - optional( - choice( - seq($.dot, $._shape_attribute), - seq( - optional(seq($._colon, optional(seq(spaces, $.label)))), - optional(alias($._shape_block, $.block)) - ) - ) + repeat( + prec(PREC.CONNECTION, seq(alias($.shape_key, $.container_key), $.dot)) ), - $._end - ), - - _shape_path: ($) => - seq( - spaces, - repeat(seq(alias($.shape_key, $.container_key), spaces, $.dot, spaces)), $.shape_key ), - shape_key: ($) => - choice( - $.string, + // containers + + container: ($) => + prec( + PREC.CONTAINER, seq( - optional($._dash), + alias($.shape_key, $.container_key), choice( - $._word, - repeat1(seq($._word, choice(repeat1(" "), $._dash), $._word)) - ), - optional($._dash) + seq($.dot, choice($.shape, $.container)), + seq( + seq( + optional(seq($._colon, optional($.label))), + optional(seq(alias($._container_block, $.block))) + ) + ) + ) ) ), - _dash: ($) => token.immediate("-"), + _container_block: ($) => + seq("{", repeat($._container_block_definition), "}"), - label: ($) => choice($.string, $._unquoted_string), + _container_block_definition: ($) => + choice( + $._eol, + seq( + choice($.shape, $.container, $.connection, $._shape_attribute), + $._end + ) + ), - attr_value: ($) => seq(spaces, choice($.string, $._unquoted_string)), + // shapes + + shape: ($) => + prec( + PREC.SHAPE, + seq( + $.shape_key, + optional( + choice( + seq($.dot, alias($._style_attribute, $.attribute)), + seq(optional(seq($._colon, optional($.label)))) + ) + ) + ) + ), + + shape_key: ($) => choice($.string, seq($._identifier, optional($._dash))), + + _identifier: ($) => + token(prec(PREC.IDENTIFIER, /\-?([\w\d]+|([\w\d]+( +|\-)[\w\d]+)+)/)), + + // attributes _root_attribute: ($) => + seq(alias($._root_attr_key, $.attr_key), $._colon, $.attr_value), + + _root_attr_key: ($) => choice( - seq( - alias($._root_attr_key, $.attr_key), - $._colon, - $.attr_value, - $._end - ), - alias(seq($._shape_attribute, $._end), $.invalid) + "direction", + // reserved but doesn't affected for root + alias( + choice( + "shape", + "label", + "constraint", + "icon", + "style", + $._common_style_attr_key, + $._text_attr_key + ), + $.reserved + ) ), - _root_attr_key: ($) => "direction", - - _shape_block: ($) => - seq( - spaces, - "{", - repeat(choice($._emptyline, seq(spaces, $._shape_block_definition))), - optional(seq($._shape_block_definition, optional($._end))), - spaces, - "}" - ), - - _shape_block_definition: ($) => - choice($.connection, $._shape_definition, $._shape_attribute), - _shape_attribute: ($) => choice( - seq(alias($._shape_attr_key, $.attr_key), $._colon, $.attr_value), - $._style_attribute + alias($._base_shape_attribute, $.attribute), + alias($._style_attribute, $.attribute) ), - _style_attribute: ($) => - seq( - alias("style", $.attr_key), + _base_shape_attribute: ($) => + seq(alias($._shape_attr_key, $.attr_key), $._colon, $.attr_value), + + _shape_attr_key: ($) => + prec( + PREC.ATTRIBUTE_KEY, choice( - seq($.dot, $._inner_style_attribute), - seq($._colon, alias($._style_attr_block, $.block)) + "shape", + "label", + // sql + "constraint", + // image + "icon", + "width", + "height" ) ), - _style_attr_block: ($) => + _style_attribute: ($) => + prec( + PREC.ATTRIBUTE, + seq( + alias("style", $.attr_key), + choice( + seq($.dot, alias($._inner_style_attribute, $.attribute)), + seq($._colon, alias($._style_attribute_block, $.block)) + ) + ) + ), + + _style_attribute_block: ($) => seq( - spaces, "{", - spaces, - repeat(choice($._emptyline, seq($._inner_style_attribute, $._end))), - optional(seq($._inner_style_attribute, optional($._end))), - spaces, + repeat( + choice( + $._eol, + seq(alias($._inner_style_attribute, $.attribute), $._end) + ) + ), "}" ), _inner_style_attribute: ($) => - seq(spaces, alias($._style_attr_key, $.attr_key), $._colon, $.attr_value), - - _connection_attribute: ($) => - seq(alias($._connection_attr_key, $.attr_key), $._colon, $.attr_value), - - _shape_attr_key: ($) => - choice( - "shape", - "label", - // sql - "constraint", - // image - "icon", - "width", - "height" + prec( + PREC.ATTRIBUTE, + seq(alias($._style_attr_key, $.attr_key), $._colon, $.attr_value) ), - _style_attr_key: ($) => + _style_attr_key: ($) => choice($._common_style_attr_key, "3d"), + + _common_style_attr_key: ($) => choice( "opacity", "fill", @@ -161,7 +200,6 @@ module.exports = grammar({ "shadow", "multiple", "animated", - "3d", "link" ), @@ -169,15 +207,24 @@ module.exports = grammar({ _connection_attr_key: ($) => choice("source-arrowhead", "target-arrowhead"), - _colon: ($) => seq(spaces, ":"), + // - _arrow: ($) => seq(spaces, $.arrow), + label: ($) => choice($.string, $._unquoted_string), - arrow: ($) => choice(/-+>/, /--+/, /<-+/, /<-+>/), + attr_value: ($) => seq(choice($.string, $._unquoted_string)), - dot: ($) => token.immediate("."), + // -------------------------------------------- - _unquoted_string: ($) => token.immediate(/[^'"`\n;{}]+/), + _dash: ($) => token.immediate("-"), + + _colon: ($) => seq(":"), + + arrow: ($) => token(prec(PREC.ARROW, choice(/-+>/, /--+/, /<-+/, /<-+>/))), + + dot: ($) => token("."), + + _unquoted_string: ($) => + token(prec(PREC.UNQUOTED_STRING, /[\w\-?!]([^'"`\n;{}]*[\w\-?!])?/)), string: ($) => choice( @@ -186,12 +233,9 @@ module.exports = grammar({ seq("`", repeat(token.immediate(/[^`\n]+/)), "`") ), - line_comment: ($) => token(prec(-2, seq("#", /.*/))), + line_comment: ($) => token(prec(PREC.COMMENT, seq("#", /.*/))), - _word: ($) => /[\w\d]+/, - - _emptyline: ($) => seq(spaces, $._eof), - _eof: ($) => choice("\n", "\0"), - _end: ($) => seq(spaces, choice(";", $._eof)), + _eol: ($) => token(prec(PREC.EOL, "\n")), + _end: ($) => seq(choice(";", $._eol)), }, }); diff --git a/queries/highlights.scm b/queries/highlights.scm index f9e3551..54a6672 100644 --- a/queries/highlights.scm +++ b/queries/highlights.scm @@ -1,13 +1,9 @@ -; Special (treesitter don't overwrite) -;------------------------------------------------------------------------------- - -(ERROR) @error -(invalid (_) @error) ;------------------------------------------------------------------------------- (container_key) @constant (shape_key) @variable (attr_key) @property +(reserved) @error ; Literals ;------------------------------------------------------------------------------- @@ -42,4 +38,3 @@ ;------------------------------------------------------------------------------- (ERROR) @error -(invalid (_) @error) diff --git a/src/grammar.json b/src/grammar.json index 537f9ee..45a4ba0 100644 --- a/src/grammar.json +++ b/src/grammar.json @@ -1,6 +1,6 @@ { "name": "d2", - "word": "_word", + "word": "_identifier", "rules": { "source_file": { "type": "REPEAT", @@ -14,19 +14,42 @@ "members": [ { "type": "SYMBOL", - "name": "_emptyline" + "name": "_eol" }, { - "type": "SYMBOL", - "name": "_root_attribute" - }, - { - "type": "SYMBOL", - "name": "connection" - }, - { - "type": "SYMBOL", - "name": "_shape_definition" + "type": "SEQ", + "members": [ + { + "type": "CHOICE", + "members": [ + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_root_attribute" + }, + "named": true, + "value": "attribute" + }, + { + "type": "SYMBOL", + "name": "shape" + }, + { + "type": "SYMBOL", + "name": "container" + }, + { + "type": "SYMBOL", + "name": "connection" + } + ] + }, + { + "type": "SYMBOL", + "name": "_end" + } + ] } ] }, @@ -35,7 +58,7 @@ "members": [ { "type": "SYMBOL", - "name": "_shape_path" + "name": "_connection_path" }, { "type": "REPEAT1", @@ -44,11 +67,11 @@ "members": [ { "type": "SYMBOL", - "name": "_arrow" + "name": "arrow" }, { "type": "SYMBOL", - "name": "_shape_path" + "name": "_connection_path" } ] } @@ -57,228 +80,51 @@ "type": "CHOICE", "members": [ { - "type": "CHOICE", + "type": "SEQ", "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": [ - { - "type": "SYMBOL", - "name": "_shape_path" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "dot" - }, - { - "type": "SYMBOL", - "name": "_shape_attribute" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_colon" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] - } - }, - { - "type": "SYMBOL", - "name": "label" - } - ] - }, - { - "type": "BLANK" - } - ] - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_shape_block" - }, - "named": true, - "value": "block" - }, - { - "type": "BLANK" - } - ] - } - ] - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "SYMBOL", - "name": "_end" - } - ] - }, - "_shape_path": { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] - } - }, - { - "type": "REPEAT", - "content": { - "type": "SEQ", - "members": [ - { - "type": "ALIAS", - "content": { "type": "SYMBOL", - "name": "shape_key" + "name": "_colon" }, - "named": true, - "value": "container_key" - }, - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] + { + "type": "SYMBOL", + "name": "label" } - }, - { - "type": "SYMBOL", - "name": "dot" - }, - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] + ] + }, + { + "type": "BLANK" + } + ] + } + ] + }, + "_connection_path": { + "type": "SEQ", + "members": [ + { + "type": "REPEAT", + "content": { + "type": "PREC", + "value": 2, + "content": { + "type": "SEQ", + "members": [ + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "shape_key" + }, + "named": true, + "value": "container_key" + }, + { + "type": "SYMBOL", + "name": "dot" } - } - ] + ] + } } }, { @@ -287,6 +133,249 @@ } ] }, + "container": { + "type": "PREC", + "value": 2, + "content": { + "type": "SEQ", + "members": [ + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "shape_key" + }, + "named": true, + "value": "container_key" + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "dot" + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "shape" + }, + { + "type": "SYMBOL", + "name": "container" + } + ] + } + ] + }, + { + "type": "SEQ", + "members": [ + { + "type": "SEQ", + "members": [ + { + "type": "CHOICE", + "members": [ + { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_colon" + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "label" + }, + { + "type": "BLANK" + } + ] + } + ] + }, + { + "type": "BLANK" + } + ] + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SEQ", + "members": [ + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_container_block" + }, + "named": true, + "value": "block" + } + ] + }, + { + "type": "BLANK" + } + ] + } + ] + } + ] + } + ] + } + ] + } + }, + "_container_block": { + "type": "SEQ", + "members": [ + { + "type": "STRING", + "value": "{" + }, + { + "type": "REPEAT", + "content": { + "type": "SYMBOL", + "name": "_container_block_definition" + } + }, + { + "type": "STRING", + "value": "}" + } + ] + }, + "_container_block_definition": { + "type": "CHOICE", + "members": [ + { + "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": "_shape_attribute" + } + ] + }, + { + "type": "SYMBOL", + "name": "_end" + } + ] + } + ] + }, + "shape": { + "type": "PREC", + "value": 3, + "content": { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "shape_key" + }, + { + "type": "CHOICE", + "members": [ + { + "type": "CHOICE", + "members": [ + { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "dot" + }, + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_style_attribute" + }, + "named": true, + "value": "attribute" + } + ] + }, + { + "type": "SEQ", + "members": [ + { + "type": "CHOICE", + "members": [ + { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_colon" + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "label" + }, + { + "type": "BLANK" + } + ] + } + ] + }, + { + "type": "BLANK" + } + ] + } + ] + } + ] + }, + { + "type": "BLANK" + } + ] + } + ] + } + }, "shape_key": { "type": "CHOICE", "members": [ @@ -298,57 +387,8 @@ "type": "SEQ", "members": [ { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_dash" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_word" - }, - { - "type": "REPEAT1", - "content": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_word" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "REPEAT1", - "content": { - "type": "STRING", - "value": " " - } - }, - { - "type": "SYMBOL", - "name": "_dash" - } - ] - }, - { - "type": "SYMBOL", - "name": "_word" - } - ] - } - } - ] + "type": "SYMBOL", + "name": "_identifier" }, { "type": "CHOICE", @@ -366,461 +406,25 @@ } ] }, - "_dash": { - "type": "IMMEDIATE_TOKEN", + "_identifier": { + "type": "TOKEN", "content": { - "type": "STRING", - "value": "-" + "type": "PREC", + "value": 0, + "content": { + "type": "PATTERN", + "value": "\\-?([\\w\\d]+|([\\w\\d]+( +|\\-)[\\w\\d]+)+)" + } } }, - "label": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "string" - }, - { - "type": "SYMBOL", - "name": "_unquoted_string" - } - ] - }, - "attr_value": { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "string" - }, - { - "type": "SYMBOL", - "name": "_unquoted_string" - } - ] - } - ] - }, "_root_attribute": { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_root_attr_key" - }, - "named": true, - "value": "attr_key" - }, - { - "type": "SYMBOL", - "name": "_colon" - }, - { - "type": "SYMBOL", - "name": "attr_value" - }, - { - "type": "SYMBOL", - "name": "_end" - } - ] - }, - { - "type": "ALIAS", - "content": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_shape_attribute" - }, - { - "type": "SYMBOL", - "name": "_end" - } - ] - }, - "named": true, - "value": "invalid" - } - ] - }, - "_root_attr_key": { - "type": "STRING", - "value": "direction" - }, - "_shape_block": { "type": "SEQ", "members": [ - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] - } - }, - { - "type": "STRING", - "value": "{" - }, - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_emptyline" - }, - { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] - } - }, - { - "type": "SYMBOL", - "name": "_shape_block_definition" - } - ] - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_shape_block_definition" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_end" - }, - { - "type": "BLANK" - } - ] - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] - } - }, - { - "type": "STRING", - "value": "}" - } - ] - }, - "_shape_block_definition": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "connection" - }, - { - "type": "SYMBOL", - "name": "_shape_definition" - }, - { - "type": "SYMBOL", - "name": "_shape_attribute" - } - ] - }, - "_shape_attribute": { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_shape_attr_key" - }, - "named": true, - "value": "attr_key" - }, - { - "type": "SYMBOL", - "name": "_colon" - }, - { - "type": "SYMBOL", - "name": "attr_value" - } - ] - }, - { - "type": "SYMBOL", - "name": "_style_attribute" - } - ] - }, - "_style_attribute": { - "type": "SEQ", - "members": [ - { - "type": "ALIAS", - "content": { - "type": "STRING", - "value": "style" - }, - "named": true, - "value": "attr_key" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "dot" - }, - { - "type": "SYMBOL", - "name": "_inner_style_attribute" - } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_colon" - }, - { - "type": "ALIAS", - "content": { - "type": "SYMBOL", - "name": "_style_attr_block" - }, - "named": true, - "value": "block" - } - ] - } - ] - } - ] - }, - "_style_attr_block": { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] - } - }, - { - "type": "STRING", - "value": "{" - }, - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] - } - }, - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_emptyline" - }, - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_inner_style_attribute" - }, - { - "type": "SYMBOL", - "name": "_end" - } - ] - } - ] - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_inner_style_attribute" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_end" - }, - { - "type": "BLANK" - } - ] - } - ] - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] - } - }, - { - "type": "STRING", - "value": "}" - } - ] - }, - "_inner_style_attribute": { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] - } - }, { "type": "ALIAS", "content": { "type": "SYMBOL", - "name": "_style_attr_key" + "name": "_root_attr_key" }, "named": true, "value": "attr_key" @@ -835,14 +439,84 @@ } ] }, - "_connection_attribute": { + "_root_attr_key": { + "type": "CHOICE", + "members": [ + { + "type": "STRING", + "value": "direction" + }, + { + "type": "ALIAS", + "content": { + "type": "CHOICE", + "members": [ + { + "type": "STRING", + "value": "shape" + }, + { + "type": "STRING", + "value": "label" + }, + { + "type": "STRING", + "value": "constraint" + }, + { + "type": "STRING", + "value": "icon" + }, + { + "type": "STRING", + "value": "style" + }, + { + "type": "SYMBOL", + "name": "_common_style_attr_key" + }, + { + "type": "SYMBOL", + "name": "_text_attr_key" + } + ] + }, + "named": true, + "value": "reserved" + } + ] + }, + "_shape_attribute": { + "type": "CHOICE", + "members": [ + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_base_shape_attribute" + }, + "named": true, + "value": "attribute" + }, + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_style_attribute" + }, + "named": true, + "value": "attribute" + } + ] + }, + "_base_shape_attribute": { "type": "SEQ", "members": [ { "type": "ALIAS", "content": { "type": "SYMBOL", - "name": "_connection_attr_key" + "name": "_shape_attr_key" }, "named": true, "value": "attr_key" @@ -858,35 +532,180 @@ ] }, "_shape_attr_key": { - "type": "CHOICE", + "type": "PREC", + "value": 0, + "content": { + "type": "CHOICE", + "members": [ + { + "type": "STRING", + "value": "shape" + }, + { + "type": "STRING", + "value": "label" + }, + { + "type": "STRING", + "value": "constraint" + }, + { + "type": "STRING", + "value": "icon" + }, + { + "type": "STRING", + "value": "width" + }, + { + "type": "STRING", + "value": "height" + } + ] + } + }, + "_style_attribute": { + "type": "PREC", + "value": 0, + "content": { + "type": "SEQ", + "members": [ + { + "type": "ALIAS", + "content": { + "type": "STRING", + "value": "style" + }, + "named": true, + "value": "attr_key" + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "dot" + }, + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_inner_style_attribute" + }, + "named": true, + "value": "attribute" + } + ] + }, + { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_colon" + }, + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_style_attribute_block" + }, + "named": true, + "value": "block" + } + ] + } + ] + } + ] + } + }, + "_style_attribute_block": { + "type": "SEQ", "members": [ { "type": "STRING", - "value": "shape" + "value": "{" + }, + { + "type": "REPEAT", + "content": { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "_eol" + }, + { + "type": "SEQ", + "members": [ + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_inner_style_attribute" + }, + "named": true, + "value": "attribute" + }, + { + "type": "SYMBOL", + "name": "_end" + } + ] + } + ] + } }, { "type": "STRING", - "value": "label" - }, - { - "type": "STRING", - "value": "constraint" - }, - { - "type": "STRING", - "value": "icon" - }, - { - "type": "STRING", - "value": "width" - }, - { - "type": "STRING", - "value": "height" + "value": "}" } ] }, + "_inner_style_attribute": { + "type": "PREC", + "value": 0, + "content": { + "type": "SEQ", + "members": [ + { + "type": "ALIAS", + "content": { + "type": "SYMBOL", + "name": "_style_attr_key" + }, + "named": true, + "value": "attr_key" + }, + { + "type": "SYMBOL", + "name": "_colon" + }, + { + "type": "SYMBOL", + "name": "attr_value" + } + ] + } + }, "_style_attr_key": { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "_common_style_attr_key" + }, + { + "type": "STRING", + "value": "3d" + } + ] + }, + "_common_style_attr_key": { "type": "CHOICE", "members": [ { @@ -929,10 +748,6 @@ "type": "STRING", "value": "animated" }, - { - "type": "STRING", - "value": "3d" - }, { "type": "STRING", "value": "link" @@ -956,89 +771,97 @@ } ] }, - "_colon": { + "label": { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "string" + }, + { + "type": "SYMBOL", + "name": "_unquoted_string" + } + ] + }, + "attr_value": { "type": "SEQ", "members": [ { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] - } - }, + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "string" + }, + { + "type": "SYMBOL", + "name": "_unquoted_string" + } + ] + } + ] + }, + "_dash": { + "type": "IMMEDIATE_TOKEN", + "content": { + "type": "STRING", + "value": "-" + } + }, + "_colon": { + "type": "SEQ", + "members": [ { "type": "STRING", "value": ":" } ] }, - "_arrow": { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] - } - }, - { - "type": "SYMBOL", - "name": "arrow" - } - ] - }, "arrow": { - "type": "CHOICE", - "members": [ - { - "type": "PATTERN", - "value": "-+>" - }, - { - "type": "PATTERN", - "value": "--+" - }, - { - "type": "PATTERN", - "value": "<-+" - }, - { - "type": "PATTERN", - "value": "<-+>" + "type": "TOKEN", + "content": { + "type": "PREC", + "value": 0, + "content": { + "type": "CHOICE", + "members": [ + { + "type": "PATTERN", + "value": "-+>" + }, + { + "type": "PATTERN", + "value": "--+" + }, + { + "type": "PATTERN", + "value": "<-+" + }, + { + "type": "PATTERN", + "value": "<-+>" + } + ] } - ] + } }, "dot": { - "type": "IMMEDIATE_TOKEN", + "type": "TOKEN", "content": { "type": "STRING", "value": "." } }, "_unquoted_string": { - "type": "IMMEDIATE_TOKEN", + "type": "TOKEN", "content": { - "type": "PATTERN", - "value": "[^'\"`\\n;{}]+" + "type": "PREC", + "value": 0, + "content": { + "type": "PATTERN", + "value": "[\\w\\-?!]([^'\"`\\n;{}]*[\\w\\-?!])?" + } } }, "string": { @@ -1135,67 +958,20 @@ } } }, - "_word": { - "type": "PATTERN", - "value": "[\\w\\d]+" - }, - "_emptyline": { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] - } - }, - { - "type": "SYMBOL", - "name": "_eof" - } - ] - }, - "_eof": { - "type": "CHOICE", - "members": [ - { + "_eol": { + "type": "TOKEN", + "content": { + "type": "PREC", + "value": -1, + "content": { "type": "STRING", "value": "\n" - }, - { - "type": "STRING", - "value": "\u0000" } - ] + } }, "_end": { "type": "SEQ", "members": [ - { - "type": "REPEAT", - "content": { - "type": "CHOICE", - "members": [ - { - "type": "STRING", - "value": " " - }, - { - "type": "STRING", - "value": "\t" - } - ] - } - }, { "type": "CHOICE", "members": [ @@ -1205,7 +981,7 @@ }, { "type": "SYMBOL", - "name": "_eof" + "name": "_eol" } ] } @@ -1213,6 +989,10 @@ } }, "extras": [ + { + "type": "PATTERN", + "value": "[ \\f\\t\\v\\u00a0\\u1680\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000\\ufeff]" + }, { "type": "SYMBOL", "name": "line_comment" @@ -1220,25 +1000,8 @@ ], "conflicts": [ [ - "shape_key" - ], - [ - "_shape_path" - ], - [ - "_shape_block" - ], - [ - "_shape_block_definition" - ], - [ - "_style_attr_block" - ], - [ - "_inner_style_attribute" - ], - [ - "_emptyline" + "_connection_path", + "container" ] ], "precedences": [], diff --git a/src/node-types.json b/src/node-types.json index 2efdd90..810cf29 100644 --- a/src/node-types.json +++ b/src/node-types.json @@ -1,13 +1,18 @@ [ - { - "type": "arrow", - "named": true, - "fields": {} - }, { "type": "attr_key", "named": true, - "fields": {} + "fields": {}, + "children": { + "multiple": false, + "required": false, + "types": [ + { + "type": "reserved", + "named": true + } + ] + } }, { "type": "attr_value", @@ -25,12 +30,12 @@ } }, { - "type": "block", + "type": "attribute", "named": true, "fields": {}, "children": { "multiple": true, - "required": false, + "required": true, "types": [ { "type": "attr_key", @@ -40,28 +45,43 @@ "type": "attr_value", "named": true }, + { + "type": "attribute", + "named": true + }, { "type": "block", "named": true }, + { + "type": "dot", + "named": true + } + ] + } + }, + { + "type": "block", + "named": true, + "fields": {}, + "children": { + "multiple": true, + "required": false, + "types": [ + { + "type": "attribute", + "named": true + }, { "type": "connection", "named": true }, { - "type": "container_key", + "type": "container", "named": true }, { - "type": "dot", - "named": true - }, - { - "type": "label", - "named": true - }, - { - "type": "shape_key", + "type": "shape", "named": true } ] @@ -80,11 +100,38 @@ "named": true }, { - "type": "attr_key", + "type": "container_key", "named": true }, { - "type": "attr_value", + "type": "dot", + "named": true + }, + { + "type": "label", + "named": true + }, + { + "type": "shape_key", + "named": true + } + ] + } + }, + { + "type": "container", + "named": true, + "fields": {}, + "children": { + "multiple": true, + "required": true, + "types": [ + { + "type": "block", + "named": true + }, + { + "type": "container", "named": true }, { @@ -100,7 +147,7 @@ "named": true }, { - "type": "shape_key", + "type": "shape", "named": true } ] @@ -121,33 +168,6 @@ ] } }, - { - "type": "invalid", - "named": true, - "fields": {}, - "children": { - "multiple": true, - "required": false, - "types": [ - { - "type": "attr_key", - "named": true - }, - { - "type": "attr_value", - "named": true - }, - { - "type": "block", - "named": true - }, - { - "type": "dot", - "named": true - } - ] - } - }, { "type": "label", "named": true, @@ -163,6 +183,38 @@ ] } }, + { + "type": "reserved", + "named": true, + "fields": {} + }, + { + "type": "shape", + "named": true, + "fields": {}, + "children": { + "multiple": true, + "required": true, + "types": [ + { + "type": "attribute", + "named": true + }, + { + "type": "dot", + "named": true + }, + { + "type": "label", + "named": true + }, + { + "type": "shape_key", + "named": true + } + ] + } + }, { "type": "shape_key", "named": true, @@ -187,15 +239,7 @@ "required": false, "types": [ { - "type": "attr_key", - "named": true - }, - { - "type": "attr_value", - "named": true - }, - { - "type": "block", + "type": "attribute", "named": true }, { @@ -203,23 +247,11 @@ "named": true }, { - "type": "container_key", + "type": "container", "named": true }, { - "type": "dot", - "named": true - }, - { - "type": "invalid", - "named": true - }, - { - "type": "label", - "named": true - }, - { - "type": "shape_key", + "type": "shape", "named": true } ] @@ -230,22 +262,6 @@ "named": true, "fields": {} }, - { - "type": "\u0000", - "named": false - }, - { - "type": "\t", - "named": false - }, - { - "type": "\n", - "named": false - }, - { - "type": " ", - "named": false - }, { "type": "\"", "named": false @@ -274,6 +290,10 @@ "type": "animated", "named": false }, + { + "type": "arrow", + "named": true + }, { "type": "border-radius", "named": false @@ -282,6 +302,10 @@ "type": "constraint", "named": false }, + { + "type": "direction", + "named": false + }, { "type": "dot", "named": true diff --git a/src/parser.c b/src/parser.c index 00ca67858728554f4dfe2b6c1714f0df4c76f7f5..ab92f908956e862cf13bdeded950d225c1770623 100644 GIT binary patch literal 113709 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 diff --git a/test/corpus/attributes.txt b/test/corpus/attributes.txt index f48a55c..9017546 100644 --- a/test/corpus/attributes.txt +++ b/test/corpus/attributes.txt @@ -3,59 +3,75 @@ Root attribute ================================================================================ direction: value --------------------------------------------------------------------------------- - -(source_file - (attr_key) (attr_value) -) - -================================================================================ -Block shape attribute -================================================================================ -foo: { - shape: oval - - foo.bar.baz: { - shape: oval - } -} +shape: oval +label: ten +constraint: utehu +icon: huell +opacity: 1 +fill: red +stroke: red +stroke-width: 5 +stroke-dash: 4 +border-radius: 1 +font-color: red +shadow: true +multiple: true +animated: true +link: https://to +near: abc -------------------------------------------------------------------------------- (source_file - (shape_key) - (block - (attr_key) (attr_value) - (container_key) (dot) (container_key) (dot) (shape_key) - (block - (attr_key) (attr_value) - ) - ) -) + (attribute (attr_key) (attr_value)) - -================================================================================ -Inline shape attribute -================================================================================ -foo.shape: oval -foo.bar.baz.shape: oval - --------------------------------------------------------------------------------- - -(source_file - (shape_key) (dot) (attr_key) (attr_value) - (container_key) (dot) (container_key) (dot) (shape_key) (dot) (attr_key) (attr_value) + (attribute (attr_key (reserved)) (attr_value)) + (attribute (attr_key (reserved)) (attr_value)) + (attribute (attr_key (reserved)) (attr_value)) + (attribute (attr_key (reserved)) (attr_value)) + (attribute (attr_key (reserved)) (attr_value)) + (attribute (attr_key (reserved)) (attr_value)) + (attribute (attr_key (reserved)) (attr_value)) + (attribute (attr_key (reserved)) (attr_value)) + (attribute (attr_key (reserved)) (attr_value)) + (attribute (attr_key (reserved)) (attr_value)) + (attribute (attr_key (reserved)) (attr_value)) + (attribute (attr_key (reserved)) (attr_value)) + (attribute (attr_key (reserved)) (attr_value)) + (attribute (attr_key (reserved)) (attr_value)) + (attribute (attr_key (reserved)) (attr_value)) + (attribute (attr_key (reserved)) (attr_value)) ) ================================================================================ -Inline style attribute +Style attribute ================================================================================ foo.style.opacity: 5 +foo.style.fill: red +foo.style.stroke: red +foo.style.stroke-width: 5 +foo.style.stroke-dash: 4 +foo.style.border-radius: 1 +foo.style.font-color: red +foo.style.shadow: true +foo.style.multiple: true +foo.style.animated: true +foo.style.link: https://to -------------------------------------------------------------------------------- (source_file - (shape_key) (dot) (attr_key) (dot) (attr_key) (attr_value) + (shape (shape_key) (dot) (attribute (attr_key) (dot) (attribute (attr_key) (attr_value)))) + (shape (shape_key) (dot) (attribute (attr_key) (dot) (attribute (attr_key) (attr_value)))) + (shape (shape_key) (dot) (attribute (attr_key) (dot) (attribute (attr_key) (attr_value)))) + (shape (shape_key) (dot) (attribute (attr_key) (dot) (attribute (attr_key) (attr_value)))) + (shape (shape_key) (dot) (attribute (attr_key) (dot) (attribute (attr_key) (attr_value)))) + (shape (shape_key) (dot) (attribute (attr_key) (dot) (attribute (attr_key) (attr_value)))) + (shape (shape_key) (dot) (attribute (attr_key) (dot) (attribute (attr_key) (attr_value)))) + (shape (shape_key) (dot) (attribute (attr_key) (dot) (attribute (attr_key) (attr_value)))) + (shape (shape_key) (dot) (attribute (attr_key) (dot) (attribute (attr_key) (attr_value)))) + (shape (shape_key) (dot) (attribute (attr_key) (dot) (attribute (attr_key) (attr_value)))) + (shape (shape_key) (dot) (attribute (attr_key) (dot) (attribute (attr_key) (attr_value)))) ) ================================================================================ @@ -63,48 +79,150 @@ Block style attributes ================================================================================ foo.style: { opacity: 5 - - fill: red; + fill: red + stroke: red + stroke-width: 5 + stroke-dash: 4 + border-radius: 1 + font-color: red + shadow: true + multiple: true + animated: true + link: https://to } -------------------------------------------------------------------------------- (source_file - (shape_key) (dot) (attr_key) - (block - (attr_key) (attr_value) - (attr_key) (attr_value) + (shape + (shape_key) (dot) + (attribute + (attr_key) + (block + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + ) + ) ) ) ================================================================================ -Inline block style attributes +Container attributes ================================================================================ -foo.style: { opacity: 5; fill: red; } -foo.style: { opacity: 5 } +foo: { + shape: oval + label: Baz + constraint: primary-key + icon: pathto + width: 100 + height: 200 +} -------------------------------------------------------------------------------- (source_file - (shape_key) (dot) (attr_key) - (block - (attr_key) (attr_value) - (attr_key) (attr_value) - ) - (shape_key) (dot) (attr_key) - (block - (attr_key) (attr_value) + (container + (container_key) + (block + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + ) ) ) ================================================================================ -Color in string +Container style attributes ================================================================================ -foo.style.fill: "#ffffff"; +foo: { + style.opacity: 5 + style.fill: red + style.stroke: red + style.stroke-width: 5 + style.stroke-dash: 4 + style.border-radius: 1 + style.font-color: red + style.shadow: true + style.multiple: true + style.animated: true + style.link: https://to +} -------------------------------------------------------------------------------- (source_file - (shape_key) (dot) (attr_key) (dot) (attr_key) (attr_value (string)) + (container + (container_key) + (block + (attribute (attr_key) (dot) (attribute (attr_key) (attr_value))) + (attribute (attr_key) (dot) (attribute (attr_key) (attr_value))) + (attribute (attr_key) (dot) (attribute (attr_key) (attr_value))) + (attribute (attr_key) (dot) (attribute (attr_key) (attr_value))) + (attribute (attr_key) (dot) (attribute (attr_key) (attr_value))) + (attribute (attr_key) (dot) (attribute (attr_key) (attr_value))) + (attribute (attr_key) (dot) (attribute (attr_key) (attr_value))) + (attribute (attr_key) (dot) (attribute (attr_key) (attr_value))) + (attribute (attr_key) (dot) (attribute (attr_key) (attr_value))) + (attribute (attr_key) (dot) (attribute (attr_key) (attr_value))) + (attribute (attr_key) (dot) (attribute (attr_key) (attr_value))) + ) + ) +) + +================================================================================ +Block style attributes inside a container +================================================================================ +foo: { + style: { + opacity: 5 + fill: red + stroke: red + stroke-width: 5 + stroke-dash: 4 + border-radius: 1 + font-color: red + shadow: true + multiple: true + animated: true + link: https://to + } +} + +-------------------------------------------------------------------------------- + +(source_file + (container + (container_key) + (block + (attribute + (attr_key) + (block + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + (attribute (attr_key) (attr_value)) + ) + ) + ) + ) ) diff --git a/test/corpus/connection.txt b/test/corpus/connection.txt index f1d8b64..50ef980 100644 --- a/test/corpus/connection.txt +++ b/test/corpus/connection.txt @@ -196,3 +196,29 @@ foo.biz.baz -> bar.baz.biz: Label (label) ) ) + +================================================================================ +Connection of shapes inside a block of container +================================================================================ +foo.baz: { + foo -> biz: Label +} + +-------------------------------------------------------------------------------- + +(source_file + (container + (container_key) (dot) + (container + (container_key) + (block + (connection + (shape_key) + (arrow) + (shape_key) + (label) + ) + ) + ) + ) +) diff --git a/test/corpus/container.txt b/test/corpus/container.txt index d0b5691..704d2b5 100644 --- a/test/corpus/container.txt +++ b/test/corpus/container.txt @@ -2,22 +2,36 @@ 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)) + ) + ) ) ================================================================================ -Use quoted string as a shape key +Use quoted string as keys ================================================================================ 'foo'.'baz' -------------------------------------------------------------------------------- (source_file - (container_key (string)) (dot) (shape_key (string)) + (container + (container_key (string)) (dot) + (shape (shape_key (string))) + ) ) ================================================================================ @@ -35,20 +49,26 @@ 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 labeled container inside a labeled container using block ================================================================================ foo: Foo { @@ -62,13 +82,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 +116,111 @@ 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)) + ) ) ) + +================================================================================ +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 a container with complex keys and labels +================================================================================ + +Foo biz bar: Biz biz Bar { + bar biz baz: baz baz biz { + -biz-baz-Baz-: Biz buz Baz { + Helo world + } + } +} + +-------------------------------------------------------------------------------- + +(source_file + (container + (container_key) + (label) + (block + (container + (container_key) + (label) + (block + (container + (container_key) + (label) + (block + (shape (shape_key)) + ) + ) + ) + ) + ) + ) +) + +================================================================================ +Declare shapes sparsely in a container +================================================================================ + +Foo: Baz { + + biz + + baz + + bar + + +} + +-------------------------------------------------------------------------------- + +(source_file + (container + (container_key) + (label) + (block + (shape (shape_key)) + (shape (shape_key)) + (shape (shape_key)) + ) + ) +) diff --git a/test/corpus/shape.txt b/test/corpus/shape.txt index c73d2f7..cf52896 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,19 @@ 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 +Use quoted string as shape key and label ================================================================================ - -foo: { - bar: { - baz: { - biz - } - } -} +'foo': "Label" -------------------------------------------------------------------------------- (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) - ) - ) - ) + (shape (shape_key (string)) (label (string))) ) diff --git a/test/highlight/keyword.d2 b/test/highlight/attribute.d2 similarity index 95% rename from test/highlight/keyword.d2 rename to test/highlight/attribute.d2 index 72044c1..58f878a 100644 --- a/test/highlight/keyword.d2 +++ b/test/highlight/attribute.d2 @@ -6,7 +6,7 @@ direction: right; shape: oval # <- error -# ^ error +# ^ string baaaz.style: { # <- variable diff --git a/test/highlight/shape.d2 b/test/highlight/shape.d2 index ca98449..ef251c4 100644 --- a/test/highlight/shape.d2 +++ b/test/highlight/shape.d2 @@ -15,7 +15,7 @@ foo: Foo Bar # ^ string foo: Foo Bar { - # <- variable + # <- constant # ^ string # ^ punctuation.bracket diff --git a/tree-sitter-d2.wasm b/tree-sitter-d2.wasm index c9f5b7dd472e7e9d92497c1aa63b51ee17035672..609a0111088564c286b2066b776e87661ae38007 100755 GIT binary patch literal 25898 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

l#*$RF%_7aANo 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 F{|nFKIQ;+s literal 33162 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șBQ zZ8xKv_6d3NwQl3_#A)hf;&*see5rokc-+?q4{O~J;cwH*_LC{v(aaN8H~W^q%8SLs zgEu?M&+=^X=oc#8@(gt4^N`YQ{Gs96@^)EHD!wBCe<1+(-j^7D>;nV=(9cg`5xWfUp!3pz*8FA?sGl%vs^lt?V4;q$(4_{ zSswjzm(C;J@>Z&RnNqUAqhF(R9Ul*=>(Ru^xmw>s(h4=P`(N-R^$QQV_miCWbMuDv zx@pScy5Ec*_V|a~`3&De(a*$%H((y!Tb|OLacS1WSKV=k3tc=s%@aquN6&EU3{Uy! z=ftJgKV2`pb(8rv4pUylQ*MgxE{Ai^{YKQ2pVr3{$CDnt%pHebXYt0_W4GCDXV*Qi z-A0!mPj{Ek!)~47`6>OJc52|#dDLysLvEen8L``cj7#U?<6Ju4zPfZC@$#MR%4e+9 zqt|%!?H+x#N3ZA6mw5D-Jo=p;eVIpB>#);ao^>Lm?jxM*Qt1rOrCrx0@9*N}Aw3=? z3RA7)O|siBG)h`H{7T0gVwWA>b}N3(hd0|wx8wgrPd>`Q&t~Jfxm$nTqoX|hoOXD{ zrSp*Dx7U}}@l}E+PVe~Lt$1Wg3EB-mQx4||k3PVq+kK#|$SzO*Z61A~OE>L$G2UrZ zPbw{|sGY$|YRk{BEh(+7ttpvMK7*B2SJjqQRN)`;CT+_2(n;m=tfaK2rg}O7V{sT; zT}zfzYHMIy%kYntmzR`PPn=i|Wqf(Xx#MfuIn^~|%WDd1O2<}Aox;X}wxF!Kvbu)B zu(G;}mDE&M*OuU)y{xFJpnr9om8inb!9NT>!3R&WM9Ee72g}K+0_SX8MP((cEIp?j zDgN1XCMg(#tDaC^Fuh`I?RY~zsg%ygmQEROvgLWn)T+r-t82^0mcXe3|NKZvdG$CZ z+hkg4<%@FCDA> zlYky$*%;hB_G8kfq!ukw)sv`EOZ+43lgdkLdnD)eFnQ7vni&AvxVy<$zTK03ZJzXn z=JD-jdco;R&DxCylkQRrB{f@#8WgHbOXCYt4_gXXJ-a2ht~E(&7Z|8^k@0uKJIIzS z7f<{%Dl!xD*0(|4tnX#21 z*$mmQ$>_4Sm$tM_O-A-`u$M6nZiNg4e-We+&O2agY6fWnq4TA{_ThLI9~O1dbHzaX23e`3dLuL8@_nxz=alcshjY zW@HJ@iy^}y-I2Ef(iid)Bpc=3gYp(Z_CYRz420~4Y=q#YDjSVs6G#vEzYd@O1Nagu Al>h($