alecthomas / participle

A parser library for Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

example not working?

Diliz opened this issue · comments

Hello there!

Thanks for your work!

I'm currently trying to use participle to make a custom parser, I understood the basics (I think), I first tried to use the ini example and iterate other it (changing ini format a little and try to make a new format that looks like ini but is not the same, to see if I can parse it anyway).

I first had no @int defined at first, had the following error: panic: Number: unknown token type "Int"

I declared the int type in the inilexer, then used what was the in the test file, but no success, got the following error:
panic: duplicated key '@@*' in struct cmd.INI [recovered]

Do you have this issue as well? Am I missing something here?

package cmd

import (
	"path/filepath"

	"github.com/alecthomas/participle/v2"
	"github.com/alecthomas/participle/v2/lexer"
)

type INI struct {
	Properties []*Property `@@*`
	Sections   []*Section  `@@*`
}

type Section struct {
	Identifier string      `"["@Ident"]"`
	Properties []*Property `@@*`
}

type Property struct {
	Key   string `@Ident "="`
	Value Value  `@@`
}

type Value interface{ value() }

type String struct {
	String string `@String`
}

func (String) value() {}

type Number struct {
	// Number float64 `@Float | @Int`
	Number float64 `@Float`
}

func (Number) value() {}

func iniParser(fileLocationPath string) map[string]interface{} {
	iniLexer := lexer.MustSimple([]lexer.SimpleRule{
		{`Ident`, `[a-zA-Z][a-zA-Z_\d]*`},
		{`String`, `"(?:\\.|[^"])*"`},
		{`Float`, `\d+(?:\.\d+)?`},
		{`Punct`, `[][=]`},
		{"comment", `[#;][^\n]*`},
		{"whitespace", `\s+`},
	})
	parser := participle.MustBuild[INI](
		participle.Lexer(iniLexer),
		participle.Unquote("String"),
		participle.Union[Value](String{}, Number{}),
	)
	iniContent, err := parser.ParseString("", `
global = 1

[section]
value = "str"
`)
	if err != nil {
		log.Panicf("error: %s", err.Error())
	}
	log.Infof("error: %s", err.Error())
}

I can't quite decide if you're saying the INI example doesn't work, or your code doesn't work? The INI example does work so I assume it's the latter.

Your example code seems to work fine for me also: https://go.dev/play/p/DfcUaaEh976

If you can, paste a play.golang.org link with the reproduction and reopen.