diff --git a/_examples/json/main.go b/_examples/json/main.go new file mode 100644 index 0000000..22dcc43 --- /dev/null +++ b/_examples/json/main.go @@ -0,0 +1,86 @@ +// nolint: golint, dupl +package main + +import ( + "os" + + "github.com/alecthomas/kong" + + "github.com/alecthomas/participle/v2" + "github.com/alecthomas/participle/v2/lexer" +) + +var ( + jsonLexer = lexer.MustSimple([]lexer.SimpleRule{ + {Name: "Comment", Pattern: `\/\/[^\n]*`}, + {Name: "String", Pattern: `"(\\"|[^"])*"`}, + {Name: "Number", Pattern: `[-+]?(\d*\.)?\d+`}, + {Name: "Punct", Pattern: `[-[!@#$%^&*()+_={}\|:;"'<,>.?/]|]`}, + {Name: "Null", Pattern: "null"}, + {Name: "True", Pattern: "true"}, + {Name: "False", Pattern: "false"}, + {Name: "EOL", Pattern: `[\n\r]+`}, + {Name: "Whitespace", Pattern: `[ \t]+`}, + }) + + jsonParser = participle.MustBuild[Json]( + participle.Lexer(jsonLexer), + participle.Unquote("String"), + participle.Elide("Whitespace", "EOL"), + participle.UseLookahead(2), + ) + + cli struct { + File string `arg:"" type:"existingfile" help:"File to parse."` + } +) + +// Parse a Json string. +func Parse(data []byte) (*Json, error) { + json, err := jsonParser.ParseBytes("", data) + if err != nil { + return nil, err + } + return json, nil +} + +type Json struct { + Pos lexer.Position + + Object *Object `parser:"@@ |"` + Array *Array `parser:"@@ |"` + Number *string `parser:"@Number |"` + String *string `parser:"@String |"` + False *string `parser:"@False |"` + True *string `parser:"@True |"` + Null *string `parser:"@Null"` +} + +type Object struct { + Pos lexer.Position + + Pairs []*Pair `parser:"'{' @@ (',' @@)* '}'"` +} + +type Pair struct { + Pos lexer.Position + + Key string `parser:"@String ':'"` + Value *Json `parser:"@@"` +} + +type Array struct { + Pos lexer.Position + + Items []*Json `parser:"'[' @@ (',' @@)* ']'"` +} + +func main() { + ctx := kong.Parse(&cli) + data, err := os.ReadFile(cli.File) + ctx.FatalIfErrorf(err) + + res, err := Parse(data) + ctx.FatalIfErrorf(err) + ctx.Printf("res is: %v", res) +} diff --git a/_examples/json/main_test.go b/_examples/json/main_test.go new file mode 100644 index 0000000..f667ae7 --- /dev/null +++ b/_examples/json/main_test.go @@ -0,0 +1,15 @@ +package main + +import ( + "os" + "testing" + + require "github.com/alecthomas/assert/v2" +) + +func TestParse(t *testing.T) { + src, err := os.ReadFile("./test.json") + require.NoError(t, err) + _, err = Parse(src) + require.NoError(t, err) +} diff --git a/_examples/json/test.json b/_examples/json/test.json new file mode 100644 index 0000000..dae87b5 --- /dev/null +++ b/_examples/json/test.json @@ -0,0 +1,11 @@ +{ + "list": [1, 1.2, 1, -1, {"foo": "bar"}, true, false, null], + "object": { + "foo1": "bar2", + "foo2": true, + "foo3": false, + "foo4": null, + "foo5": 1, + "foo6": "ss" + } +} \ No newline at end of file