Skip to content

Commit 0ef7496

Browse files
committed
Improve support for flow-style productions in YAML.
1 parent 272380e commit 0ef7496

File tree

5 files changed

+272
-13
lines changed

5 files changed

+272
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## 0.2.3-wip
22

33
- Add initial, basic support for `python`.
4+
- Improve support for flow-style productions in YAML.
45

56
## 0.2.2
67

lib/src/language/yaml.dart

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ final class YamlGrammar extends MatcherGrammar {
1414
Matcher.include(_anchorsAndAliases),
1515
Matcher.include(_tags),
1616
Matcher.include(_multilineIndicators),
17-
Matcher.include(_keys),
17+
Matcher.include(_blockKeys),
1818
Matcher.include(_literals),
19+
Matcher.include(_flowSequence),
20+
Matcher.include(_flowMapping),
1921
Matcher.include(_strings),
2022
Matcher.include(_punctuation),
2123
];
@@ -74,6 +76,58 @@ final class YamlGrammar extends MatcherGrammar {
7476

7577
static const Tag _multiline = Tag('multiline', parent: Tags.stringLiteral);
7678

79+
Matcher _flowSequence() => Matcher.wrapped(
80+
begin: Matcher.verbatim(
81+
'[',
82+
tag: const Tag('begin', parent: Tags.arrayLiteral),
83+
),
84+
end: Matcher.verbatim(
85+
']',
86+
tag: const Tag('end', parent: Tags.arrayLiteral),
87+
),
88+
content: Matcher.include(_flowContent),
89+
tag: Tags.arrayLiteral,
90+
);
91+
92+
Matcher _flowMapping() => Matcher.wrapped(
93+
begin: Matcher.verbatim(
94+
'{',
95+
tag: const Tag('begin', parent: Tags.mapLiteral),
96+
),
97+
end: Matcher.verbatim(
98+
'}',
99+
tag: const Tag('end', parent: Tags.mapLiteral),
100+
),
101+
content: Matcher.include(_flowContent),
102+
tag: Tags.mapLiteral,
103+
);
104+
105+
Matcher _flowContent() => Matcher.options([
106+
Matcher.include(_comments),
107+
Matcher.include(_anchorsAndAliases),
108+
Matcher.include(_tags),
109+
Matcher.include(_flowKeys),
110+
Matcher.include(_literals),
111+
Matcher.include(_flowSequence),
112+
Matcher.include(_flowMapping),
113+
Matcher.include(_doubleQuotedString),
114+
Matcher.include(_singleQuotedString),
115+
Matcher.include(_flowPlainScalar),
116+
Matcher.regex(r'\?(?=\s)', tag: Tags.punctuation),
117+
Matcher.regex(r',', tag: Tags.separator),
118+
Matcher.regex(r':', tag: Tags.separator),
119+
]);
120+
121+
/// A plain scalar restricted for flow context.
122+
///
123+
/// Unlike [_plainScalar], the continuation excludes flow indicator
124+
/// characters (`[`, `]`, `{`, `}`, `,`) which have structural
125+
/// meaning inside flow collections.
126+
Matcher _flowPlainScalar() => Matcher.regex(
127+
r'''[^\s:#\[\]{},&*!|>'"%@`-][^\n:#\[\]{},]*(?<!\s)''',
128+
tag: Tags.unquotedString,
129+
);
130+
77131
Matcher _strings() => Matcher.options([
78132
Matcher.include(_doubleQuotedString),
79133
Matcher.include(_singleQuotedString),
@@ -175,7 +229,7 @@ final class YamlGrammar extends MatcherGrammar {
175229
),
176230
]);
177231

178-
Matcher _keys() => Matcher.options([
232+
Matcher _blockKeys() => Matcher.options([
179233
Matcher.regex(
180234
r'[a-zA-Z0-9_-]+(?=\s*:(?:\s|$))',
181235
tag: Tags.property,
@@ -190,6 +244,21 @@ final class YamlGrammar extends MatcherGrammar {
190244
),
191245
]);
192246

247+
Matcher _flowKeys() => Matcher.options([
248+
Matcher.regex(
249+
r'[a-zA-Z0-9_-]+(?=\s*:(?:\s|$|[\]},]))',
250+
tag: Tags.property,
251+
),
252+
Matcher.regex(
253+
r'"(?:[^"\\]|\\.)*"(?=\s*:)',
254+
tag: _quotedKey,
255+
),
256+
Matcher.regex(
257+
r"'(?:[^']|'')*'(?=\s*:)",
258+
tag: _quotedKey,
259+
),
260+
]);
261+
193262
static const Tag _quotedKey = Tag('quoted', parent: Tags.property);
194263

195264
Matcher _punctuation() => Matcher.options([
@@ -199,7 +268,6 @@ final class YamlGrammar extends MatcherGrammar {
199268
),
200269
Matcher.regex(r':', tag: Tags.separator),
201270
Matcher.regex(r',', tag: Tags.separator),
202-
Matcher.regex(r'[\[\]{}]', tag: Tags.punctuation),
203271
Matcher.regex(r'\?(?=\s)', tag: Tags.punctuation),
204272
]);
205273
}

test/goldens/yaml/basic.out

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,22 @@ source-text-data-yaml-identifier-property
4646
^
4747
source-text-data-yaml-whitespace
4848
^
49-
source-text-data-yaml-punctuation
49+
source-text-data-yaml-literal-collection-array-literal-collection-array-begin
5050
^
51-
source-text-data-yaml-literal-string-quoted-double-literal-string-quoted-double-begin
51+
source-text-data-yaml-literal-collection-array-literal-string-quoted-double-literal-string-quoted-double-begin
5252
^^^^^^^^^^^^^^^
53-
source-text-data-yaml-literal-string-quoted-double-literal-string-unquoted
53+
source-text-data-yaml-literal-collection-array-literal-string-quoted-double-literal-string-unquoted
5454
^
55-
source-text-data-yaml-literal-string-quoted-double-literal-string-quoted-double-end
55+
source-text-data-yaml-literal-collection-array-literal-string-quoted-double-literal-string-quoted-double-end
5656
^
57-
source-text-data-yaml-punctuation-separator
57+
source-text-data-yaml-literal-collection-array-punctuation-separator
5858
^
59-
source-text-data-yaml-whitespace
59+
source-text-data-yaml-literal-collection-array-whitespace
6060
^
61-
source-text-data-yaml-literal-string-quoted-single-literal-string-quoted-single-begin
61+
source-text-data-yaml-literal-collection-array-literal-string-quoted-single-literal-string-quoted-single-begin
6262
^^^^^^^^^^
63-
source-text-data-yaml-literal-string-quoted-single-literal-string-unquoted
63+
source-text-data-yaml-literal-collection-array-literal-string-quoted-single-literal-string-unquoted
6464
^
65-
source-text-data-yaml-literal-string-quoted-single-literal-string-quoted-single-end
65+
source-text-data-yaml-literal-collection-array-literal-string-quoted-single-literal-string-quoted-single-end
6666
^
67-
source-text-data-yaml-punctuation
67+
source-text-data-yaml-literal-collection-array-literal-collection-array-end

test/goldens/yaml/flow.in

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
sequence: [one, two, three]
2+
mapping: {name: Dart, version: 3}
3+
nested: {langs: [Dart, Rust], active: true}
4+
quoted: ["Double quoted", 'Single quoted']
5+
literals: [true, false, null, 42, 3.14]
6+
empty_sequence: []
7+
empty_map: {}

test/goldens/yaml/flow.out

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
sequence: [one, two, three]
2+
^^^^^^^^
3+
source-text-data-yaml-identifier-property
4+
^
5+
source-text-data-yaml-punctuation-separator
6+
^
7+
source-text-data-yaml-whitespace
8+
^
9+
source-text-data-yaml-literal-collection-array-literal-collection-array-begin
10+
^^^
11+
source-text-data-yaml-literal-collection-array-literal-string-unquoted
12+
^
13+
source-text-data-yaml-literal-collection-array-punctuation-separator
14+
^
15+
source-text-data-yaml-literal-collection-array-whitespace
16+
^^^
17+
source-text-data-yaml-literal-collection-array-literal-string-unquoted
18+
^
19+
source-text-data-yaml-literal-collection-array-punctuation-separator
20+
^
21+
source-text-data-yaml-literal-collection-array-whitespace
22+
^^^^^
23+
source-text-data-yaml-literal-collection-array-literal-string-unquoted
24+
^
25+
source-text-data-yaml-literal-collection-array-literal-collection-array-end
26+
mapping: {name: Dart, version: 3}
27+
^^^^^^^
28+
source-text-data-yaml-identifier-property
29+
^
30+
source-text-data-yaml-punctuation-separator
31+
^
32+
source-text-data-yaml-whitespace
33+
^
34+
source-text-data-yaml-literal-collection-map-literal-collection-map-begin
35+
^^^^
36+
source-text-data-yaml-literal-collection-map-identifier-property
37+
^
38+
source-text-data-yaml-literal-collection-map-punctuation-separator
39+
^
40+
source-text-data-yaml-literal-collection-map-whitespace
41+
^^^^
42+
source-text-data-yaml-literal-collection-map-literal-string-unquoted
43+
^
44+
source-text-data-yaml-literal-collection-map-punctuation-separator
45+
^
46+
source-text-data-yaml-literal-collection-map-whitespace
47+
^^^^^^^
48+
source-text-data-yaml-literal-collection-map-identifier-property
49+
^
50+
source-text-data-yaml-literal-collection-map-punctuation-separator
51+
^
52+
source-text-data-yaml-literal-collection-map-whitespace
53+
^
54+
source-text-data-yaml-literal-collection-map-literal-number
55+
^
56+
source-text-data-yaml-literal-collection-map-literal-collection-map-end
57+
nested: {langs: [Dart, Rust], active: true}
58+
^^^^^^
59+
source-text-data-yaml-identifier-property
60+
^
61+
source-text-data-yaml-punctuation-separator
62+
^
63+
source-text-data-yaml-whitespace
64+
^
65+
source-text-data-yaml-literal-collection-map-literal-collection-map-begin
66+
^^^^^
67+
source-text-data-yaml-literal-collection-map-identifier-property
68+
^
69+
source-text-data-yaml-literal-collection-map-punctuation-separator
70+
^
71+
source-text-data-yaml-literal-collection-map-whitespace
72+
^
73+
source-text-data-yaml-literal-collection-map-literal-collection-array-literal-collection-array-begin
74+
^^^^
75+
source-text-data-yaml-literal-collection-map-literal-collection-array-literal-string-unquoted
76+
^
77+
source-text-data-yaml-literal-collection-map-literal-collection-array-punctuation-separator
78+
^
79+
source-text-data-yaml-literal-collection-map-literal-collection-array-whitespace
80+
^^^^
81+
source-text-data-yaml-literal-collection-map-literal-collection-array-literal-string-unquoted
82+
^
83+
source-text-data-yaml-literal-collection-map-literal-collection-array-literal-collection-array-end
84+
^
85+
source-text-data-yaml-literal-collection-map-punctuation-separator
86+
^
87+
source-text-data-yaml-literal-collection-map-whitespace
88+
^^^^^^
89+
source-text-data-yaml-literal-collection-map-identifier-property
90+
^
91+
source-text-data-yaml-literal-collection-map-punctuation-separator
92+
^
93+
source-text-data-yaml-literal-collection-map-whitespace
94+
^^^^
95+
source-text-data-yaml-literal-collection-map-literal-boolean-true
96+
^
97+
source-text-data-yaml-literal-collection-map-literal-collection-map-end
98+
quoted: ["Double quoted", 'Single quoted']
99+
^^^^^^
100+
source-text-data-yaml-identifier-property
101+
^
102+
source-text-data-yaml-punctuation-separator
103+
^
104+
source-text-data-yaml-whitespace
105+
^
106+
source-text-data-yaml-literal-collection-array-literal-collection-array-begin
107+
^
108+
source-text-data-yaml-literal-collection-array-literal-string-quoted-double-literal-string-quoted-double-begin
109+
^^^^^^^^^^^^^
110+
source-text-data-yaml-literal-collection-array-literal-string-quoted-double-literal-string-unquoted
111+
^
112+
source-text-data-yaml-literal-collection-array-literal-string-quoted-double-literal-string-quoted-double-end
113+
^
114+
source-text-data-yaml-literal-collection-array-punctuation-separator
115+
^
116+
source-text-data-yaml-literal-collection-array-whitespace
117+
^
118+
source-text-data-yaml-literal-collection-array-literal-string-quoted-single-literal-string-quoted-single-begin
119+
^^^^^^^^^^^^^
120+
source-text-data-yaml-literal-collection-array-literal-string-quoted-single-literal-string-unquoted
121+
^
122+
source-text-data-yaml-literal-collection-array-literal-string-quoted-single-literal-string-quoted-single-end
123+
^
124+
source-text-data-yaml-literal-collection-array-literal-collection-array-end
125+
literals: [true, false, null, 42, 3.14]
126+
^^^^^^^^
127+
source-text-data-yaml-identifier-property
128+
^
129+
source-text-data-yaml-punctuation-separator
130+
^
131+
source-text-data-yaml-whitespace
132+
^
133+
source-text-data-yaml-literal-collection-array-literal-collection-array-begin
134+
^^^^
135+
source-text-data-yaml-literal-collection-array-literal-boolean-true
136+
^
137+
source-text-data-yaml-literal-collection-array-punctuation-separator
138+
^
139+
source-text-data-yaml-literal-collection-array-whitespace
140+
^^^^^
141+
source-text-data-yaml-literal-collection-array-literal-boolean-false
142+
^
143+
source-text-data-yaml-literal-collection-array-punctuation-separator
144+
^
145+
source-text-data-yaml-literal-collection-array-whitespace
146+
^^^^
147+
source-text-data-yaml-literal-collection-array-literal-null
148+
^
149+
source-text-data-yaml-literal-collection-array-punctuation-separator
150+
^
151+
source-text-data-yaml-literal-collection-array-whitespace
152+
^^
153+
source-text-data-yaml-literal-collection-array-literal-number
154+
^
155+
source-text-data-yaml-literal-collection-array-punctuation-separator
156+
^
157+
source-text-data-yaml-literal-collection-array-whitespace
158+
^^^^
159+
source-text-data-yaml-literal-collection-array-literal-number
160+
^
161+
source-text-data-yaml-literal-collection-array-literal-collection-array-end
162+
empty_sequence: []
163+
^^^^^^^^^^^^^^
164+
source-text-data-yaml-identifier-property
165+
^
166+
source-text-data-yaml-punctuation-separator
167+
^
168+
source-text-data-yaml-whitespace
169+
^
170+
source-text-data-yaml-literal-collection-array-literal-collection-array-begin
171+
^
172+
source-text-data-yaml-literal-collection-array-literal-collection-array-end
173+
empty_map: {}
174+
^^^^^^^^^
175+
source-text-data-yaml-identifier-property
176+
^
177+
source-text-data-yaml-punctuation-separator
178+
^
179+
source-text-data-yaml-whitespace
180+
^
181+
source-text-data-yaml-literal-collection-map-literal-collection-map-begin
182+
^
183+
source-text-data-yaml-literal-collection-map-literal-collection-map-end

0 commit comments

Comments
 (0)