Пример #1
0
func (l *lex) parseAnds() (*Pred, error) {
	if l.debug {
		defer dbg.Trace(dbg.Call("ands"))
	}
	args := []*Pred{}
	a1, err := l.parsePrim()
	if err != nil {
		return nil, err
	}
	args = append(args, a1)
	for {
		op, _, err := l.peek()
		if err!=nil || op!=tAnd {
			if err==io.EOF || op==tRpar || op==tOr {
				err = nil
			}
			if len(args) == 1 {
				return args[0], err
			}
			return &Pred{op: oAnd, args: args}, err
		}
		l.scan()
		a, err := l.parsePrim()
		if err != nil {
			return nil, err
		}
		args = append(args, a)
	}
}
Пример #2
0
/*
	prim ::= prune | t | true | f | false | name op name | unop prim | maxmin name | n | ( ors )
	but handle ~ str as meaning "name~str"
*/
func (l *lex) parsePrim() (*Pred, error) {
	if l.debug {
		defer dbg.Trace(dbg.Call("prim"))
	}
	t, _, err := l.peek()
	if err != nil {
		return nil, err
	}
	switch {
	case t == tPrune, t == tTrue, t == tFalse:
		l.scan()
		return &Pred{op: op(t)}, nil
	case t==tMatch || t==tEqs || t==tRexp:
		// unary usage assumes path op ...
		l.scan()
		t2, v2, err := l.scan()
		if err!=nil || t2.class()!=cName {
			return nil, errors.New("name expected")
		}
		return &Pred{op: op(t), name: "path", value: v2}, nil
	case t == tName:
		_, v1, _ := l.scan()
		if v1 == "d" || v1 == "-" || v1 == "c" {
			// d/-/c -> type = d/-/c
			return &Pred{op: oEqs, name: "type", value: v1}, nil
		}
		_, err := strconv.Atoi(v1)
		if err == nil {
			// n -> depth<=n
			return &Pred{op: oLe, name: "depth", value: v1}, nil
		}
		x, _, err := l.scan()
		if err!=nil || x.class()!=cOp {
			return nil, errors.New("op expected")
		}
		t2, v2, err := l.scan()
		if err!=nil || t2.class()!=cName {
			return nil, errors.New("name expected")
		}
		return &Pred{op: op(x), name: v1, value: v2}, nil
	case t.class() == cUn:
		l.scan()
		arg, err := l.parsePrim()
		if err != nil {
			return nil, err
		}
		return &Pred{op: op(t), args: []*Pred{arg}}, nil
	case t == tLpar:
		l.scan()
		arg, err := l.parseOrs()
		if err != nil {
			return nil, err
		}
		r, _, err := l.scan()
		if err!=nil || r!=tRpar {
			return nil, errors.New("')' expected")
		}
		return arg, nil
	}
	return nil, errors.New("not a primary expression")
}