alecthomas / participle

A parser library for Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

tutorial: ini file parser doesn't parse the example with integers (age = 21)

marco-m opened this issue · comments

Hello,
thanks for participle, I am trying it out and I like it! :-)

While following the tutorial, I stumbled upon the following. The code for the structs is copied and pasted from the tutorial:

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

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

type Value struct {
	String *string  `  @String`
	Number *float64 `| @Float`
}

func TestTutorial(t *testing.T) {
	input := `age = 21`
	parser, err := participle.Build(&INI{})
	assert.NoError(t, err)
	have := &INI{}

	err = parser.ParseString("", input, have)

	assert.NoError(t, err)
	assert.Equal(t, "age", have.Properties[0].Key)
	assert.Equal(t, 21, *have.Properties[0].Value.Number)
}

Running the test gives the error:

=== RUN   TestTutorial
    foo_test.go:32: Did not expect an error but got:
        1:7: unexpected token "21" (expected Value)

After a bit of head scratching I replaced

input := `age = 21`

with

input := `age = 21.0`

and the test passed.

I then looked at _examples/ini/main.go and I saw that it uses a custom lexer, where Float is defined as

{`Float`, `\d+(?:\.\d+)?`},

So I think it is because the example in the tutorial uses the default Go lexer, which wants a dot to recognize a float.

I see two possible fixes for the tutorial:

  1. Replace float64 with int in the Value struct:
type Value struct {
	String *string `  @String`
	Number *int    `| @Int`
}
  1. Add a dot to the sample input:
age = 21.0
name = "Bob Smith"

[address]
city = "Beverly Hills"
postal_code = 90210
  1. Actually I just found _examples/simpleexpr and this seems to be the best fix:
type Value struct {
	String *string  `  @String`
	Number *float64 `| @Float | @Int`
}

Am I going in the right direction?

Yes! Your last one is correct, though I would change it to this to make it extra clear:

type Value struct {
	String *string  `  @String`
	Number *float64 `| (@Float | @Int)`
}

Mind sending a PR?