public static void AddExpression(int prec, Parser<IExpression> p) { if (!ExpressionList.ContainsKey(prec)) ExpressionList[prec] = new List<Parser<IExpression>>(); ExpressionList[prec].Add(p); ExpressionCache = null; SimpleExpressionCache = null; RebuildExp(); }
public static void AddOperator(int prec, string name, Func<IExpression, IExpression, Operator> op) { if (!OperatorList.ContainsKey(prec)) OperatorList[prec] = new List<Tuple<string, Func<IExpression, IExpression, Operator>>>(); OperatorList[prec].Add(new Tuple<string,Func<IExpression,IExpression,Operator>>(name, op)); ExpressionCache = null; SimpleExpressionCache = null; }
private static Parser<IExpression> RebuildExp(bool simple = false) { // sort by precedence var precs = new List<int>(ExpressionList.Keys); foreach (var k in OperatorList.Keys) if (!ExpressionList.ContainsKey(k)) precs.Add(k); // descending precs.Sort((a, b) => b.CompareTo(a)); foreach (var k in precs) { // expressions if (ExpressionList.ContainsKey(k)) foreach (var v in ExpressionList[k]) if (ExpressionCache == null) { ExpressionCache = v; SimpleExpressionCache = v; } else { // Mirror all changes into the simple expression ExpressionCache = ExpressionCache.Or(v); SimpleExpressionCache = SimpleExpressionCache.Or(v); } // operators if (OperatorList.ContainsKey(k)) { Parser<Func<IExpression, IExpression, Operator>> cache = null; foreach (var op in OperatorList[k]) { var c = op; // closure var p = //from s1 in Parse.Char('_') from symbol in Parse.String(c.Item1) //from s2 in Parse.Char('_') select c.Item2; if (cache == null) cache = p; else cache = cache.Or(p); } ExpressionCache = Parse.ChainOperator(cache, ExpressionCache.Token(), (op, left, right) => op(left, right)); } } return ExpressionCache; }