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

View file

@ -1251,6 +1251,40 @@
"value": "class_name" "value": "class_name"
}, },
"_base_shape_attribute": { "_base_shape_attribute": {
"type": "CHOICE",
"members": [
{
"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": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
@ -1271,6 +1305,8 @@
"name": "attr_value" "name": "attr_value"
} }
] ]
}
]
}, },
"_shape_attr_key": { "_shape_attr_key": {
"type": "PREC", "type": "PREC",
@ -1298,10 +1334,6 @@
"type": "STRING", "type": "STRING",
"value": "tooltip" "value": "tooltip"
}, },
{
"type": "STRING",
"value": "constraint"
},
{ {
"type": "STRING", "type": "STRING",
"value": "icon" "value": "icon"
@ -1325,6 +1357,14 @@
] ]
} }
}, },
"_shape_list_attr_key": {
"type": "PREC",
"value": 0,
"content": {
"type": "STRING",
"value": "constraint"
}
},
"_style_attribute": { "_style_attribute": {
"type": "PREC", "type": "PREC",
"value": 0, "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": { "attr_value": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
@ -1940,7 +2047,7 @@
"value": -1, "value": -1,
"content": { "content": {
"type": "PATTERN", "type": "PATTERN",
"value": "[^'\"`\\\\|\\n\\s;{}]([^\\\\\\n;{}]*[^\\\\\\n\\s;{}])?" "value": "[^'\"`\\\\|\\n\\s;{}\\[\\]]([^\\\\\\n;{}\\[\\]]*[^\\\\\\n\\s;{}\\[\\]])?"
} }
} }
} }
@ -2167,6 +2274,9 @@
[ [
"class_list" "class_list"
], ],
[
"attr_value_list"
],
[ [
"_text_block_attrs" "_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", "type": "attribute",
"named": true, "named": true,
@ -61,6 +76,10 @@
"type": "attr_value", "type": "attr_value",
"named": true "named": true
}, },
{
"type": "attr_value_list",
"named": true
},
{ {
"type": "attribute", "type": "attribute",
"named": true "named": true

Binary file not shown.

View file

@ -488,4 +488,30 @@ footer
(shape (shape_key)) (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 Declare shape with many classes
================================================================================ ================================================================================
fee.class: [biz]
foo.class: [biz; baz] foo.class: [biz; baz]
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
(source_file (source_file
(shape
(shape_key)
(dot)
(attribute
(keyword_class)
(class_list
(class_name)
)
)
)
(shape (shape
(shape_key) (shape_key)
(dot) (dot)
@ -181,6 +192,12 @@ Declare a class in the container
================================================================================ ================================================================================
foo: { foo: {
class: biz class: biz
class: [biz]
class: [biz; baz]
class: [
biz
baz
]
} }
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -193,6 +210,26 @@ foo: {
(keyword_class) (keyword_class)
(class_name) (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.