/
CDC-1.2b/
CDC-1.2b/src/
parent $misc
object $lock_parser

var $root child_index 0
var $root owners [$lock_parser]
var $root fertile 0
var $root inited 1
var $root owned [$lock_parser]
var $root manager $lock_parser
var $root writable [$lock_parser]
var $root readable ['parameters, 'methods, 'code]
var $root dbref 'lock_parser

method parse
    arg s, env;
    var stack, lock, n, m, obj, len;
    
    stack = [];
    while (1) {
        // Look for valid prefixes.
        while (1) {
            while (s && ((s[1]) == " "))
                s = substr(s, 2);
            if (!s)
                throw(~parse, "String ends unexpectedly.");
            if ((s[1]) == "(") {
                stack = stack + ['open];
                s = substr(s, 2);
            } else if ((s[1]) == "!") {
                stack = stack + ['not];
                s = substr(s, 2);
            } else {
                break;
            }
        }
    
        // Look for an object obj_name.
        for n in [1 .. strlen(s)] {
            if ((s[n]) in ")&|") {
                n = n - 1;
                break;
            }
        }
        m = n;
        while (m && ((s[m]) == " "))
            m = m - 1;
        if (!m)
            throw(~parse, "Null object obj_name.");
        obj = (> env.match_environment(substr(s, 1, m)) <);
        lock = $object_lock_class.new(obj);
        stack = stack + [lock];
        s = substr(s, n + 1);
    
        // Loop until no more reduction to be done.
        while (1) {
            // Process negations, ands, ors.
            while (1) {
                len = listlen(stack);
                if (len < 2)
                    break;
                if ((stack[len - 1]) == 'not) {
                    lock = $not_lock_class.new(stack[len]);
                    stack = sublist(stack, 1, len - 2) + [lock];
                } else if ((stack[len - 1]) == 'and) {
                    lock = $and_lock_class.new(stack[len - 2], stack[len]);
                    stack = sublist(stack, 1, len - 3) + [lock];
                } else if ((stack[len - 1]) == 'or) {
                    lock = $or_lock_class.new(stack[len - 2], stack[len]);
                    stack = sublist(stack, 1, len - 3) + [lock];
                } else {
                    break;
                }
            }
    
            // Close parens, if necessary; otherwise stop.
            if ((!s) || ((s[1]) != ")"))
                break;
            while (s && ((s[1]) == ")")) {
                len = listlen(stack);
                if ((len < 2) || ((stack[len - 1]) != 'open))
                    throw(~parse, "Misplaced right parenthesis.");
                stack = sublist(stack, 1, len - 2) + [stack[len]];
                s = substr(s, 2);
                while (s && ((s[1]) == " "))
                    s = substr(s, 2);
            }
        }
    
        // Are we done?
        if (!s) {
            if (listlen(stack) > 1)
                throw(~parse, "Unmatched left parentheses.");
            return stack[1];
        }
    
        // No, we're at a conjunction.
        if ((s[1]) == "&") {
            stack = stack + ['and];
            s = substr(s, 2);
        } else if ((s[1]) == "|") {
            stack = stack + ['or];
            s = substr(s, 2);
        } else {
            throw(~parse, "Illegal character following right parenthesis.");
        }
    }
.