比较变更表达式与目标表达式之间的关系，用于视图更新判断
视图更新需要根据其关系，做出相应的更新行为

0: 完全没关系
1: 变更表达式是目标表达式的母项(如a与a.b) 或 表示需要完全变化
2: 变更表达式是目标表达式相等
>2: 变更表达式是目标表达式的子项，如a.b.c与a.b

@param {Object} changeExpr 变更表达式
@param {Object} expr 要比较的目标表达式
@param {Data} data 表达式所属数据环境
@return {number}
351301
function changeExprCompare(changeExpr, expr, data) {
    var result = 0;
    if (!expr.changeCache) {
        expr.changeCache = {};
    }

    if (changeExpr.raw && !expr.dynamic) {
        if (expr.changeCache[changeExpr.raw] != null) {
            return expr.changeCache[changeExpr.raw];
        }
    }

    switch (expr.type) {
        case ExprType.ACCESSOR:
            var paths = expr.paths;
            var pathsLen = paths.length;
            var changePaths = changeExpr.paths;
            var changeLen = changePaths.length;

            result = 1;
            for (var i = 0; i < pathsLen; i++) {
                var pathExpr = paths[i];
                var pathExprValue = pathExpr.value;

                if (pathExprValue == null && changeExprCompare(changeExpr, pathExpr, data)) {
                    result = 1;
                    break;
                }

                if (result && i < changeLen
                    /* eslint-disable eqeqeq */
                    && (pathExprValue || evalExpr(pathExpr, data)) != changePaths[i].value
                    /* eslint-enable eqeqeq */
                ) {
                    result = 0;
                }
            }

            if (result) {
                result = Math.max(1, changeLen - pathsLen + 2);
            }
            break;

        case ExprType.UNARY:
            result = changeExprCompare(changeExpr, expr.expr, data) ? 1 : 0;
            break;

        case ExprType.TEXT:
        case ExprType.BINARY:
        case ExprType.TERTIARY:
            result = changeExprCompareExprs(changeExpr, expr.segs, data);
            break;

        case ExprType.ARRAY:
        case ExprType.OBJECT:
            for (var i = 0; i < expr.items.length; i++) {
                if (changeExprCompare(changeExpr, expr.items[i].expr, data)) {
                    result = 1;
                    break;
                }
            }

            break;

        case ExprType.INTERP:
            if (changeExprCompare(changeExpr, expr.expr, data)) {
                result = 1;
            }
            else {
                for (var i = 0; i < expr.filters.length; i++) {
                    if (changeExprCompareExprs(changeExpr, expr.filters[i].args, data)) {
                        result = 1;
                        break;
                    }
                }
            }

            break;

        case ExprType.CALL:
            if (changeExprCompareExprs(changeExpr, expr.name.paths, data)
                || changeExprCompareExprs(changeExpr, expr.args, data)
            ) {
                result = 1;
            }
            break;
    }

    if (changeExpr.raw && !expr.dynamic) {
        expr.changeCache[changeExpr.raw] = result;
    }

    return result;
}
866021
function(expr) {
    var inputStream = this.inputStream;
    var origNumBindings = this._bindings.length;

    var origRecordedFailures;
    if (this.recordedFailures) {
      origRecordedFailures = this.recordedFailures;
      this.recordedFailures = Object.create(null);
    }

    var origPos = inputStream.pos;
    var memoPos = this.maybeSkipSpacesBefore(expr);

    var origTrace;
    if (this.trace) {
      origTrace = this.trace;
      this.trace = [];
    }

    // Do the actual evaluation.
    var ans = expr.eval(this);

    if (this.trace) {
      var bindings = this._bindings.slice(origNumBindings);
      var traceEntry = this.getTraceEntry(memoPos, expr, ans, bindings);
      traceEntry.isImplicitSpaces = expr === applySpaces;
      traceEntry.isRootNode = expr === this.startExpr;
      origTrace.push(traceEntry);
      this.trace = origTrace;
    }

    if (ans) {
      if (this.recordedFailures && inputStream.pos === this.positionToRecordFailures) {
        var self = this;
        Object.keys(this.recordedFailures).forEach(function(key) {
          self.recordedFailures[key].makeFluffy();
        });
      }
    } else {
      // Reset the position and the bindings.
      inputStream.pos = origPos;
      this.truncateBindings(origNumBindings);
    }

    if (this.recordedFailures) {
      this.recordFailures(origRecordedFailures, false);
    }

    return ans;
  }
