private Expression ParseAtom() { string id; Expression x = null; switch (_token.Type) { // literals case TKTYPE.LITERAL: x = new Expression(_token); break; // identifiers case TKTYPE.IDENTIFIER: // get identifier id = (string)_token.Value; // look for functions if (_fnTbl.TryGetValue(id, out FunctionDefinition fnDef)) { var p = GetParameters(); var pCnt = p == null ? 0 : p.Count; if (fnDef.ParmMin != -1 && pCnt < fnDef.ParmMin) { Throw(string.Format("Too few parameters for function '{0}'. Expected a minimum of {1} and a maximum of {2}.", id, fnDef.ParmMin, fnDef.ParmMax)); } if (fnDef.ParmMax != -1 && pCnt > fnDef.ParmMax) { Throw(string.Format("Too many parameters for function '{0}'.Expected a minimum of {1} and a maximum of {2}.", id, fnDef.ParmMin, fnDef.ParmMax)); } x = new FunctionExpression(fnDef, p); break; } // look for simple variables (much faster than binding!) if (_vars.ContainsKey(id)) { x = new VariableExpression(_vars, id); break; } // look for external objects var xObj = GetExternalObject(id); if (xObj != null) { x = new XObjectExpression(xObj); break; } Throw("Unexpected identifier"); break; // sub-expressions case TKTYPE.GROUP: // Normally anything other than opening parenthesis is illegal here // but Excel allows omitted parameters so return empty value expression. if (_token.ID != TKID.OPEN) { return(new EmptyValueExpression()); } // get expression GetToken(); x = ParseCompare(); // check that the parenthesis was closed if (_token.ID != TKID.CLOSE) { Throw("Unbalanced parenthesis."); } break; case TKTYPE.ERROR: x = new ErrorExpression((ErrorExpression.ExpressionErrorType)_token.Value); break; } // make sure we got something... if (x == null) { Throw(); } // done GetToken(); return(x); }
Expression ParseAtom() { string id; Expression x = null; FunctionDefinition fnDef = null; switch (_token.Type) { // literals case TKTYPE.LITERAL: x = new Expression(_token); break; // identifiers case TKTYPE.IDENTIFIER: // get identifier id = (string)_token.Value; // look for functions if (_fnTbl.TryGetValue(id, out fnDef)) { var p = GetParameters(); var pCnt = p == null ? 0 : p.Count; if (fnDef.ParmMin != -1 && pCnt < fnDef.ParmMin) { Throw("Too few parameters."); } if (fnDef.ParmMax != -1 && pCnt > fnDef.ParmMax) { Throw("Too many parameters."); } x = new FunctionExpression(fnDef, p); break; } // look for simple variables (much faster than binding!) if (_vars.ContainsKey(id)) { x = new VariableExpression(_vars, id); break; } // look for external objects var xObj = GetExternalObject(id); if (xObj != null) { x = new XObjectExpression(xObj); break; } // look for bindings if (DataContext != null) { var list = new List <BindingInfo>(); for (var t = _token; t != null; t = GetMember()) { list.Add(new BindingInfo((string)t.Value, GetParameters())); } x = new BindingExpression(this, list, _ci); break; } Throw("Unexpected identifier"); break; // sub-expressions case TKTYPE.GROUP: // anything other than opening parenthesis is illegal here if (_token.ID != TKID.OPEN) { Throw("Expression expected."); } // get expression GetToken(); x = ParseCompare(); // check that the parenthesis was closed if (_token.ID != TKID.CLOSE) { Throw("Unbalanced parenthesis."); } break; } // make sure we got something... if (x == null) { Throw(); } // done GetToken(); return(x); }