private static STNode ReadFunctionCall(ExcelFormulaLexer lexer) { var id = ReadSheetName(lexer); if (id == null) return null; string funName = null; // process function name like 'LOG10' if (id.Type == STNodeType.CELL) { Group mg = null; if (lexer.CurrentToken == null || (mg = lexer.CurrentToken.Groups["token"]) == null || !mg.Success || mg.Value != "(") return id; funName = lexer.Input.Substring(id.Start, id.Length); lexer.NextToken(); } else { if (id.Type != STNodeType.IDENTIFIER || !lexer.SkipToken("(")) return id; funName = ((STIdentifierNode)id).Identifier; } var parameterList = ReadParameterList(lexer); if (!lexer.SkipToken(")")) throw CreateException(lexer, "expect )"); return new STFunctionNode(funName, id.Start, lexer.CommittedLength - id.Start, parameterList); }
private static List <STNode> ReadParameterList(ExcelFormulaLexer lexer) { List <STNode> nodes = new List <STNode>(); int i = 0; while (true) { STNode node = ReadExpr(lexer); nodes.Add(node); i++; if (!lexer.SkipToken(Parser.ParameterSeparator)) { break; } } while (nodes.Count > 0 && nodes[nodes.Count - 1] == null) { nodes.RemoveAt(nodes.Count - 1); } return(nodes.Count == 0 ? null : nodes); }
private static STNode ReadExponent(ExcelFormulaLexer lexer) { var node = ReadPercent(lexer); if (node == null) { return(node); } while (lexer.SkipToken("^")) { var right = ReadPercent(lexer); if (right == null) { throw CreateException(lexer, "expect expression"); } node = CreateNode(lexer, STNodeType.POW, node.Start, lexer.CommittedLength - node.Start, new List <STNode> { node, right }); } return(node); }
private static STNode ReadPrimary(ExcelFormulaLexer lexer) { STNode node; if (CommitMatchNode(lexer, "string", STNodeType.STRING, out node) || CommitMatchNode(lexer, "identifier", STNodeType.IDENTIFIER, out node) || CommitMatchNode(lexer, "number", STNodeType.NUMBER, out node) || CommitMatchNode(lexer, "cell", STNodeType.CELL, out node) || CommitMatchNode(lexer, "range", STNodeType.RANGE, out node) || CommitMatchNode(lexer, "true", STNodeType.TRUE, out node) || CommitMatchNode(lexer, "false", STNodeType.FALSE, out node) || CommitMatchNode(lexer, "union_ranges", STNodeType.INTERSECTION, out node)) { return(node); } //else if (lexer.IsMatch("abs_cell")) //{ // var g = lexer.CurrentToken; // int col = RGUtility.GetNumberOfChar(g.Groups["col"].Value) - 1; // int row = int.Parse(g.Groups["row"].Value) - 1; // lexer.NextToken(); // return new STCellNode(lexer.Cell.Worksheet, new ReoGridPos(row, col), STNodeType.CELL, g.Index, g.Length); //} else if (lexer.IsToken("(")) { int start = lexer.Index; lexer.NextToken(); var expr = ReadExpr(lexer); if (expr == null) { throw CreateException(lexer, "expect expression"); } if (!lexer.SkipToken(")")) { throw CreateException(lexer, "expect )"); } return(CreateNode(lexer, STNodeType.SUB_EXPR, start, lexer.CommittedLength - start, new List <STNode>() { expr })); } else { return(null); } }
private static STNode ReadPercent(ExcelFormulaLexer lexer) { var node = ReadMinus(lexer); if (node == null) return null; while (lexer.SkipToken("%")) { node = CreateNode(lexer, STNodeType.UNARY_PERCENT, node.Start, lexer.CommittedLength - node.Start, new List<STNode>() { node }); } return node; }
private static STNode ReadConnect(ExcelFormulaLexer lexer) { var node = ReadAdd(lexer); if (node == null) return null; while (lexer.SkipToken("&")) { var right = ReadAdd(lexer); if (right == null) throw CreateException(lexer, "expect expression"); node = CreateNode(lexer, STNodeType.CONNECT, node.Start, lexer.CommittedLength - node.Start, new List<STNode> { node, right }); } return node; }
private static STNode ReadSheetName(ExcelFormulaLexer lexer) { var node = ReadPrimary(lexer); if (node == null) { return(null); } // neither a sheet name nor a function scope if (node.Type != STNodeType.IDENTIFIER) { return(node); } if (lexer.SkipToken("!")) { var id = ReadPrimary(lexer); if (id.Type != STNodeType.CELL && id.Type != STNodeType.RANGE && id.Type != STNodeType.IDENTIFIER) { throw CreateException(lexer, "expect Cell/Range/Name reference"); } var sheetName = ((STIdentifierNode)node).Identifier; IWorkbook workbook = lexer.Workbook; if (workbook == null && lexer.Cell != null && lexer.Cell.Worksheet != null && lexer.Cell.Worksheet.workbook != null) { workbook = lexer.Cell.Worksheet.workbook; } // only set worksheet reference if cell or worksheet associated if (workbook != null) { switch (id.Type) { case STNodeType.CELL: { STCellNode cellNode = (STCellNode)id; cellNode.Worksheet = workbook.GetWorksheetByName(sheetName); } break; case STNodeType.RANGE: { STRangeNode rangeNode = (STRangeNode)id; rangeNode.Worksheet = workbook.GetWorksheetByName(sheetName); } break; case STNodeType.IDENTIFIER: { STIdentifierNode idNode = (STIdentifierNode)id; idNode.Worksheet = workbook.GetWorksheetByName(sheetName); } break; } } return(id); } else if (lexer.SkipToken(".")) { var id = ReadPrimary(lexer); if (id.Type != STNodeType.IDENTIFIER) { throw CreateException(lexer, "expect identifier"); } return(id); } else { return(node); } }