Skip to content

Commit b1ee217

Browse files
authored
feat: json example (#395)
* feat: json example * fix: Whitespace contains EOL in Json lexer
1 parent 499a330 commit b1ee217

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed

_examples/json/main.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// nolint: golint, dupl
2+
package main
3+
4+
import (
5+
"os"
6+
7+
"github.com/alecthomas/kong"
8+
9+
"github.com/alecthomas/participle/v2"
10+
"github.com/alecthomas/participle/v2/lexer"
11+
)
12+
13+
var (
14+
jsonLexer = lexer.MustSimple([]lexer.SimpleRule{
15+
{Name: "Comment", Pattern: `\/\/[^\n]*`},
16+
{Name: "String", Pattern: `"(\\"|[^"])*"`},
17+
{Name: "Number", Pattern: `[-+]?(\d*\.)?\d+`},
18+
{Name: "Punct", Pattern: `[-[!@#$%^&*()+_={}\|:;"'<,>.?/]|]`},
19+
{Name: "Null", Pattern: "null"},
20+
{Name: "True", Pattern: "true"},
21+
{Name: "False", Pattern: "false"},
22+
{Name: "EOL", Pattern: `[\n\r]+`},
23+
{Name: "Whitespace", Pattern: `[ \t]+`},
24+
})
25+
26+
jsonParser = participle.MustBuild[Json](
27+
participle.Lexer(jsonLexer),
28+
participle.Unquote("String"),
29+
participle.Elide("Whitespace", "EOL"),
30+
participle.UseLookahead(2),
31+
)
32+
33+
cli struct {
34+
File string `arg:"" type:"existingfile" help:"File to parse."`
35+
}
36+
)
37+
38+
// Parse a Json string.
39+
func Parse(data []byte) (*Json, error) {
40+
json, err := jsonParser.ParseBytes("", data)
41+
if err != nil {
42+
return nil, err
43+
}
44+
return json, nil
45+
}
46+
47+
type Json struct {
48+
Pos lexer.Position
49+
50+
Object *Object `parser:"@@ |"`
51+
Array *Array `parser:"@@ |"`
52+
Number *string `parser:"@Number |"`
53+
String *string `parser:"@String |"`
54+
False *string `parser:"@False |"`
55+
True *string `parser:"@True |"`
56+
Null *string `parser:"@Null"`
57+
}
58+
59+
type Object struct {
60+
Pos lexer.Position
61+
62+
Pairs []*Pair `parser:"'{' @@ (',' @@)* '}'"`
63+
}
64+
65+
type Pair struct {
66+
Pos lexer.Position
67+
68+
Key string `parser:"@String ':'"`
69+
Value *Json `parser:"@@"`
70+
}
71+
72+
type Array struct {
73+
Pos lexer.Position
74+
75+
Items []*Json `parser:"'[' @@ (',' @@)* ']'"`
76+
}
77+
78+
func main() {
79+
ctx := kong.Parse(&cli)
80+
data, err := os.ReadFile(cli.File)
81+
ctx.FatalIfErrorf(err)
82+
83+
res, err := Parse(data)
84+
ctx.FatalIfErrorf(err)
85+
ctx.Printf("res is: %v", res)
86+
}

_examples/json/main_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package main
2+
3+
import (
4+
"os"
5+
"testing"
6+
7+
require "github.com/alecthomas/assert/v2"
8+
)
9+
10+
func TestParse(t *testing.T) {
11+
src, err := os.ReadFile("./test.json")
12+
require.NoError(t, err)
13+
_, err = Parse(src)
14+
require.NoError(t, err)
15+
}

_examples/json/test.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"list": [1, 1.2, 1, -1, {"foo": "bar"}, true, false, null],
3+
"object": {
4+
"foo1": "bar2",
5+
"foo2": true,
6+
"foo3": false,
7+
"foo4": null,
8+
"foo5": 1,
9+
"foo6": "ss"
10+
}
11+
}

0 commit comments

Comments
 (0)