grammar: add support of list variables

Closes #16
This commit is contained in:
Dmitriy Pleshevskiy 2023-06-21 16:51:47 +03:00
parent 8a9d50043d
commit 0003298cb8
Signed by: pleshevskiy
GPG key ID: 79C4487B44403985
7 changed files with 234 additions and 29 deletions

View file

@ -32,8 +32,16 @@ const attrAlias = mkAlias(($) => $.attribute);
// mkAttrCont :: ($ -> Rule) -> ($ -> Rule) -> $ -> Rule
const mkAttrCont = (onValue) => (onKey) => ($) =>
seq(onKey($), $._colon, onValue($));
const mkBaseAttr = (onKey) =>
mkAttrCont(($) => $.attr_value)(attrKeyAlias(onKey));
const mkAttr = (onKey) => mkAttrCont(($) => $.attr_value)(attrKeyAlias(onKey));
const mkListAttr = (onKey) =>
mkAttrCont(
either(
($) => $.attr_value_list,
($) => $.attr_value
)
)(attrKeyAlias(onKey));
const either = (onLeft, onRight) => ($) => choice(onLeft($), onRight($));
module.exports = grammar({
name: "d2",
@ -59,6 +67,7 @@ module.exports = grammar({
[$._classes_block],
[$._classes_item_block],
[$.class_list],
[$.attr_value_list],
[$._text_block_attrs],
],
@ -216,7 +225,7 @@ module.exports = grammar({
// attributes
_root_attribute: mkBaseAttr(($) => $._root_attr_key),
_root_attribute: mkAttr(($) => $._root_attr_key),
_root_attr_key: ($) =>
choice(
@ -249,7 +258,10 @@ module.exports = grammar({
_class_name: ($) => alias($.shape_key, $.class_name),
_base_shape_attribute: mkBaseAttr(($) => $._shape_attr_key),
_base_shape_attribute: either(
mkListAttr(($) => $._shape_list_attr_key),
mkAttr(($) => $._shape_attr_key)
),
_shape_attr_key: ($) =>
prec(
@ -260,9 +272,6 @@ module.exports = grammar({
"label",
"link",
"tooltip",
// sql
"constraint",
// image
"icon",
"width",
"height",
@ -271,6 +280,8 @@ module.exports = grammar({
)
),
_shape_list_attr_key: ($) => prec(PREC.ATTRIBUTE_KEY, "constraint"),
_style_attribute: ($) =>
prec(
PREC.ATTRIBUTE,
@ -285,7 +296,7 @@ module.exports = grammar({
_style_attribute_block: mkBlock(attrAlias(($) => $._inner_style_attribute)),
_inner_style_attribute: mkBaseAttr(($) => $._style_attr_key),
_inner_style_attribute: mkAttr(($) => $._style_attr_key),
_grid_attr_key: ($) =>
choice(
@ -321,7 +332,7 @@ module.exports = grammar({
"text-transform"
),
_text_shape_attribute: mkBaseAttr(($) => $._text_attr_key),
_text_shape_attribute: mkAttr(($) => $._text_attr_key),
_text_attr_key: ($) => "near",
@ -355,6 +366,8 @@ module.exports = grammar({
label: ($) => choice($.string, $._unquoted_string),
attr_value_list: mkList(($) => $.attr_value),
attr_value: ($) =>
seq(choice($.boolean, $.integer, $.float, $.string, $._unquoted_string)),
@ -375,7 +388,7 @@ module.exports = grammar({
token(
prec(
PREC.UNQUOTED_STRING,
/[^'"`\\|\n\s;{}]([^\\\n;{}]*[^\\\n\s;{}])?/
/[^'"`\\|\n\s;{}\[\]]([^\\\n;{}\[\]]*[^\\\n\s;{}\[\]])?/
)
)
)

View file

@ -1251,24 +1251,60 @@
"value": "class_name"
},
"_base_shape_attribute": {
"type": "SEQ",
"type": "CHOICE",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_shape_attr_key"
},
"named": true,
"value": "attr_key"
"type": "SEQ",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_shape_list_attr_key"
},
"named": true,
"value": "attr_key"
},
{
"type": "SYMBOL",
"name": "_colon"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "attr_value_list"
},
{
"type": "SYMBOL",
"name": "attr_value"
}
]
}
]
},
{
"type": "SYMBOL",
"name": "_colon"
},
{
"type": "SYMBOL",
"name": "attr_value"
"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"
}
]
}
]
},
@ -1298,10 +1334,6 @@
"type": "STRING",
"value": "tooltip"
},
{
"type": "STRING",
"value": "constraint"
},
{
"type": "STRING",
"value": "icon"
@ -1325,6 +1357,14 @@
]
}
},
"_shape_list_attr_key": {
"type": "PREC",
"value": 0,
"content": {
"type": "STRING",
"value": "constraint"
}
},
"_style_attribute": {
"type": "PREC",
"value": 0,
@ -1843,6 +1883,73 @@
}
]
},
"attr_value_list": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "["
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_eol"
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "attr_value"
},
{
"type": "SYMBOL",
"name": "_end"
}
]
}
]
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "attr_value"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_end"
},
{
"type": "BLANK"
}
]
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "]"
}
]
},
"attr_value": {
"type": "SEQ",
"members": [
@ -1940,7 +2047,7 @@
"value": -1,
"content": {
"type": "PATTERN",
"value": "[^'\"`\\\\|\\n\\s;{}]([^\\\\\\n;{}]*[^\\\\\\n\\s;{}])?"
"value": "[^'\"`\\\\|\\n\\s;{}\\[\\]]([^\\\\\\n;{}\\[\\]]*[^\\\\\\n\\s;{}\\[\\]])?"
}
}
}
@ -2167,6 +2274,9 @@
[
"class_list"
],
[
"attr_value_list"
],
[
"_text_block_attrs"
]

