Пример #1
0
func nullables(refs map[string]*ast.Pattern, patterns []*ast.Pattern) bitset {
	nulls := newBitSet(len(patterns))
	for i, p := range patterns {
		nulls.set(i, interp.Nullable(refs, p))
	}
	return nulls
}
Пример #2
0
func (this *Mem) calcAccepts(upto int) {
	for i := len(this.Accept); i <= upto; i++ {
		patterns := this.patterns[i]
		if len(patterns) != 1 {
			this.Accept = append(this.Accept, false)
		} else {
			this.Accept = append(this.Accept, interp.Nullable(this.refs, patterns[0]))
		}
	}
}
Пример #3
0
func derivReturn(refs map[string]*ast.Pattern, p *ast.Pattern, nullable []bool) (*ast.Pattern, []bool) {
	typ := p.GetValue()
	switch v := typ.(type) {
	case *ast.Empty:
		return ast.NewNot(ast.NewZAny()), nullable
	case *ast.ZAny:
		return ast.NewZAny(), nullable
	case *ast.TreeNode:
		if nullable[0] {
			return ast.NewEmpty(), nullable[1:]
		}
		return ast.NewNot(ast.NewZAny()), nullable[1:]
	case *ast.LeafNode:
		if nullable[0] {
			return ast.NewEmpty(), nullable[1:]
		}
		return ast.NewNot(ast.NewZAny()), nullable[1:]
	case *ast.Concat:
		l, leftRest := derivReturn(refs, v.GetLeftPattern(), nullable)
		leftConcat := ast.NewConcat(l, v.GetRightPattern())
		if !interp.Nullable(refs, v.GetLeftPattern()) {
			return leftConcat, leftRest
		}
		r, rightRest := derivReturn(refs, v.GetRightPattern(), leftRest)
		return ast.NewOr(leftConcat, r), rightRest
	case *ast.Or:
		l, leftRest := derivReturn(refs, v.GetLeftPattern(), nullable)
		r, rightRest := derivReturn(refs, v.GetRightPattern(), leftRest)
		return ast.NewOr(l, r), rightRest
	case *ast.And:
		l, leftRest := derivReturn(refs, v.GetLeftPattern(), nullable)
		r, rightRest := derivReturn(refs, v.GetRightPattern(), leftRest)
		return ast.NewAnd(l, r), rightRest
	case *ast.Interleave:
		l, leftRest := derivReturn(refs, v.GetLeftPattern(), nullable)
		r, rightRest := derivReturn(refs, v.GetRightPattern(), leftRest)
		return ast.NewOr(ast.NewInterleave(l, v.GetRightPattern()), ast.NewInterleave(r, v.GetLeftPattern())), rightRest
	case *ast.ZeroOrMore:
		c, rest := derivReturn(refs, v.GetPattern(), nullable)
		return ast.NewConcat(c, p), rest
	case *ast.Reference:
		return derivReturn(refs, refs[v.GetName()], nullable)
	case *ast.Not:
		c, rest := derivReturn(refs, v.GetPattern(), nullable)
		return ast.NewNot(c), rest
	case *ast.Contains:
		return derivReturn(refs, ast.NewConcat(ast.NewZAny(), ast.NewConcat(v.GetPattern(), ast.NewZAny())), nullable)
	case *ast.Optional:
		return derivReturn(refs, ast.NewOr(v.GetPattern(), ast.NewEmpty()), nullable)
	}
	panic(fmt.Sprintf("unknown pattern typ %T", typ))
}
Пример #4
0
func derivCall(refs map[string]*ast.Pattern, getFunc func(*ast.Expr) funcs.Bool, p *ast.Pattern) []*ifExpr {
	typ := p.GetValue()
	switch v := typ.(type) {
	case *ast.Empty:
		return []*ifExpr{}
	case *ast.ZAny:
		return []*ifExpr{}
	case *ast.TreeNode:
		b := nameexpr.NameToFunc(v.GetName())
		return []*ifExpr{{b, v.GetPattern(), ast.NewNot(ast.NewZAny())}}
	case *ast.LeafNode:
		b := getFunc(v.GetExpr())
		return []*ifExpr{{b, ast.NewEmpty(), ast.NewNot(ast.NewZAny())}}
	case *ast.Concat:
		l := derivCall(refs, getFunc, v.GetLeftPattern())
		if !interp.Nullable(refs, v.GetLeftPattern()) {
			return l
		}
		r := derivCall(refs, getFunc, v.GetRightPattern())
		return append(l, r...)
	case *ast.Or:
		return derivCall2(refs, getFunc, v.GetLeftPattern(), v.GetRightPattern())
	case *ast.And:
		return derivCall2(refs, getFunc, v.GetLeftPattern(), v.GetRightPattern())
	case *ast.Interleave:
		return derivCall2(refs, getFunc, v.GetLeftPattern(), v.GetRightPattern())
	case *ast.ZeroOrMore:
		return derivCall(refs, getFunc, v.GetPattern())
	case *ast.Reference:
		return derivCall(refs, getFunc, refs[v.GetName()])
	case *ast.Not:
		return derivCall(refs, getFunc, v.GetPattern())
	case *ast.Contains:
		return derivCall(refs, getFunc, ast.NewConcat(ast.NewZAny(), ast.NewConcat(v.GetPattern(), ast.NewZAny())))
	case *ast.Optional:
		return derivCall(refs, getFunc, ast.NewOr(v.GetPattern(), ast.NewEmpty()))
	}
	panic(fmt.Sprintf("unknown pattern typ %T", typ))
}