alecthomas/participle

Need advice: Wrong branch is picked on non-trivial match

Closed this issue · 1 comments

Hello, and thank you for the awesome library!

I'm trying to create a parser for source code. The stripped down example parsing expressions and assignments would be as following:

package main

import (
	"fmt"

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

const source = `
2;
x+y.z+1;
a=5+x;
a.b=4+y;
a.b=3+x.y+z;
a.b.c;
`

type Scope struct {
	Entry []*Entry `( @@ ";"+)*`
}

type Entry struct {
	Assignment *Value      `(@@ "=")?`
	Expression *Expression `@@`
}

type Expression struct {
	Left     *Value      `@@`
	Operator string      `( @"+"`
	Right    *Expression `@@ )?`
}

type Value struct {
	Int  int   `@Int`
	Path *Path `| @@`
}

type Path struct {
	Ident string   `@Ident`
	Path  []string `( "." @Ident )*`
}

func main() {
	parser := participle.MustBuild[Scope]()
	t, err := parser.ParseString("", source)
	if err != nil {
		fmt.Printf("Error: %v", err)
		return
	}
	repr.Println(t)
}

Parser fails on the last entry:

Error: 7:6: unexpected token ";" (expected "=")

As far as I understand, in Entry it picks Assignment path instead of Expression because it can't know how long will be the repeating Path value.

Not sure if it's the same issue as #216

Could you please suggest any workarounds to make this work? I'm still struggling with advanced regex use cases.

Also, unrelated: when I try to use positive lookahead (?="x"), I always get an error saying that branch matched the symbol in question, but it doesn't progress the lexer. Negative lookahead (?!"x") works as expected.

As usual, I came to the solution right after asking the question (I've been stuck on this issue for the 3rd day already).

Using participle.UseLookahead(n) option solves the issue. I've just used it incorrectly (called right away instead of passing to participle.MustBuild). Silly mistake.