Skip to content

Commit a5ceb28

Browse files
committed
fix: add lexer compile time validation for group by
So that if there's a mismatch between capture groups and emitters, it will error early.
1 parent cd5c4a8 commit a5ceb28

File tree

12 files changed

+667
-529
lines changed

12 files changed

+667
-529
lines changed

cmd/chromad/templates/index.html.tmpl

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,24 @@
1212
<body>
1313
<div class="container">
1414

15-
<h1 class="title">Chroma Playground ({{.Version}})</h1>
15+
<nav class="level">
16+
<div class="level-left">
17+
<div class="level-item">
18+
<h1 class="title">Chroma Playground ({{.Version}})</h1>
19+
</div>
20+
</div>
21+
<div class="level-right">
22+
<div class="level-item">
23+
<div class="container has-text-centered">
24+
<button name="darkmode" id="theme-toggle" class="button">
25+
<span class="icon is-small">
26+
<ion-icon id="theme-icon" name="ellipse-outline"></ion-icon>
27+
</span>
28+
</button>
29+
</div>
30+
</div>
31+
</div>
32+
</nav>
1633

1734
<div class="notification">
1835
<button class="delete"></button>

emitters.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ type Emitter interface {
1010
Emit(groups []string, state *LexerState) Iterator
1111
}
1212