1176296
public boolean mergeEffects(String expr, Effect[] effects, float[] results) {
        boolean result;
        if (expr.equals("some(where (p_eft == allow))")) {
            result = false;
            for (Effect eft : effects) {
                if (eft == Effect.Allow) {
                    result = true;
                    break;
                }
            }
        } else if (expr.equals("!some(where (p_eft == deny))")) {
            result = true;
            for (Effect eft : effects) {
                if (eft == Effect.Deny) {
                    result = false;
                    break;
                }
            }
        } else if (expr.equals("some(where (p_eft == allow)) && !some(where (p_eft == deny))")) {
            result = false;
            for (Effect eft : effects) {
                if (eft == Effect.Allow) {
                    result = true;
                } else if (eft == Effect.Deny) {
                    result = false;
                    break;
                }
            }
        } else if (expr.equals("priority(p_eft) || deny")) {
            result = false;
            for (Effect eft : effects) {
                if (eft != Effect.Indeterminate) {
                    if (eft == Effect.Allow) {
                        result = true;
                    } else {
                        result = false;
                    }
                    break;
                }
            }
        } else {
            throw new Error("unsupported effect");
        }

        return result;
    }
266369
function updateDataIs(expr, parent, tagName) {
  var conf, isVirtual, head, ref;

  if (expr.tag && expr.tagName === tagName) {
    expr.tag.update();
    return
  }

  isVirtual = expr.dom.tagName === 'VIRTUAL';
  // sync _parent to accommodate changing tagnames
  if (expr.tag) {
    // need placeholder before unmount
    if(isVirtual) {
      head = expr.tag.__.head;
      ref = createDOMPlaceholder();
      head.parentNode.insertBefore(ref, head);
    }

    expr.tag.unmount(true);
  }

  if (!isString(tagName)) { return }

  expr.impl = __TAG_IMPL[tagName];
  conf = {root: expr.dom, parent: parent, hasImpl: true, tagName: tagName};
  expr.tag = initChildTag(expr.impl, conf, expr.dom.innerHTML, parent);
  each(expr.attrs, function (a) { return setAttr(expr.tag.root, a.name, a.value); });
  expr.tagName = tagName;
  expr.tag.mount();
  if (isVirtual)
    { makeReplaceVirtual(expr.tag, ref || expr.tag.root); } // root exist first time, after use placeholder

  // parent is the placeholder tag, not the dynamic tag so clean up
  parent.__.onUnmount = function() {
    var delName = expr.tag.opts.dataIs,
      tags = expr.tag.parent.tags,
      _tags = expr.tag.__.parent.tags;
    arrayishRemove(tags, delName, expr.tag);
    arrayishRemove(_tags, delName, expr.tag);
    expr.tag.unmount();
  };
}
744072
function getExpression(expr){
//console.debug(MODULE, expr)
	let val = (expr + '').trim();
	if ( options.ExpressionUnescapeStart.length > options.ExpressionStart.length ) {
		// 长的先匹配
		if ( val.startsWith(options.ExpressionUnescapeStart) && val.endsWith(options.ExpressionUnescapeEnd) ) {
			return '(' + val.substring(options.ExpressionUnescapeStart.length, val.length - options.ExpressionUnescapeEnd.length) + ')';
		}else if ( val.startsWith(options.ExpressionStart) && val.endsWith(options.ExpressionEnd) ) {
			return options.NameFnEscapeHtml + '(' + val.substring(options.ExpressionStart.length, val.length - options.ExpressionEnd.length) + ')';
		}
	}else{
		if ( val.startsWith(options.ExpressionStart) && val.endsWith(options.ExpressionEnd) ) {
			return options.NameFnEscapeHtml + '(' + val.substring(options.ExpressionStart.length, val.length - options.ExpressionEnd.length) + ')';
		}else if ( val.startsWith(options.ExpressionUnescapeStart) && val.endsWith(options.ExpressionUnescapeEnd) ) {
			return '(' + val.substring(options.ExpressionUnescapeStart.length, val.length - options.ExpressionUnescapeEnd.length) + ')';
		}
	}
	return '"' + lineString(val) + '"';
}
150709
function transExpr(expContent, toFunc) {
  var ret
  expContent = expContent.trim().replace(/\"/g, '\'')
  if (!textParser.isExpr(expContent)) {
    ret = expContent
  }
  else {
    ret = []
    var tokens = textParser.parseText(expContent)
    var isSingle = tokens.length === 1
    tokens.forEach(function (token) {
      if (token.tag) {
        var res = expParser.parseExpression(token.value)
        if (!isSingle) {
          res = '(' + res + ')'
        }
        ret.push(res)
      }
      else {
        ret.push('\'' + token.value + '\'')
      }
    })
    ret = ret.join(' + ')
    if (toFunc !== false) {
      ret = eval('(function () {return ' + ret + '})')
    }
  }
  return ret
}
250718
private Expression expoOp(Data data) throws TemplateException {
	Expression expr = unaryOp(data);

	// Modulus Operation
	while (data.srcCode.forwardIfCurrent('^') || data.srcCode.forwardIfCurrentAndNoWordAfter("exp")) {
	    comments(data);
	    expr = data.factory.opDouble(expr, unaryOp(data), Factory.OP_DBL_EXP);
	}
	return expr;
    }
15906
def p_expr1(p):
    
    p[0] = node.expr(op=p[1], args=node.expr_list([p[2]]))
259796
def convert(self, expr):
        
        if expr is True or expr == None or expr is False:
            return expr
        elif is_number(expr):
            return expr
        elif expr == ".":
            return "."
        elif is_variable_name(expr):
            return coalesce(self.dimensions[expr], expr)
        elif is_text(expr):
            Log.error("{{name|quote}} is not a valid variable name", name=expr)
        elif isinstance(expr, Date):
            return expr
        elif is_op(expr, QueryOp):
            return self._convert_query(expr)
        elif is_data(expr):
            if expr["from"]:
                return self._convert_query(expr)
            elif len(expr) >= 2:
                #ASSUME WE HAVE A NAMED STRUCTURE, NOT AN EXPRESSION
                return wrap({name: self.convert(value) for name, value in expr.leaves()})
            else:
                # ASSUME SINGLE-CLAUSE EXPRESSION
                k, v = expr.items()[0]
                return converter_map.get(k, self._convert_bop)(self, k, v)
        elif is_many(expr):
            return wrap([self.convert(value) for value in expr])
        else:
            return expr
1337986
function refreshData(data) {
                    var k = 0;
                    var tmp = 0;
                    for (;
                      (k | 0) < 227; k = (k + 1) | 0) {
                      tmp = (data[k] & 0x80000000) | (data[(k + 1) | 0] & 0x7fffffff);
                      data[k] = data[(k + 397) | 0] ^ (tmp >>> 1) ^ ((tmp & 0x1) ? 0x9908b0df : 0);
                    }

                    for (;
                      (k | 0) < 623; k = (k + 1) | 0) {
                      tmp = (data[k] & 0x80000000) | (data[(k + 1) | 0] & 0x7fffffff);
                      data[k] = data[(k - 227) | 0] ^ (tmp >>> 1) ^ ((tmp & 0x1) ? 0x9908b0df : 0);
                    }

                    tmp = (data[623] & 0x80000000) | (data[0] & 0x7fffffff);
                    data[623] = data[396] ^ (tmp >>> 1) ^ ((tmp & 0x1) ? 0x9908b0df : 0);
                  }
192385
function updateExpression(expr) {
  if (this.root && getAttr(this.root,'virtualized')) { return }

  var dom = expr.dom,
    // remove the riot- prefix
    attrName = normalizeAttrName(expr.attr),
    isToggle = contains([SHOW_DIRECTIVE, HIDE_DIRECTIVE], attrName),
    isVirtual = expr.root && expr.root.tagName === 'VIRTUAL',
    parent = dom && (expr.parent || dom.parentNode),
    // detect the style attributes
    isStyleAttr = attrName === 'style',
    isClassAttr = attrName === 'class',
    hasValue,
    isObj,
    value;

  // if it's a tag we could totally skip the rest
  if (expr._riot_id) {
    if (expr.isMounted) {
      expr.update();
    // if it hasn't been mounted yet, do that now.
    } else {
      expr.mount();
      if (isVirtual) {
        makeReplaceVirtual(expr, expr.root);
      }
    }
    return
  }
  // if this expression has the update method it means it can handle the DOM changes by itself
  if (expr.update) { return expr.update() }

  // ...it seems to be a simple expression so we try to calculat its value
  value = tmpl(expr.expr, isToggle ? extend({}, Object.create(this.parent), this) : this);
  hasValue = !isBlank(value);
  isObj = isObject(value);

  // convert the style/class objects to strings
  if (isObj) {
    isObj = !isClassAttr && !isStyleAttr;
    if (isClassAttr) {
      value = tmpl(JSON.stringify(value), this);
    } else if (isStyleAttr) {
      value = styleObjectToString(value);
    }
  }

  // remove original attribute
  if (expr.attr && (!expr.isAttrRemoved || !hasValue || value === false)) {
    remAttr(dom, expr.attr);
    expr.isAttrRemoved = true;
  }

  // for the boolean attributes we don't need the value
  // we can convert it to checked=true to checked=checked
  if (expr.bool) { value = value ? attrName : false; }
  if (expr.isRtag) { return updateDataIs(expr, this, value) }
  if (expr.wasParsedOnce && expr.value === value) { return }

  // update the expression value
  expr.value = value;
  expr.wasParsedOnce = true;

  // if the value is an object we can not do much more with it
  if (isObj && !isToggle) { return }
  // avoid to render undefined/null values
  if (isBlank(value)) { value = ''; }

  // textarea and text nodes have no attribute name
  if (!attrName) {
    // about #815 w/o replace: the browser converts the value to a string,
    // the comparison by "==" does too, but not in the server
    value += '';
    // test for parent avoids error with invalid assignment to nodeValue
    if (parent) {
      // cache the parent node because somehow it will become null on IE
      // on the next iteration
      expr.parent = parent;
      if (parent.tagName === 'TEXTAREA') {
        parent.value = value;                    // #1113
        if (!IE_VERSION) { dom.nodeValue = value; }  // #1625 IE throws here, nodeValue
      }                                         // will be available on 'updated'
      else { dom.nodeValue = value; }
    }
    return
  }


  // event handler
  if (isFunction(value)) {
    setEventHandler(attrName, value, dom, this);
  // show / hide
  } else if (isToggle) {
    toggleVisibility(dom, attrName === HIDE_DIRECTIVE ? !value : value);
  // handle attributes
  } else {
    if (expr.bool) {
      dom[attrName] = value;
    }

    if (attrName === 'value' && dom.value !== value) {
      dom.value = value;
    }

    if (hasValue && value !== false) {
      setAttr(dom, attrName, value);
    }

    // make sure that in case of style changes
    // the element stays hidden
    if (isStyleAttr && dom.hidden) { toggleVisibility(dom, false); }
  }
}
453952
function getExpressions(ast, start, end) {
        var expns = [],
            s     = start,
            e     = end,
            expn;

        while (true) {
            expn = RefactoringUtils.findSurroundExpression(ast, {start: s, end: e});
            if (!expn) {
                break;
            }
            expns.push(expn);
            s = expn.start - 1;
        }

        s = start;
        e = end;

        function checkExpnEquality(e) {
            return e.start === expn.start && e.end === expn.end;
        }

        while (true) {
            expn = RefactoringUtils.findSurroundExpression(ast, {start: s, end: e});
            if (!expn) {
                break;
            }
            e = expn.end + 1;

            // if expn already added, continue
            if (expns.find(checkExpnEquality)) {
                 continue;
            }

            expns.push(expn);
        }

        return expns;
    }
753631
def wrap_expr(self, src: str, dfltChaining: bool) -> str:
        """"""
        diff_binding = self.op_man.diff_binding()
        if diff_binding < 0 or diff_binding == 0 and not dfltChaining:
            return self.parenthesize(src)
        else:
            return src
326086
function transformDeleteDelete (a, b, first) {
  // reduce to a normalized case
  if (a.pos > b.pos) {
    return transformDeleteDelete(b, a, !first)
  }
  if (a.pos === b.pos && a.str.length > b.str.length) {
    return transformDeleteDelete(b, a, !first)
  }
  // take out overlapping parts
  if (b.pos < a.pos + a.str.length) {
    var s = b.pos - a.pos
    var s1 = a.str.length - s
    var s2 = s + b.str.length
    a.str = a.str.slice(0, s) + a.str.slice(s2)
    b.str = b.str.slice(s1)
    b.pos -= s
  } else {
    b.pos -= a.str.length
  }
}
534045
function bindingUpdated4(exp1, exp2, exp3, exp4) {
    var different = bindingUpdated2(exp1, exp2);
    return bindingUpdated2(exp3, exp4) || different;
}
1100531
function(expr, sup, sub) {
                    var opShape = generateOperator.call(this), expBox = expr.getFixRenderBox(), scriptHanlder = this.parentExpression.isSideScript() ? "applySide" : "applyUpDown", space = new ScriptController(this, opShape, sup, sub, {
                        zoom: .5
                    })[scriptHanlder](), padding = 5, diff = (space.height + space.top + space.bottom - expBox.height) / 2;
                    // 应用偏移， 使图形在正确的位置上
                    opShape.translate(0, space.top);
                    sup.translate(0, space.top);
                    sub.translate(0, space.top);
                    if (diff >= 0) {
                        expr.translate(space.width + padding, diff);
                    } else {
                        diff = -diff;
                        opShape.translate(0, diff);
                        sup.translate(0, diff);
                        sub.translate(0, diff);
                        expr.translate(space.width + padding, 0);
                    }
                    // 只扩展左边， 不扩展右边， 所以padding不 *2
                    this.parentExpression.expand(padding, padding * 2);
                    this.parentExpression.translateElement(padding, padding);
                }
394147
Expr atom() {
		Tok tok = peek();
		switch (tok.sym) {
		case LPAREN:
			move();
			Expr expr = expr();
			match(Sym.RPAREN);
			return expr;
		case ID:
			move();
			return new Id(tok.value());
		case STR:
			move();
			return new Const(tok.sym, tok.value());
		case INT:
		case LONG:
		case FLOAT:
		case DOUBLE:
			move();
			return new Const(tok.sym, ((NumTok)tok).getNumberValue());
		case TRUE:
			move();
			return Const.TRUE;
		case FALSE:
			move();
			return Const.FALSE;
		case NULL:
			move();
			return Const.NULL;
		case COMMA:
		case SEMICOLON:
		case QUESTION:	// support "c ?? ? a : b"
		case AND: case OR: case EQUAL: case NOTEQUAL:	// support "a.b ?? && expr"
		case RPAREN:	// support "(a.b ??)"
		case RBRACK:	// support "[start .. end ??]"
		case RBRACE:	// support "{key : value ??}"
		case RANGE:		// support "[start ?? .. end]"
		case COLON:		// support "c ? a ?? : b"
		case EOF:
			return null;
		default :
			throw new ParseException("Expression error: can not match the symbol \"" + tok.value() + "\"", location);
		}
	}