{ package parser type IdFilter struct { Ids []int } } Filter <- first:(IdRange / SingleId) rest:(',' (IdRange / SingleId))* { var ids []int first := toIntSlice(first) ids = append(ids, first...) if rest != nil { for _, r := range rest.([]interface{}) { restIds := toIntSlice(r.([]interface{})[1]) ids = append(ids, restIds...) } } return &IdFilter{Ids: ids}, nil } IdRange <- start:Integer '-' end:Integer { start := start.(int) end := end.(int) var ids []int for i := start; i <= end; i++ { ids = append(ids, i) } return ids, nil } SingleId <- id:Integer { return []int{id.(int)}, nil } Integer <- [0-9]+ { val := string(c.text) n, _ := strconv.Atoi(val) return n, nil } _ <- [ \t]* { func toIntSlice(v interface{}) []int { if slice, ok := v.([]int); ok { return slice } return nil } }