コード例 #1
0
ファイル: parser.go プロジェクト: 8l/go-learn
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
}
コード例 #2
0
ファイル: parser.go プロジェクト: 8l/go-learn
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
}
コード例 #3
0
ファイル: parser.go プロジェクト: 8l/go-learn
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
}