13+
// ValidatingEmitter is an Emitter that can validate against a compiled rule.
14+
type ValidatingEmitter interface {
15+
Emitter
16+
ValidateEmitter(rule *CompiledRule) error
17+
}
18+
1319
// SerialisableEmitter is an Emitter that can be serialised and deserialised to/from JSON.
1420
type SerialisableEmitter interface {
1521
Emitter
@@ -30,13 +36,22 @@ type byGroupsEmitter struct {
3036
Emitters
3137
}
3238

39+
var _ ValidatingEmitter = (*byGroupsEmitter)(nil)
40+
3341
// ByGroups emits a token for each matching group in the rule's regex.
3442
func ByGroups(emitters ...Emitter) Emitter {
3543
return &byGroupsEmitter{Emitters: emitters}
3644
}
3745

3846
func (b *byGroupsEmitter) EmitterKind() string { return "bygroups" }
3947

48+
func (b *byGroupsEmitter) ValidateEmitter(rule *CompiledRule) error {
49+
if len(rule.Regexp.GetGroupNumbers())-1 != len(b.Emitters) {
50+
return fmt.Errorf("number of groups %d does not match number of emitters %d", len(rule.Regexp.GetGroupNumbers())-1, len(b.Emitters))
51+
}
52+
return nil
53+
}
54+
4055
func (b *byGroupsEmitter) Emit(groups []string, state *LexerState) Iterator {
4156
iterators := make([]Iterator, 0, len(groups)-1)
4257
if len(b.Emitters) != len(groups)-1 {

lexers/embedded/angular2.xml

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,103 +6,104 @@
66
<rules>
77
<state name="attr">
88
<rule pattern="&#34;.*?&#34;">
9-
<token type="LiteralString"/>
10-
<pop depth="1"/>
9+
<token type="LiteralString" />
10+
<pop depth="1" />
1111
</rule>
1212
<rule pattern="&#39;.*?&#39;">
13-
<token type="LiteralString"/>
14-
<pop depth="1"/>
13+
<token type="LiteralString" />
14+
<pop depth="1" />
1515
</rule>
1616
<rule pattern="[^\s&gt;]+">
17-
<token type="LiteralString"/>
18-
<pop depth="1"/>
17+
<token type="LiteralString" />
18+
<pop depth="1" />
1919
</rule>
2020
</state>
2121
<state name="root">
2222
<rule pattern="[^{([*#]+">
23-
<token type="Other"/>
23+
<token type="Other" />
2424
</rule>
2525
<rule pattern="(\{\{)(\s*)">
2626
<bygroups>
27-
<token type="CommentPreproc"/>
28-
<token type="Text"/>
27+
<token type="CommentPreproc" />
28+
<token type="Text" />
2929
</bygroups>
30-
<push state="ngExpression"/>
30+
<push state="ngExpression" />
3131
</rule>
3232
<rule pattern="([([]+)([\w:.-]+)([\])]+)(\s*)(=)(\s*)">
3333
<bygroups>
34-
<token type="Punctuation"/>
35-
<token type="NameAttribute"/>
36-
<token type="Punctuation"/>
37-
<token type="Text"/>
38-
<token type="Operator"/>
39-
<token type="Text"/>
34+
<token type="Punctuation" />
35+
<token type="NameAttribute" />
36+
<token type="Punctuation" />
37+
<token type="Text" />
38+
<token type="Operator" />
39+
<token type="Text" />
4040
</bygroups>
41-
<push state="attr"/>
41+
<push state="attr" />
4242
</rule>
4343
<rule pattern="([([]+)([\w:.-]+)([\])]+)(\s*)">
4444
<bygroups>
45-
<token type="Punctuation"/>
46-
<token type="NameAttribute"/>
47-
<token type="Punctuation"/>
48-
<token type="Text"/>
45+
<token type="Punctuation" />
46+
<token type="NameAttribute" />
47+
<token type="Punctuation" />
48+
<token type="TextWhitespace" />
4949
</bygroups>
5050
</rule>
5151
<rule pattern="([*#])([\w:.-]+)(\s*)(=)(\s*)">
5252
<bygroups>
53-
<token type="Punctuation"/>
54-
<token type="NameAttribute"/>
55-
<token type="Punctuation"/>
56-
<token type="Operator"/>
53+
<token type="Punctuation" />
54+
<token type="NameAttribute" />
55+
<token type="Punctuation" />
56+
<token type="Operator" />
57+
<token type="TextWhitespace" />
5758
</bygroups>
58-
<push state="attr"/>
59+
<push state="attr" />
5960
</rule>
6061
<rule pattern="([*#])([\w:.-]+)(\s*)">
6162
<bygroups>
62-
<token type="Punctuation"/>
63-
<token type="NameAttribute"/>
64-
<token type="Punctuation"/>
63+
<token type="Punctuation" />
64+
<token type="NameAttribute" />
65+
<token type="Punctuation" />
6566
</bygroups>
6667
</rule>
6768
</state>
6869
<state name="ngExpression">
6970
<rule pattern="\s+(\|\s+)?">
70-
<token type="Text"/>
71+
<token type="Text" />
7172
</rule>
7273
<rule pattern="\}\}">
73-
<token type="CommentPreproc"/>
74-
<pop depth="1"/>
74+
<token type="CommentPreproc" />
75+
<pop depth="1" />
7576
</rule>
7677
<rule pattern=":?(true|false)">
77-
<token type="LiteralStringBoolean"/>
78+
<token type="LiteralStringBoolean" />
7879
</rule>
7980
<rule pattern=":?&#34;(\\\\|\\&#34;|[^&#34;])*&#34;">
80-
<token type="LiteralStringDouble"/>
81+
<token type="LiteralStringDouble" />
8182
</rule>
8283
<rule pattern=":?&#39;(\\\\|\\&#39;|[^&#39;])*&#39;">
83-
<token type="LiteralStringSingle"/>
84+
<token type="LiteralStringSingle" />
8485
</rule>
8586
<rule pattern="[0-9](\.[0-9]*)?(eE[+-][0-9])?[flFLdD]?|0[xX][0-9a-fA-F]+[Ll]?">
86-
<token type="LiteralNumber"/>
87+
<token type="LiteralNumber" />
8788
</rule>
8889
<rule pattern="[a-zA-Z][\w-]*(\(.*\))?">
89-
<token type="NameVariable"/>
90+
<token type="NameVariable" />
9091
</rule>
9192
<rule pattern="\.[\w-]+(\(.*\))?">
92-
<token type="NameVariable"/>
93+
<token type="NameVariable" />
9394
</rule>
9495
<rule pattern="(\?)(\s*)([^}\s]+)(\s*)(:)(\s*)([^}\s]+)(\s*)">
9596
<bygroups>
96-
<token type="Operator"/>
97-
<token type="Text"/>
98-
<token type="LiteralString"/>
99-
<token type="Text"/>
100-
<token type="Operator"/>
101-
<token type="Text"/>
102-
<token type="LiteralString"/>
103-
<token type="Text"/>
97+
<token type="Operator" />
98+
<token type="Text" />
99+
<token type="LiteralString" />
100+
<token type="Text" />
101+
<token type="Operator" />
102+
<token type="Text" />
103+
<token type="LiteralString" />
104+
<token type="Text" />
104105
</bygroups>
105106
</rule>
106107
</state>
107108
</rules>
108-
</lexer>
109+
</lexer>

lexers/embedded/applescript.xml

Lines changed: 78 additions & 57 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)