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

📄 formulaparser.java

📁 介绍java核心技术的pio编程方法以及基本概念
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
        Match('(');        int numArgs = Arguments();        Match(')');                        AbstractFunctionPtg functionPtg = getFunction(name,(byte)numArgs);        		tokens.add(functionPtg);         if (functionPtg.getName().equals("externalflag")) {            tokens.add(new NamePtg(name, this.book));        } 		//remove what we just put in		this.functionTokens.remove(0);    }        /**     * Adds the size of all the ptgs after the provided index (inclusive).     * <p>     * Initially used to count a goto     * @param index     * @return int     */    private int getPtgSize(int index) {    	int count = 0;    	    	Iterator ptgIterator = tokens.listIterator(index);    	while (ptgIterator.hasNext()) {    		Ptg ptg = (Ptg)ptgIterator.next();    		count+=ptg.getSize();    	}    	    	return count;    }        private int getPtgSize(int start, int end) {        int count = 0;        int index = start;        Iterator ptgIterator = tokens.listIterator(index);        while (ptgIterator.hasNext() && index <= end) {            Ptg ptg = (Ptg)ptgIterator.next();            count+=ptg.getSize();            index++;        }                return count;    }    /**     * 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 AbstractFunctionPtg getFunction(String name, byte numArgs) {        AbstractFunctionPtg retval = null;                if (name.equals("IF")) {            retval = new FuncVarPtg(AbstractFunctionPtg.ATTR_NAME, numArgs);                        //simulated pop, no bounds checking because this list better be populated by function()            List argumentPointers = (List)this.functionTokens.get(0);                                    AttrPtg ifPtg = new AttrPtg();            ifPtg.setData((short)7); //mirroring excel output            ifPtg.setOptimizedIf(true);                        if (argumentPointers.size() != 2  && argumentPointers.size() != 3) {                throw new IllegalArgumentException("["+argumentPointers.size()+"] Arguments Found - An IF formula requires 2 or 3 arguments. IF(CONDITION, TRUE_VALUE, FALSE_VALUE [OPTIONAL]");            }                        //Biffview of an IF formula record indicates the attr ptg goes after the condition ptgs and are            //tracked in the argument pointers            //The beginning first argument pointer is the last ptg of the condition            int ifIndex = tokens.indexOf(argumentPointers.get(0))+1;            tokens.add(ifIndex, ifPtg);                        //we now need a goto ptgAttr to skip to the end of the formula after a true condition            //the true condition is should be inserted after the last ptg in the first argument                        int gotoIndex = tokens.indexOf(argumentPointers.get(1))+1;                        AttrPtg goto1Ptg = new AttrPtg();            goto1Ptg.setGoto(true);                                    tokens.add(gotoIndex, goto1Ptg);                                    if (numArgs > 2) { //only add false jump if there is a false condition                                //second goto to skip past the function ptg                AttrPtg goto2Ptg = new AttrPtg();                goto2Ptg.setGoto(true);                goto2Ptg.setData((short)(retval.getSize()-1));                //Page 472 of the Microsoft Excel Developer's kit states that:                //The b(or w) field specifies the number byes (or words to skip, minus 1                                tokens.add(goto2Ptg); //this goes after all the arguments are defined            }                        //data portion of the if ptg points to the false subexpression (Page 472 of MS Excel Developer's kit)            //count the number of bytes after the ifPtg to the False Subexpression            //doesn't specify -1 in the documentation            ifPtg.setData((short)(getPtgSize(ifIndex+1, gotoIndex)));                        //count all the additional (goto) ptgs but dont count itself            int ptgCount = this.getPtgSize(gotoIndex)-goto1Ptg.getSize()+retval.getSize();            if (ptgCount > (int)Short.MAX_VALUE) {                throw new RuntimeException("Ptg Size exceeds short when being specified for a goto ptg in an if");            }                        goto1Ptg.setData((short)(ptgCount-1));                    } else {                        retval = new FuncVarPtg(name,numArgs);        }                return retval;    }        /** get arguments to a function */    private int Arguments() {        int numArgs = 0;        if (look != ')')  {            numArgs++;             Expression();			   addArgumentPointer();        }        while (look == ','  || look == ';') { //TODO handle EmptyArgs            if(look == ',') {              Match(',');            }            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('+');            Factor();            tokens.add(new UnaryPlusPtg());        }        else if (look == '(' ) {            Match('(');            Expression();            Match(')');            tokens.add(new ParenthesisPtg());        } else if (IsAlpha(look) || look == '\''){            Ident();        } else if(look == '"') {           StringLiteral();        } else if (look == ')' || look == ',') {        	tokens.add(new MissingArgPtg());        } else {            String number2 = null;            String exponent = null;            String number1 = GetNum();                        if (look == '.') {                GetChar();                number2 = GetNum();            }                        if (look == 'E') {                GetChar();                                String sign = "";                if (look == '+') {                    GetChar();                } else if (look == '-') {                    GetChar();                    sign = "-";                }                                String number = GetNum();                if (number == null) {                    Expected("Integer");                }                exponent = sign + number;            }                        if (number1 == null && number2 == null) {                Expected("Integer");            }                        tokens.add(getNumberPtgFromString(number1, number2, exponent));        }    }    	/** 	 * Get a PTG for an integer from its string representation. 	 * return Int or Number Ptg based on size of input	 */	private Ptg getNumberPtgFromString(String number1, String number2, String exponent) {        StringBuffer number = new StringBuffer();        	    if (number2 == null) {	        number.append(number1);    	        	    if (exponent != null) {    	        number.append('E');    	        number.append(exponent);    	    }    	                String numberStr = number.toString();                        try {                return new IntPtg(numberStr);            } catch (NumberFormatException e) {                return new NumberPtg(numberStr);            }	    } else {            if (number1 != null) {                number.append(number1);            }                        number.append('.');            number.append(number2);                        if (exponent != null) {                number.append('E');                number.append(exponent);            }                        return new NumberPtg(number.toString());	    }	}			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();        }

⌨️ 快捷键说明

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