package parser import ( "fmt" ) // buildScheme builds a 'basic' scheme // from a pattern string func buildScheme(ss []string) (Scheme, error) { /* (1) Build scheme */ sch := make(Scheme, 0, maxMatch) for _, s := range ss { /* (2) ignore empty */ if len(s) == 0 { continue } m := new(matcher) switch s { /* (3) Card: 0, N */ case "**": m.req = false m.mul = true sch = append(sch, m) /* (4) Card: 1, N */ case "..": m.req = true m.mul = true sch = append(sch, m) /* (5) Card: 0, 1 */ case "*": m.req = false m.mul = false sch = append(sch, m) /* (6) Card: 1 */ case ".": m.req = true m.mul = false sch = append(sch, m) /* (7) Card: 1, literal string */ default: m.req = true m.mul = false m.pat = fmt.Sprintf("/%s", s) sch = append(sch, m) } } return sch, nil } // optimise optimised the scheme for further parsing func (s Scheme) optimise() (Scheme, error) { /* (1) Nothing to do if only 1 element */ if len(s) <= 1 { return s, nil } /* (2) Init reshifted scheme */ rshift := make(Scheme, 0, maxMatch) rshift = append(rshift, s[0]) /* (2) Iterate over matchers */ for p, i, l := 0, 1, len(s) ; i < l ; i++ { pre, cur := s[p], s[i] /* Merge: 2 following literals */ if len(pre.pat) > 0 && len(cur.pat) > 0 { // merge strings into previous pre.pat = fmt.Sprintf("%s%s", pre.pat, cur.pat) // delete current s[i] = nil } // increment previous (only if current is not nul) if s[i] != nil { rshift = append(rshift, s[i]) p = i } } return rshift, nil }