View file

@ -45,6 +45,21 @@
]
}
},
{
"type": "attr_value_list",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "attr_value",
"named": true
}
]
}
},
{
"type": "attribute",
"named": true,
@ -61,6 +76,10 @@
"type": "attr_value",
"named": true
},
{
"type": "attr_value_list",
"named": true
},
{
"type": "attribute",
"named": true

Binary file not shown.

View file

@ -488,4 +488,30 @@ footer
(shape (shape_key))
)
================================================================================
Declare a attribute with many values
================================================================================
block: {
constraint: primary_key
constraint: [primary_key]
constraint: [primary_key; unique]
constraint: [
primary_key
unique
]
}
--------------------------------------------------------------------------------
(source_file
(container
(container_key)
(block
(attribute (attr_key) (attr_value))
(attribute (attr_key) (attr_value_list (attr_value)))
(attribute (attr_key) (attr_value_list (attr_value) (attr_value)))
(attribute (attr_key) (attr_value_list (attr_value) (attr_value)))
)
)
)

View file

@ -158,11 +158,22 @@ foo.class: biz
================================================================================
Declare shape with many classes
================================================================================
fee.class: [biz]
foo.class: [biz; baz]
--------------------------------------------------------------------------------
(source_file
(shape
(shape_key)
(dot)
(attribute
(keyword_class)
(class_list
(class_name)
)
)
)
(shape
(shape_key)
(dot)
@ -181,6 +192,12 @@ Declare a class in the container
================================================================================
foo: {
class: biz
class: [biz]
class: [biz; baz]
class: [
biz
baz
]
}
--------------------------------------------------------------------------------
@ -193,6 +210,26 @@ foo: {
(keyword_class)
(class_name)
)
(attribute
(keyword_class)
(class_list
(class_name)
)
)
(attribute
(keyword_class)
(class_list
(class_name)
(class_name)
)
)
(attribute
(keyword_class)
(class_list
(class_name)
(class_name)
)
)
)
)
)

Binary file not shown.