{ package parser type Attribute struct{ Type string Value string } type AddCommand struct { Description string Attributes []Attribute } func MakeAdd(description interface{}, attributes interface{}) (*AddCommand, error) { attribs, _ := attributes.([]Attribute) return &AddCommand{Description: description.(string), Attributes: attribs}, nil } func MakeAttributes(attributes interface{}) ([]Attribute, error) { ats := attributes.([]interface{}) attribs := make([]Attribute, 0) for _, p := range ats { pa := p.([]interface{}) px := pa[1:] for _, pi := range px { ps := pi.(*Attribute) attribs = append(attribs, *ps) } } return attribs, nil } } Add <- desc:Description attributes:Attributes? { return MakeAdd(desc, attributes) } Description <- (!Attribute .)+ { return string(c.text), nil } Attributes <- attributes:(_ Attribute)* { return MakeAttributes(attributes) } Attribute <- Project / Priority / Tag Project <- ("pro:" / "project:") value:Word { return &Attribute{Type:"project", Value:value.(string)}, nil } Priority <- "priority:" value:[HML] { return &Attribute{Type:"priority", Value:value.(string)}, nil } Tag <- "+" value:Word { return &Attribute{Type:"tag", Value:value.(string)}, nil } Word <- [a-zA-Z0-9_-]+ { return string(c.text), nil } _ <- [ \t]* EOF = !.