103 lines
1.6 KiB
Go
103 lines
1.6 KiB
Go
|
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
|
||
|
|
||
|
}
|