Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: using struct-types with Capture interface is broken #140

Open
torbenschinke opened this issue Apr 10, 2021 · 3 comments
Open

bug: using struct-types with Capture interface is broken #140

torbenschinke opened this issue Apr 10, 2021 · 3 comments

Comments

@torbenschinke
Copy link

In setField nodes.go:592 the type is asserted to a string to assemble the slice parameter for the Capture method. That is wrong according to the following test:

type Boxes struct {
	Pos          lexer.Position
	Boxes Box `@@`
}

type Box struct{
	Pos          lexer.Position
	Val string `@Ident`
}

func (b *Box) Capture(values []string) error {
	b.Val = values[0]
	return nil
}

func TestBoxedCapture(t *testing.T) {
	lex := stateful.MustSimple([]stateful.Rule{
		{"Ident", `[a-zA-Z](\w|\.|/|:|-)*`, nil},
		{"whitespace", `\s+`, nil},
	})

	parser := participle.MustBuild(&Boxes{},
		participle.Lexer(lex),
		participle.UseLookahead(2),
	)

	boxed:=&Boxes{}
	if err:=parser.ParseString("test", "abc::cdef.abc", boxed);err!=nil{
		t.Fatal(err)
	}
}

This causes a type assertion panic:

panic: interface conversion: interface {} is parser.Box, not string [recovered]
	panic: interface conversion: interface {} is parser.Box, not string

goroutine 6 [running]:
testing.tRunner.func1.2(0x1166b80, 0xc00006c810)
	/usr/local/go/src/testing/testing.go:1144 +0x332
testing.tRunner.func1(0xc000001380)
	/usr/local/go/src/testing/testing.go:1147 +0x4b6
panic(0x1166b80, 0xc00006c810)
	/usr/local/go/src/runtime/panic.go:965 +0x1b9
github.com/alecthomas/participle/v2.setField(0xc000022880, 0x1, 0x1, 0x116f320, 0xc0000585a0, 0x199, 0x114c743, 0x5, 0x0, 0x0, ...)
	/Users/tschinke/go/pkg/mod/github.com/alecthomas/participle/v2@v2.0.0-alpha4/nodes.go:582 +0x23e5
github.com/alecthomas/participle/v2.(*parseContext).Apply(0xc0000102d0, 0xc000022880, 0x1)
	/Users/tschinke/go/pkg/mod/github.com/alecthomas/participle/v2@v2.0.0-alpha4/context.go:53 +0x150
github.com/alecthomas/participle/v2.(*strct).Parse(0xc000114d20, 0xc0000102d0, 0x116f320, 0xc0000584e0, 0x199, 0x199, 0xc00007fcc8, 0x113635e, 0x1168200, 0xc00006c4b0)
	/Users/tschinke/go/pkg/mod/github.com/alecthomas/participle/v2@v2.0.0-alpha4/nodes.go:121 +0x5cc
github.com/alecthomas/participle/v2.(*Parser).parseInto(0xc000114c40, 0xc0000102d0, 0x1156840, 0xc0000584e0, 0x16, 0x11c23c8, 0x128e940)
	/Users/tschinke/go/pkg/mod/github.com/alecthomas/participle/v2@v2.0.0-alpha4/parser.go:239 +0xd0
github.com/alecthomas/participle/v2.(*Parser).parseOne(0xc000114c40, 0xc0000102d0, 0x1156840, 0xc0000584e0, 0x16, 0xc000022800, 0x1)
	/Users/tschinke/go/pkg/mod/github.com/alecthomas/participle/v2@v2.0.0-alpha4/parser.go:222 +0x77
github.com/alecthomas/participle/v2.(*Parser).ParseFromLexer(0xc000114c40, 0xc000114e70, 0x1156840, 0xc0000584e0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/Users/tschinke/go/pkg/mod/github.com/alecthomas/participle/v2@v2.0.0-alpha4/parser.go:152 +0x4c5
github.com/alecthomas/participle/v2.(*Parser).parse(0xc000114c40, 0x11c1a28, 0xc000058540, 0x1156840, 0xc0000584e0, 0x0, 0x0, 0x0, 0x0, 0xc0000584e0)
	/Users/tschinke/go/pkg/mod/github.com/alecthomas/participle/v2@v2.0.0-alpha4/parser.go:160 +0xe5
github.com/alecthomas/participle/v2.(*Parser).ParseString(0xc000114c40, 0x118ff92, 0x4, 0x11918f3, 0xd, 0x1156840, 0xc0000584e0, 0x0, 0x0, 0x0, ...)
	/Users/tschinke/go/pkg/mod/github.com/alecthomas/participle/v2@v2.0.0-alpha4/parser.go:189 +0xf5
github.com/golangee/architecture/adl/parser.TestBoxedCapture(0xc000001380)
	/Users/tschinke/git/github.com/golangee/architecture.git/adl/parser/parser_test.go:73 +0x1fa
testing.tRunner(0xc000001380, 0x119ad10)
	/usr/local/go/src/testing/testing.go:1194 +0xef
created by testing.(*T).Run
	/usr/local/go/src/testing/testing.go:1239 +0x2b3

btw, just closing #139 "as incorrect" was a bit offensive.

@alecthomas
Copy link
Owner

Definitely looks like a bug.

btw, just closing #139 "as incorrect" was a bit offensive.

Given the information you provided in the previous ticket, it was incorrect - it does work with other types including bool, ints, etc., just not structs. If you'd provided the above panic there, then I would have had enough information to determine that there was a bug.

@alecthomas
Copy link
Owner

alecthomas commented Jun 30, 2021

I've finally had a chance to look at this. This is a bug, but not quite the one expected.

Altering the grammar to the following works as expected:

-	Boxes Box `@@`
+ 	Boxes *Box `@Ident`

The Capture interface:

transform captured tokens into field values

What this means in practice is that you have to capture tokens explicitly as above with @Ident rather than @@. If you want to use @@ you should implement that Parseable interface.

However there are two bugs in Participle here:

  • @@ should not panic in this case.
  • Box shouldn't have to be a pointer to work.

alecthomas added a commit that referenced this issue Jun 30, 2021
See #140, fixes second bug.
@torbenschinke
Copy link
Author

cool, many thanks for the follow up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants