func (p *parser) parseExpression() expr { var list vector.Vector list.Init(0) for { x := p.parseSequence() if x != nil { list.Push(x) } if p.tok != token.OR { break } p.next() } // no need for an alternatives if list.Len() < 2 switch list.Len() { case 0: return nil case 1: return list.At(0).(expr) } // convert list into a alternatives alt := make(alternatives, list.Len()) for i := 0; i < list.Len(); i++ { alt[i] = list.At(i).(expr) } return alt }
func (p *parser) parseLiteral() literal { s := strings.Bytes(p.parseString()) // A string literal may contain %-format specifiers. To simplify // and speed up printing of the literal, split it into segments // that start with "%" possibly followed by a last segment that // starts with some other character. var list vector.Vector list.Init(0) i0 := 0 for i := 0; i < len(s); i++ { if s[i] == '%' && i+1 < len(s) { // the next segment starts with a % format if i0 < i { // the current segment is not empty, split it off list.Push(s[i0:i]) i0 = i } i++ // skip %; let loop skip over char after % } } // the final segment may start with any character // (it is empty iff the string is empty) list.Push(s[i0:len(s)]) // convert list into a literal lit := make(literal, list.Len()) for i := 0; i < list.Len(); i++ { lit[i] = list.At(i).([]byte) } return lit }
func (p *parser) parseSequence() expr { var list vector.Vector list.Init(0) for x := p.parseOperand(); x != nil; x = p.parseOperand() { list.Push(x) } // no need for a sequence if list.Len() < 2 switch list.Len() { case 0: return nil case 1: return list.At(0).(expr) } // convert list into a sequence seq := make(sequence, list.Len()) for i := 0; i < list.Len(); i++ { seq[i] = list.At(i).(expr) } return seq }