func (p *parser) op(op Op) *Regexp {
	re := p.newRegexp(op)
	re.Flags = p.flags
	return p.push(re)
}
op pushes a regexp with the given op onto the stack
and returns that regexp.
package syntax
import (
	"sort"
	"strings"
	"unicode"
	"unicode/utf8"
)
type Error struct {
	Code ErrorCode
	Expr string
}
func (e *Error) Error() string {
	return "error parsing regexp: " + e.Code.String() + ": `" + e.Expr + "`"
}
type ErrorCode string
const (
	ErrInternalError ErrorCode = "regexp/syntax: internal error"
	ErrInvalidCharClass      ErrorCode = "invalid character class"
	ErrInvalidCharRange      ErrorCode = "invalid character class range"
	ErrInvalidEscape         ErrorCode = "invalid escape sequence"
	ErrInvalidNamedCapture   ErrorCode = "invalid named capture"
	ErrInvalidPerlOp         ErrorCode = "invalid or unsupported Perl syntax"
	ErrInvalidRepeatOp       ErrorCode = "invalid nested repetition operator"
	ErrInvalidRepeatSize     ErrorCode = "invalid repeat count"
	ErrInvalidUTF8           ErrorCode = "invalid UTF-8"
	ErrMissingBracket        ErrorCode = "missing closing ]"
	ErrMissingParen          ErrorCode = "missing closing )"
	ErrMissingRepeatArgument ErrorCode = "missing argument to repetition operator"
	ErrTrailingBackslash     ErrorCode = "trailing backslash at end of expression"
	ErrUnexpectedParen       ErrorCode = "unexpected )"
)
func (e ErrorCode) String() string {
	return string(e)
}
type Flags uint16
const (
	FoldCase      Flags = 1 << iota  
	Literal                          
	ClassNL                          
	DotNL                            
	OneLine                          
	NonGreedy                        
	PerlX                            
	UnicodeGroups                    
	WasDollar                        
	Simple                           
	MatchNL = ClassNL | DotNL
	Perl        = ClassNL | OneLine | PerlX | UnicodeGroups  
	POSIX Flags = 0                                          
)
const (
	opLeftParen = opPseudo + iota
	opVerticalBar
)
type parser struct {
	flags       Flags      
	stack       []*Regexp  
	free        *Regexp
	numCap      int  
	wholeRegexp string
	tmpClass    []rune  
}
func (p *parser) newRegexp(op Op) *Regexp {
	re := p.free
	if re != nil {
		p.free = re.Sub0[0]
		*re = Regexp{}
	} else {
		re = new(Regexp)
	}
	re.Op = op
	return re
}
func (p *parser) reuse(re *Regexp) {
	re.Sub0[0] = p.free
	p.free = re
}
func (p *parser) push(re *Regexp) *Regexp {
	if re.Op == OpCharClass && len(re.Rune) == 2 && re.Rune[0] == re.Rune[1] {
		if p.maybeConcat(re.Rune[0], p.flags&^FoldCase) {
			return nil
		}
		re.Op = OpLiteral
		re.Rune = re.Rune[:1]
		re.Flags = p.flags &^ FoldCase
	} else if re.Op == OpCharClass && len(re.Rune) == 4 &&
		re.Rune[0] == re.Rune[1] && re.Rune[2] == re.Rune[3] &&
		unicode.SimpleFold(re.Rune[0]) == re.Rune[2] &&
		unicode.SimpleFold(re.Rune[2]) == re.Rune[0] ||
		re.Op == OpCharClass && len(re.Rune) == 2 &&
			re.Rune[0]+1 == re.Rune[1] &&
			unicode.SimpleFold(re.Rune[0]) == re.Rune[1] &&
			unicode.SimpleFold(re.Rune[1]) == re.Rune[0] {
		if p.maybeConcat(re.Rune[0], p.flags|FoldCase) {
			return nil
		}
		re.Op = OpLiteral
		re.Rune = re.Rune[:1]
		re.Flags = p.flags | FoldCase
	} else {
		p.maybeConcat(-1, 0)
	}
	p.stack = append(p.stack, re)
	return re
}
func (p *parser) maybeConcat(r rune, flags Flags) bool {
	n := len(p.stack)
	if n < 2 {
		return false
	}
	re1 := p.stack[n-1]
	re2 := p.stack[n-2]
	if re1.Op != OpLiteral || re2.Op != OpLiteral || re1.Flags&FoldCase != re2.Flags&FoldCase {
		return false
	}
	re2.Rune = append(re2.Rune, re1.Rune...)
	if r >= 0 {
		re1.Rune = re1.Rune0[:1]
		re1.Rune[0] = r
		re1.Flags = flags
		return true
	}
	p.stack = p.stack[:n-1]
	p.reuse(re1)
	return false  
}
func (p *parser) newLiteral(r rune, flags Flags) *Regexp {
	re := p.newRegexp(OpLiteral)
	re.Flags = flags
	if flags&FoldCase != 0 {
		r = minFoldRune(r)
	}
	re.Rune0[0] = r
	re.Rune = re.Rune0[:1]
	return re
}
func minFoldRune(r rune) rune {
	if r < minFold || r > maxFold {
		return r
	}
	min := r
	r0 := r
	for r = unicode.SimpleFold(r); r != r0; r = unicode.SimpleFold(r) {
		if min > r {
			min = r
		}
	}
	return min
}
func (p *parser) literal(r rune) {
	p.push(p.newLiteral(r, p.flags))
}