-
Notifications
You must be signed in to change notification settings - Fork 35
/
grammar.go
69 lines (61 loc) · 1.29 KB
/
grammar.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
66
67
68
69
//nolint:govet
package rust_grammar
import (
"bytes"
"os"
"github.com/alecthomas/participle/v2"
"github.com/alecthomas/participle/v2/lexer"
"github.com/gabotechs/dep-tree/internal/language"
)
type Statement struct {
Mod *Mod `@@`
Use *Use `| @@`
Pub *Pub `| @@`
}
type File struct {
Statements []*Statement `(@@ | ANY | ALL | String | Punct | PathSep | Ident)*`
Path string
loc int
size int
}
func (f File) Loc() int {
return f.loc
}
func (f File) Size() int {
return f.size
}
var (
lex = lexer.MustSimple(
[]lexer.SimpleRule{
{"ALL", `\*`},
{"PathSep", `::`},
{"Punct", `[,{}()]`},
{"String", `"(?:\\.|[^"])*"`},
{"Ident", `(r#)?[_$a-zA-Z][_$a-zA-Z0-9]*`},
{"Comment", `//.*|/\*(.|\n)*?\*/`},
{"Whitespace", `\s+`},
{"ANY", `.`},
},
)
parser = participle.MustBuild[File](
participle.Lexer(lex),
participle.Elide("Whitespace", "Comment"),
participle.UseLookahead(1024),
)
)
func Parse(filePath string) (*language.FileInfo, error) {
content, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}
file, err := parser.ParseBytes(filePath, content)
if err != nil {
return nil, err
}
return &language.FileInfo{
Content: file,
Loc: bytes.Count(content, []byte("\n")),
Size: len(content),
AbsPath: filePath,
}, nil
}