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

proposal: allowing non-string types to Capture tokens #139

Closed
torbenschinke opened this issue Apr 9, 2021 · 3 comments
Closed

proposal: allowing non-string types to Capture tokens #139

torbenschinke opened this issue Apr 9, 2021 · 3 comments

Comments

@torbenschinke
Copy link

I can only use the Capture(values []string) error interface on types with the underlying string type. It seems like an unneeded restriction.

In setField nodes.go:592 the type is asserted to a string to assemble the slice parameter for the Capture method. I wonder if we could use the lexer tokens to build the same just without the type assertion.

//			for _, v := range fieldValue {
//				ifv = append(ifv, v.Interface().(string))
//			}

			for _, token := range tokens {
				ifv = append(ifv, token.Value)
			}
@torbenschinke torbenschinke changed the title allowing non-string types to Capture tokens proposal: allowing non-string types to Capture tokens Apr 9, 2021
@alecthomas
Copy link
Owner

That is incorrect. You can implement Capture on any type. See the hcl example where it captures into a
bool.

@torbenschinke
Copy link
Author

Well, on structs it does not work:

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

@torbenschinke
Copy link
Author

I found a captureableWithPosition struct in parser_test.go but it is not used anywhere for testing, perhaps for a reason?

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