⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 formulaparser.java

📁 Office格式转换代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            }            else {              Match(';');            }            Expression();			   addArgumentPointer();            numArgs++;        }        return numArgs;    }   /** Parse and Translate a Math Factor  */    private void Factor() {    	if (look == '-')    	{    		Match('-');    		Factor();    		tokens.add(new UnaryMinusPtg());    	}        else if (look == '(' ) {            Match('(');            Expression();            Match(')');            tokens.add(new ParenthesisPtg());        } else if (IsAlpha(look) || look == '\''){            Ident();        } else if(look == '"') {           StringLiteral();        } else {                         String number = GetNum();            if (look=='.') {                Match('.');                String decimalPart = null;                if (IsDigit(look)) number = number +"."+ GetNum(); //this also takes care of someone entering "1234."                tokens.add(new NumberPtg(number));            } else {                tokens.add(new IntPtg(number));  //TODO:what if the number is too big to be a short? ..add factory to return Int or Number!            }        }    }        private void StringLiteral() 	{		// Can't use match here 'cuz it consumes whitespace		// which we need to preserve inside the string.		// - pete		// Match('"');		if (look != '"')			Expected("\"");		else		{			GetChar();			StringBuffer Token = new StringBuffer();			for (;;)			{				if (look == '"')				{					GetChar();					SkipWhite(); //potential white space here since it doesnt matter up to the operator					if (look == '"')						Token.append("\"");					else						break;				}				else if (look == 0)				{					break;				}				else				{					Token.append(look);					GetChar();				}			}			tokens.add(new StringPtg(Token.toString()));		}	}        /** Recognize and Translate a Multiply */    private void Multiply(){        Match('*');        Factor();        tokens.add(new MultiplyPtg());      }            /** Recognize and Translate a Divide */    private void Divide() {        Match('/');        Factor();        tokens.add(new DividePtg());    }            /** Parse and Translate a Math Term */    private void  Term(){        Factor();		 while (look == '*' || look == '/' || look == '^' || look == '&') {                    ///TODO do we need to do anything here??            if (look == '*') Multiply();            else if (look == '/') Divide();            else if (look == '^') Power();            else if (look == '&') Concat();        }    }        /** Recognize and Translate an Add */    private void Add() {        Match('+');        Term();        tokens.add(new AddPtg());    }        /** Recognize and Translate a Concatination */    private void Concat() {        Match('&');        Term();        tokens.add(new ConcatPtg());    }        /** Recognize and Translate a test for Equality  */    private void Equal() {        Match('=');        Expression();        tokens.add(new EqualPtg());    }        /** Recognize and Translate a Subtract */    private void Subtract() {        Match('-');        Term();        tokens.add(new SubtractPtg());    }        private void Power() {        Match('^');        Term();        tokens.add(new PowerPtg());    }            /** Parse and Translate an Expression */    private void Expression() {        Term();        while (IsAddop(look)) {            if (look == '+' )  Add();            else if (look == '-') Subtract();        }        		/*		 * This isn't quite right since it would allow multiple comparison operators.		 */				  if(look == '=' || look == '>' || look == '<') {		  		if (look == '=') Equal();		      else if (look == '>') GreaterThan();		      else if (look == '<') LessThan();		      return;		  }                            }        /** Recognize and Translate a Greater Than  */    private void GreaterThan() {		Match('>');		if(look == '=')		    GreaterEqual();		else {		    Expression();		    tokens.add(new GreaterThanPtg());		}    }        /** Recognize and Translate a Less Than  */    private void LessThan() {		Match('<');		if(look == '=')		    LessEqual();		else if(look == '>')		    NotEqual();		else {		    Expression();		    tokens.add(new LessThanPtg());		}	}        /**    * Recognize and translate Greater than or Equal    *    */ 	private void GreaterEqual() {	    Match('=');	    Expression();	    tokens.add(new GreaterEqualPtg());	}    	/**	 * Recognize and translate Less than or Equal	 *	 */ 	private void LessEqual() {	    Match('=');	    Expression();	    tokens.add(new LessEqualPtg());	}		/**	 * Recognize and not Equal	 *	 */ 	private void NotEqual() {	    Match('>');	    Expression();	    tokens.add(new NotEqualPtg());	}            //{--------------------------------------------------------------}    //{ Parse and Translate an Assignment Statement }    /**procedure Assignment;var Name: string[8];begin   Name := GetName;   Match('=');   Expression;end;     **/         /** Initialize */        private void  init() {        GetChar();        SkipWhite();    }        /** API call to execute the parsing of the formula     *     */    public void parse() {        synchronized (tokens) {            init();            Expression();        }    }            /*********************************     * PARSER IMPLEMENTATION ENDS HERE     * EXCEL SPECIFIC METHODS BELOW     *******************************/        /** API call to retrive the array of Ptgs created as      * a result of the parsing     */    public Ptg[] getRPNPtg() {     return getRPNPtg(FORMULA_TYPE_CELL);    }        public Ptg[] getRPNPtg(int formulaType) {        Node node = createTree();        setRootLevelRVA(node, formulaType);        setParameterRVA(node,formulaType);        return (Ptg[]) tokens.toArray(new Ptg[0]);    }        private void setRootLevelRVA(Node n, int formulaType) {        //Pg 16, excelfileformat.pdf @ openoffice.org        Ptg p = (Ptg) n.getValue();            if (formulaType == FormulaParser.FORMULA_TYPE_NAMEDRANGE) {                if (p.getDefaultOperandClass() == Ptg.CLASS_REF) {                    setClass(n,Ptg.CLASS_REF);                } else {                    setClass(n,Ptg.CLASS_ARRAY);                }            } else {                setClass(n,Ptg.CLASS_VALUE);            }            }        private void setParameterRVA(Node n, int formulaType) {        Ptg p = (Ptg) n.getValue();        if (p instanceof AbstractFunctionPtg) {            int numOperands = n.getNumChildren();            for (int i =0;i<n.getNumChildren();i++) {                setParameterRVA(n.getChild(i),((AbstractFunctionPtg)p).getParameterClass(i),formulaType);                if (n.getChild(i).getValue() instanceof AbstractFunctionPtg) {                    setParameterRVA(n.getChild(i),formulaType);                }            }          } else {            for (int i =0;i<n.getNumChildren();i++) {                setParameterRVA(n.getChild(i),formulaType);            }        }     }    private void setParameterRVA(Node n, int expectedClass,int formulaType) {        Ptg p = (Ptg) n.getValue();        if (expectedClass == Ptg.CLASS_REF) { //pg 15, table 1             if (p.getDefaultOperandClass() == Ptg.CLASS_REF ) {                setClass(n, Ptg.CLASS_REF);            }            if (p.getDefaultOperandClass() == Ptg.CLASS_VALUE) {                if (formulaType==FORMULA_TYPE_CELL || formulaType == FORMULA_TYPE_SHARED) {                    setClass(n,Ptg.CLASS_VALUE);                } else {                    setClass(n,Ptg.CLASS_ARRAY);                }            }            if (p.getDefaultOperandClass() == Ptg.CLASS_ARRAY ) {                setClass(n, Ptg.CLASS_ARRAY);            }        } else if (expectedClass == Ptg.CLASS_VALUE) { //pg 15, table 2            if (formulaType == FORMULA_TYPE_NAMEDRANGE) {                setClass(n,Ptg.CLASS_ARRAY) ;            } else {                setClass(n,Ptg.CLASS_VALUE);            }        } else { //Array class, pg 16.             if (p.getDefaultOperandClass() == Ptg.CLASS_VALUE &&                 (formulaType==FORMULA_TYPE_CELL || formulaType == FORMULA_TYPE_SHARED)) {                 setClass(n,Ptg.CLASS_VALUE);            } else {                setClass(n,Ptg.CLASS_ARRAY);            }        }    }         private void setClass(Node n, byte theClass) {        Ptg p = (Ptg) n.getValue();        if (p instanceof AbstractFunctionPtg || !(p instanceof OperationPtg)) {            p.setClass(theClass);        } else {            for (int i =0;i<n.getNumChildren();i++) {                setClass(n.getChild(i),theClass);            }        }     }    /**     * Convience method which takes in a list then passes it to the other toFormulaString     * signature.      * @param book   workbook for 3D and named references     * @param lptgs  list of Ptg, can be null or empty     * @return a human readable String     */    public static String toFormulaString(Workbook book, List lptgs) {        String retval = null;        if (lptgs == null || lptgs.size() == 0) return "#NAME";        Ptg[] ptgs = new Ptg[lptgs.size()];        ptgs = (Ptg[])lptgs.toArray(ptgs);        retval = toFormulaString(book, ptgs);        return retval;    }        /**     * Static method to convert an array of Ptgs in RPN order     * to a human readable string format in infix mode.     * @param book  workbook for named and 3D references     * @param ptgs  array of Ptg, can be null or empty     * @return a human readable String     */    public static String toFormulaString(Workbook book, Ptg[] ptgs) {        if (ptgs == null || ptgs.length == 0) return "#NAME";        java.util.Stack stack = new java.util.Stack();        AttrPtg ifptg = null;           // Excel allows to have AttrPtg at position 0 (such as Blanks) which           // do not have any operands. Skip them.        stack.push(ptgs[0].toFormulaString(book));                          for (int i = 1; i < ptgs.length; i++) {            if (! (ptgs[i] instanceof OperationPtg)) {                stack.push(ptgs[i].toFormulaString(book));                continue;            }                                  if (ptgs[i] instanceof AttrPtg && ((AttrPtg) ptgs[i]).isOptimizedIf()) {                ifptg = (AttrPtg) ptgs[i];                continue;            }                                  final OperationPtg o = (OperationPtg) ptgs[i];            final String[] operands = new String[o.getNumberOfOperands()];            for (int j = operands.length; j > 0; j--) {                //TODO: catch stack underflow and throw parse exception.                operands[j - 1] = (String) stack.pop();                      }              stack.push(o.toFormulaString(operands));            if (!(o instanceof AbstractFunctionPtg)) continue;            final AbstractFunctionPtg f = (AbstractFunctionPtg) o;            final String fname = f.getName();            if (fname == null) continue;            if ((ifptg != null) && (fname.equals("specialflag"))) {                             // this special case will be way different.                stack.push(ifptg.toFormulaString(new String[]{(String) stack.pop()}));                continue;                      }            if (fname.equals("externalflag")) {                final String top = (String) stack.pop();                final int paren = top.indexOf('(');                final int comma = top.indexOf(',');                if (comma == -1) {                    final int rparen = top.indexOf(')');                    stack.push(top.substring(paren + 1, rparen) + "()");                  }                else {                    stack.push(top.substring(paren + 1, comma) + '(' +                               top.substring(comma + 1));            }        }    }        // TODO: catch stack underflow and throw parse exception.        return (String) stack.pop();    }    /** Create a tree representation of the RPN token array     *used to run the class(RVA) change algo     */    private Node createTree() {        java.util.Stack stack = new java.util.Stack();        int numPtgs = tokens.size();        OperationPtg o;        int numOperands;        Node[] operands;        for (int i=0;i<numPtgs;i++) {            if (tokens.get(i) instanceof OperationPtg) {                                o = (OperationPtg) tokens.get(i);                numOperands = o.getNumberOfOperands();                operands = new Node[numOperands];                for (int j=0;j<numOperands;j++) {                    operands[numOperands-j-1] = (Node) stack.pop();                 }                Node result = new Node(o);                result.setChildren(operands);                stack.push(result);            } else {                stack.push(new Node((Ptg)tokens.get(i)));            }        }        return (Node) stack.pop();    }       /** toString on the parser instance returns the RPN ordered list of tokens     *   Useful for testing     */    public String toString() {        StringBuffer buf = new StringBuffer();           for (int i=0;i<tokens.size();i++) {            buf.append( ( (Ptg)tokens.get(i)).toFormulaString(book));            buf.append(' ');        }         return buf.toString();    }    }       /** Private helper class, used to create a tree representation of the formula*/    class Node {        private Ptg value=null;        private Node[] children=new Node[0];        private int numChild=0;        public Node(Ptg val) {            value = val;         }        public void setChildren(Node[] child) {children = child;numChild=child.length;}        public int getNumChildren() {return numChild;}        public Node getChild(int number) {return children[number];}        public Ptg getValue() {return value;}    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -