aboutsummaryrefslogtreecommitdiff
path: root/grammar.js
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-09-14 21:52:11 +0200
committerThomas Voss <mail@thomasvoss.com> 2024-09-14 21:52:11 +0200
commit642d5264e0d7b3d3870d13c2cc4a04987ee65ab6 (patch)
tree53268bb7f35994d911e7c95e6f46cb5d7788b6fd /grammar.js
parent291cb06fc2d578ac19c01ebda9b71f94733af0e8 (diff)
Completely overhaul the grammar
Diffstat (limited to 'grammar.js')
-rw-r--r--grammar.js70
1 files changed, 24 insertions, 46 deletions
diff --git a/grammar.js b/grammar.js
index 0f13c6b..a18091c 100644
--- a/grammar.js
+++ b/grammar.js
@@ -1,60 +1,38 @@
+const IDENT = /\p{XID_Start}[-\p{XID_Continue}]*/u
+
module.exports = grammar({
name: 'gsp',
- extras: $ => [$._S],
+ extras: $ => [/\p{Pattern_White_Space}+/u],
rules: {
- source_file: $ => repeat(choice($.comment, $.node)),
+ document: $ => repeat($._toplevel),
+ _toplevel: $ => choice($.comment, $.node),
- comment: $ => seq(
- '/',
- optional($.node_name),
- optional($.attribute_list),
- '{',
- optional($.node_body),
- '}',
- ),
+ comment: $ => seq('/', $.node),
+ node: $ => seq($.node_name, optional($.attrs), $.node_body),
- node: $ => seq(
- optional('>'),
- $.node_name,
- optional($.attribute_list),
+ node_name: $ => IDENT,
+ node_body: $ => seq(
'{',
- optional($.node_body),
- '}',
- ),
-
- node_body: $ => choice(
- repeat1(choice($.comment, $.node)),
- seq(choice('-', '='), optional($.text)),
- ),
-
- node_name: $ => /[a-zA-Z:_\u{000C0}-\u{000D6}\u{000D8}-\u{000F6}\u{000F8}-\u{002FF}\u{00370}-\u{0037D}\u{0037F}-\u{01FFF}\u{0200C}-\u{0200D}\u{02070}-\u{0218F}\u{02C00}-\u{02FEF}\u{03001}-\u{0D7FF}\u{0F900}-\u{0FDCF}\u{0FDF0}-\u{0FFFD}\u{10000}-\u{EFFFF}][a-zA-Z0-9:_\-.ยท\u{00300}-\u{0036F}\u{0203F}-\u{02040}\u{000C0}-\u{000D6}\u{000D8}-\u{000F6}\u{000F8}-\u{002FF}\u{00370}-\u{0037D}\u{0037F}-\u{01FFF}\u{0200C}-\u{0200D}\u{02070}-\u{0218F}\u{02C00}-\u{02FEF}\u{03001}-\u{0D7FF}\u{0F900}-\u{0FDCF}\u{0FDF0}-\u{0FFFD}\u{10000}-\u{EFFFF}]*/u,
-
- text: $ => repeat1(
choice(
- $.literal_text,
- seq('@', choice($.comment, $.node)),
- ),
- ),
-
- literal_text: $ => /(\\[@}\\]|[^@}\\])+/,
-
- attribute_list: $ => repeat1($.attribute),
-
- attribute: $ => choice(
- $.class_shorthand,
- $.id_shorthand,
- seq(
- $.attribute_name,
- optional(seq('=', $.attribute_value)),
+ repeat($._toplevel),
+ seq(choice('-', '='), optional($.text)),
),
+ '}',
),
- class_shorthand: $ => /\.\P{White_Space}+/u,
- id_shorthand: $ => /#\P{White_Space}+/u,
+ attrs: $ => repeat1(choice(
+ $.attr,
+ $.id_attr,
+ $.class_attr,
+ )),
- attribute_name: $ => /[a-zA-Z0-9_-]+/,
- attribute_value: $ => /"(\\.|[^"\\])*"/,
+ attr: $ => seq(IDENT, '=', /"(\\["\\]|[^"\\])+"/),
+ id_attr: $ => seq('#', token.immediate(IDENT)),
+ class_attr: $ => seq('.', token.immediate(IDENT)),
- _S: $ => /\p{White_Space}+/u,
+ text: $ => repeat1(choice(
+ /(\\[@}\\]|[^@}\\])+/,
+ seq('@', $._toplevel),
+ )),
},
})