-
Notifications
You must be signed in to change notification settings - Fork 122
/
directive.go
65 lines (55 loc) · 1.58 KB
/
directive.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// Copyright 2021-2024 Zenauth Ltd.
// SPDX-License-Identifier: Apache-2.0
package internal
import (
"fmt"
"github.com/alecthomas/participle/v2"
"github.com/alecthomas/participle/v2/lexer"
)
func NewParser() (*participle.Parser[REPLDirective], error) {
lex, err := lexer.New(lexer.Rules{
"Root": {
{Name: "Ident", Pattern: `[a-zA-Z]\w*(\.\w+)*`},
{Name: "#", Pattern: `#`},
{Name: "Int", Pattern: `[0-9]+`},
{Name: "Path", Pattern: `(?:((?:[\/]?)(?:[^\/]+\/)+)([^\/]+))`},
{Name: "Assign", Pattern: `=`, Action: lexer.Push("Assign")},
{Name: "Whitespace", Pattern: `\s+`},
},
"Assign": {
{Name: "Any", Pattern: `.*$`, Action: lexer.Pop()},
},
})
if err != nil {
return nil, fmt.Errorf("failed to create lexer: %w", err)
}
parser, err := participle.Build[REPLDirective](
participle.Lexer(lex),
participle.Elide("Whitespace"),
)
if err != nil {
return nil, fmt.Errorf("failed to create parser: %w", err)
}
return parser, nil
}
//nolint:govet
type REPLDirective struct {
Exit bool `parser:"@('q'|'quit'|'exit')"`
Reset bool `parser:"| @'reset'"`
Vars bool `parser:"| @'vars'"`
Help bool `parser:"| @('h' | 'help')"`
Rules bool `parser:"| @'rules'"`
Load *LoadDirective `parser:"| @@"`
Exec *ExecDirective `parser:"| @@"`
Let *LetDirective `parser:"| @@"`
}
type LetDirective struct {
Name string `parser:"'let' @Ident"`
Expr string `parser:"'=' @Any"`
}
type LoadDirective struct {
Path string `parser:"'load' @Path"`
}
type ExecDirective struct {
RuleID int `parser:"'exec' '#'@Int"`
}