private void TransformNode(ParseNode node, byte desiredOperandClass, bool callerForceArrayFlag) { Ptg token = node.GetToken(); ParseNode[] children = node.Children; if (token is ValueOperatorPtg || token is ControlPtg) { // Value Operator Ptgs and Control are base tokens, so token will be UnChanged // but any child nodes are Processed according to desiredOperandClass and callerForceArrayFlag for (int i = 0; i < children.Length; i++) { ParseNode child = children[i]; TransformNode(child, desiredOperandClass, callerForceArrayFlag); } return; } if (token is AbstractFunctionPtg) { TransformFunctionNode((AbstractFunctionPtg)token, children, desiredOperandClass, callerForceArrayFlag); return; } if (children.Length > 0) { throw new Exception("Node should not have any children"); } if (token.IsBaseToken) { // nothing to do return; } if (callerForceArrayFlag) { switch (desiredOperandClass) { case Ptg.CLASS_VALUE: case Ptg.CLASS_ARRAY: token.PtgClass=(Ptg.CLASS_ARRAY); break; case Ptg.CLASS_REF: token.PtgClass=(Ptg.CLASS_REF); break; default: throw new Exception("Unexpected operand class (" + desiredOperandClass + ")"); } } else { token.PtgClass=(desiredOperandClass); } }
/** * Traverses the supplied formula parse tree, calling <tt>Ptg.SetClass()</tt> for each non-base * token to Set its operand class. */ public void TransformFormula(ParseNode rootNode) { byte rootNodeOperandClass; switch (_formulaType) { case FormulaParser.FORMULA_TYPE_CELL: rootNodeOperandClass = Ptg.CLASS_VALUE; break; default: throw new Exception("Incomplete code - formula type (" + _formulaType + ") not supported yet"); } TransformNode(rootNode, rootNodeOperandClass, false); }
public ParseNode(Ptg token, ParseNode[] children) { _token = token; _children = children; _isIf = IsIf(token); int tokenCount = 1; for (int i = 0; i < children.Length; i++) { tokenCount += children[i].GetTokenCount(); } if (_isIf) { // there will be 2 or 3 extra tAttr tokens according to whether the false param is present tokenCount += children.Length; } _tokenCount = tokenCount; }
private void TransformFunctionNode(AbstractFunctionPtg afp, ParseNode[] children, byte desiredOperandClass, bool callerForceArrayFlag) { bool localForceArrayFlag; byte defaultReturnOperandClass = afp.DefaultOperandClass; if (callerForceArrayFlag) { switch (defaultReturnOperandClass) { case Ptg.CLASS_REF: if (desiredOperandClass == Ptg.CLASS_REF) { afp.PtgClass=(Ptg.CLASS_REF); } else { afp.PtgClass=(Ptg.CLASS_ARRAY); } localForceArrayFlag = false; break; case Ptg.CLASS_ARRAY: afp.PtgClass=(Ptg.CLASS_ARRAY); localForceArrayFlag = false; break; case Ptg.CLASS_VALUE: afp.PtgClass=(Ptg.CLASS_ARRAY); localForceArrayFlag = true; break; default: throw new Exception("Unexpected operand class (" + defaultReturnOperandClass + ")"); } } else { if (defaultReturnOperandClass == desiredOperandClass) { localForceArrayFlag = false; // an alternative would have been to for non-base Ptgs to Set their operand class // from their default, but this would require the call in many subclasses because // the default OC Is not known Until the end of the constructor afp.PtgClass=(defaultReturnOperandClass); } else { switch (desiredOperandClass) { case Ptg.CLASS_VALUE: // always OK to Set functions to return 'value' afp.PtgClass=(Ptg.CLASS_VALUE); localForceArrayFlag = false; break; case Ptg.CLASS_ARRAY: switch (defaultReturnOperandClass) { case Ptg.CLASS_REF: afp.PtgClass=(Ptg.CLASS_REF); break; case Ptg.CLASS_VALUE: afp.PtgClass=(Ptg.CLASS_ARRAY); break; default: throw new Exception("Unexpected operand class (" + defaultReturnOperandClass + ")"); } localForceArrayFlag = (defaultReturnOperandClass == Ptg.CLASS_VALUE); break; case Ptg.CLASS_REF: switch (defaultReturnOperandClass) { case Ptg.CLASS_ARRAY: afp.PtgClass=(Ptg.CLASS_ARRAY); break; case Ptg.CLASS_VALUE: afp.PtgClass=(Ptg.CLASS_VALUE); break; default: throw new Exception("Unexpected operand class (" + defaultReturnOperandClass + ")"); } localForceArrayFlag = false; break; default: throw new Exception("Unexpected operand class (" + desiredOperandClass + ")"); } } } for (int i = 0; i < children.Length; i++) { ParseNode child = children[i]; byte paramOperandClass = afp.GetParameterClass(i); TransformNode(child, paramOperandClass, localForceArrayFlag); } }
/// <summary> /// Collects the array of Ptg /// tokens for the specified tree. /// </summary> /// <param name="rootNode">The root node.</param> /// <returns></returns> public static Ptg[] ToTokenArray(ParseNode rootNode) { TokenCollector temp = new TokenCollector(rootNode.GetTokenCount()); rootNode.CollectPtgs(temp); return temp.Result; }
public ParseNode(Ptg token, ParseNode child0, ParseNode child1): this(token, new ParseNode[] { child0, child1, }) { }
//{--------------------------------------------------------------} //{ Parse and Translate an Assignment Statement } /** procedure Assignment; var Name: string[8]; begin Name := GetName; Match('='); Expression; end; **/ /** * API call To execute the parsing of the formula * @deprecated use Ptg[] FormulaParser.Parse(String, HSSFWorkbook) directly */ public void Parse() { pointer = 0; GetChar(); _rootNode = comparisonExpression(); if (pointer <= formulaLength) { String msg = "Unused input [" + formulaString.Substring(pointer - 1) + "] after attempting To Parse the formula [" + formulaString + "]"; throw new FormulaParseException(msg); } }
private ParseNode concatExpression() { ParseNode result = AdditiveExpression(); while (true) { SkipWhite(); if (look != '&') { break; // finished with concat expression } Match('&'); ParseNode other = AdditiveExpression(); result = new ParseNode(ConcatPtg.instance, result, other); } return result; }
/** Parse and Translate an Expression */ private ParseNode AdditiveExpression() { ParseNode result = Term(); while (true) { SkipWhite(); Ptg operator1; switch (look) { case '+': Match('+'); operator1 = AddPtg.instance; break; case '-': Match('-'); operator1 = SubtractPtg.instance; break; default: return result; // finished with Additive expression } ParseNode other = Term(); result = new ParseNode(operator1, result, other); } }
private ParseNode comparisonExpression() { ParseNode result = concatExpression(); while (true) { SkipWhite(); switch (look) { case '=': case '>': case '<': Ptg comparisonToken = GetComparisonToken(); ParseNode other = concatExpression(); result = new ParseNode(comparisonToken, result, other); continue; } return result; // finished with predicate expression } }
/** Parse and Translate a Math Term */ private ParseNode Term() { ParseNode result = powerFactor(); while (true) { SkipWhite(); Ptg operator1; switch (look) { case '*': Match('*'); operator1 = MultiplyPtg.instance; break; case '/': Match('/'); operator1 = DividePtg.instance; break; default: return result; // finished with Term } ParseNode other = powerFactor(); result = new ParseNode(operator1, result, other); } }
private ParseNode percentFactor() { ParseNode result = ParseSimpleFactor(); while (true) { SkipWhite(); if (look != '%') { return result; } Match('%'); result = new ParseNode(PercentPtg.instance, result); } }
/** Parse and Translate a Math Factor */ private ParseNode powerFactor() { ParseNode result = percentFactor(); while (true) { SkipWhite(); if (look != '^') { return result; } Match('^'); ParseNode other = percentFactor(); result = new ParseNode(PowerPtg.instance, result, other); } }
/** * Generates the variable function ptg for the formula. * <p> * For IF Formulas, Additional PTGs are Added To the Tokens * @param name * @param numArgs * @return Ptg a null Is returned if we're in an IF formula, it needs extreme manipulation and Is handled in this function */ private ParseNode GetFunction(String name, NamePtg namePtg, ParseNode[] args) { FunctionMetadata fm = FunctionMetadataRegistry.GetFunctionByName(name.ToUpper()); int numArgs = args.Length; if (fm == null) { if (namePtg == null) { throw new InvalidOperationException("NamePtg must be supplied for external functions"); } // must be external function ParseNode[] allArgs = new ParseNode[numArgs + 1]; allArgs[0] = new ParseNode(namePtg); Array.Copy(args, 0, allArgs, 1, numArgs); return new ParseNode(new FuncVarPtg(name, (byte)(numArgs + 1)), allArgs); } if (namePtg != null) { throw new InvalidOperationException("NamePtg no applicable To internal functions"); } bool IsVarArgs = !fm.HasFixedArgsLength; int funcIx = fm.Index; ValidateNumArgs(args.Length, fm); AbstractFunctionPtg retval; if (IsVarArgs) { retval = new FuncVarPtg(name, (byte)numArgs); } else { retval = new FuncPtg(funcIx); } return new ParseNode(retval, args); }