alecthomas / participle

A parser library for Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Zero or more match error question

yonderblue opened this issue · comments

Here is a small example that fails. However changing the phrase grammar to have Negate bool `@Negate?` will succeed. In the zero or more * case, I guess the zero is causing the *phrase pointer being filled. But ? is also allowing zero, what is the difference? If I used participle.UseLookahead(2) it works, however how would you know the correct count to avoid side effects of the highest?

package main

import (
	"fmt"

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

func main() {
	s := `--hello`

	dumpLex(lexDef, s)

	p, err := parser.ParseString("", s)
	fmt.Printf("PARSE %v\n%+v\n", err, p)
}

type parse struct {
	Texts []text `@@*`
}

type text struct {
	Phrase *phrase `( @@`
	Plain  plain   `| @@ )`
}

type phrase struct {
	Negate bool   `@Negate*`
	Text   string `@Phrase`
}

type plain struct {
	Negate bool   `@Negate*`
	Text   string `@Plain`
}

var (
	lexDef = lexer.MustSimple([]lexer.SimpleRule{
		{"Phrase", `"[^"]*"?`},
		{"Negate", `-`},
		{"Plain", `[^"\s]+`},
		{"whitespace", `\s+`},
	})
	parser = participle.MustBuild[parse](participle.Lexer(lexDef))
)

func dumpLex(def *lexer.StatefulDefinition, s string) {
	fmt.Println("STRING", s)
	fmt.Println("SYMBOLS", def.Symbols())

	lex, err := def.LexString("", s)
	if err != nil {
		panic(err)
	}

	tokens, err := lexer.ConsumeAll(lex)
	if err != nil {
		panic(err)
	}

	for _, t := range tokens {
		fmt.Printf("TOKEN type=%v value=%v\n", t.Type, t.Value)
	}
}