> ETA of my commit....tonight.  
great. i'll get on with it tomorrow in that case. 

>I'm looking at all you send.
Thanks

Quoting "Andrew C. Oliver" <[EMAIL PROTECTED]>:

> ETA of my commit....tonight.  I'm looking at all you send.   I'll 
> probably devote even more attention to it this weekend.
> 
> Avik Sengupta wrote:
> 
> >Attached is YET another version of formula parser, now with a static method
> 
> >that can convert a RPN order array of Ptgs into human readable infix order
> 
> >formula string. 
> >
> >This change depends on changes to many ptg files, so i will not even attempt
> to 
> >send accross a full set to the list. After I merge my stuff with what andy
> has 
> >done, i will send a proper patch. Till then you will have to live with these
> 
> >bits and pieces :(
> >
> >Cheers
> >-
> >Avik
> >
> >
> >
> >------------------------------------------------------------------------
> >
> >
> >/* ====================================================================
> > * The Apache Software License, Version 1.1
> > *
> > * Copyright (c) 2002 The Apache Software Foundation.  All rights
> > * reserved.
> > *
> > * Redistribution and use in source and binary forms, with or without
> > * modification, are permitted provided that the following conditions
> > * are met:
> > *
> > * 1. Redistributions of source code must retain the above copyright
> > *    notice, this list of conditions and the following disclaimer.
> > *
> > * 2. Redistributions in binary form must reproduce the above copyright
> > *    notice, this list of conditions and the following disclaimer in
> > *    the documentation and/or other materials provided with the
> > *    distribution.
> > *
> > * 3. The end-user documentation included with the redistribution,
> > *    if any, must include the following acknowledgment:
> > *       "This product includes software developed by the
> > *        Apache Software Foundation (http://www.apache.org/)."
> > *    Alternately, this acknowledgment may appear in the software itself,
> > *    if and wherever such third-party acknowledgments normally appear.
> > *
> > * 4. The names "Apache" and "Apache Software Foundation" and
> > *    "Apache POI" must not be used to endorse or promote products
> > *    derived from this software without prior written permission. For
> > *    written permission, please contact [EMAIL PROTECTED]
> > *
> > * 5. Products derived from this software may not be called "Apache",
> > *    "Apache POI", nor may "Apache" appear in their name, without
> > *    prior written permission of the Apache Software Foundation.
> > *
> > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
> > * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> > * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> > * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
> > * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> > * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> > * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> > * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
> > * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> > * SUCH DAMAGE.
> > * ====================================================================
> > *
> > * This software consists of voluntary contributions made by many
> > * individuals on behalf of the Apache Software Foundation.  For more
> > * information on the Apache Software Foundation, please see
> > * <http://www.apache.org/>.
> > */
> >
> >
> >package org.apache.poi.hssf.record.formula;
> >
> >import java.util.List;
> >import java.util.ArrayList;
> >import java.util.Stack;
> >
> >/**
> > * EXPERIMENTAL 
> > *
> > * @author Avik Sengupta <avik AT Avik Sengupta DOT com>
> > *
> > * This class parses a formula string into a List of tokens in RPN order
> > * Inspired by 
> > *           Lets Build a Compiler, by Jack Crenshaw
> > * BNF for the formula expression is :
> > * <expression> ::= <term> [<addop> <term>]*
> > * <term> ::= <factor>  [ <mulop> <factor ]*
> > * <factor> ::= <number> | (<expression>) | <cellRef> 
> > */
> >public class FormulaParser {
> >    
> >    private String formulaString;
> >    private int pointer=0;
> >    
> >    private List tokens = new java.util.Stack();
> >    //private Stack tokens = new java.util.Stack();
> >    private List result = new ArrayList();
> >    private int numParen;
> >    
> >    private static char TAB = '\t';
> >    private static char CR = '\n';
> >    
> >   private char Look;              // Lookahead Character 
> >    
> >    
> >    /** create the parser with the string that is to be parsed
> >     *    later call the parse() method to return ptg list in rpn order
> >     *    then call the getRPNPtg() to retrive the parse results
> >     *  This class is recommended only for single threaded use
> >     *  The parse and getPRNPtg are internally synchronized for safety,
> thus
> >     *  while it is safe to use in a multithreaded environment, you will get
> long lock waits.  
> >     */
> >    public FormulaParser(String formula){
> >        formulaString = formula;
> >        pointer=0;
> >    }
> >    
> >
> >    /** Read New Character From Input Stream */
> >    private void GetChar() {
> >        Look=formulaString.charAt(pointer++);
> >        //System.out.println("Got char: "+Look);
> >    }
> >    
> >
> >    /** Report an Error */
> >    private void Error(String s) {
> >        System.out.println("Error: "+s);
> >    }
> >    
> >    
> > 
> >    /** Report Error and Halt */
> >    private void Abort(String s) {
> >        Error(s);
> >        //System.exit(1);  //throw exception??
> >        throw new RuntimeException("Cannot Parse, sorry");
> >    }
> >    
> >    
> >
> >    /** Report What Was Expected */
> >    private void Expected(String s) {
> >        Abort(s + " Expected");
> >    }
> >    
> >    
> > 
> >    /** Recognize an Alpha Character */
> >    private boolean IsAlpha(char c) {
> >        return Character.isLetter(c);
> >    }
> >    
> >    
> > 
> >    /** Recognize a Decimal Digit */
> >    private boolean IsDigit(char c) {
> >        //System.out.println("Checking digit for"+c);
> >        return Character.isDigit(c);
> >    }
> >    
> >    
> >
> >    /** Recognize an Alphanumeric */
> >    private boolean  IsAlNum(char c) {
> >        return  (IsAlpha(c) || IsDigit(c));
> >    }
> >    
> >    
> >
> >    /** Recognize an Addop */
> >    private boolean IsAddop( char c) {
> >        return (c =='+' || c =='-');
> >    }
> >    
> >
> >    /** Recognize White Space */
> >    private boolean IsWhite( char c) {
> >        return  (c ==' ' || c== TAB);
> >    }
> >    
> >    
> >
> >    /** Skip Over Leading White Space */
> >    private void SkipWhite() {
> >        while (IsWhite(Look)) {
> >            GetChar();
> >        }
> >    }
> >    
> >    
> >
> >    /** Match a Specific Input Character */
> >    private void Match(char x) {
> >        if (Look != x) {
> >            Expected("" + x + "");
> >        }else {
> >            GetChar();
> >            SkipWhite();
> >        }
> >    }
> >    
> >    
> >    /** Get an Identifier */
> >    private String GetName() {
> >        String Token;
> >        Token = "";
> >        if (!IsAlpha(Look)) {
> >            Expected("Name");
> >        }
> >        while (IsAlNum(Look)) {
> >            Token = Token + Character.toUpperCase(Look);
> >            GetChar();
> >        }
> >        
> >        SkipWhite();
> >        return Token;
> >    }
> >    
> >    
> >    /** Get a Number */
> >    private String GetNum() {
> >        String Value ="";
> >        if  (!IsDigit(Look)) Expected("Integer");
> >        while (IsDigit(Look)){
> >            Value = Value + Look;
> >            GetChar();
> >        }
> >        SkipWhite();
> >        return Value;
> >    }
> >
> >    /** Output a String with Tab */
> >    private void  Emit(String s){
> >        System.out.print(TAB+s);
> >    }
> >
> >    /** Output a String with Tab and CRLF */
> >    private void EmitLn(String s) {
> >        Emit(s);
> >        System.out.println();;
> >    }
> >    
> >    /** Parse and Translate a Identifier */
> >    private void Ident() {
> >        String Name;
> >        Name = GetName();
> >        if (Look == '('){
> >            //This is a function 
> >            Match('(');
> >            int numArgs = Arguments(); //Expression() -- add this!
> >            Match(')');
> >            //this is the end of the function
> >            tokens.add(new DummyFunctionPtg(Name,numArgs));
> >        } else {
> >            //this can be either a cell ref or a named range !!
> >            
> >            boolean cellRef = true ; //we should probably do it with reg
> exp??
> >            if (cellRef) {
> >                tokens.add(new ValueReferencePtg()); //TODO we need to pass
> in Name somewhere??
> >            }else {
> >                //handle after named range is integrated!!
> >            }
> >        }
> >    }
> >    
> >    /** get arguments to a function */
> >    private int Arguments() {
> >        int numArgs = 0;
> >        if (Look != ')')  {
> >            numArgs++; 
> >            Expression();
> >        }
> >        while (Look == ',') {
> >            Match(',');
> >            Expression();
> >            numArgs++;
> >        }
> >        return numArgs;
> >    }
> >
> >   /** Parse and Translate a Math Factor  */
> >    private void Factor() {
> >        if (Look == '(' ) {
> >            Match('(');
> >            //tokens.add(new ParenthesisPtg());
> >            Expression();
> >            Match(')');
> >            //tokens.add(new ParenthesisPtg());
> >            return;
> >        } else if (IsAlpha(Look)){
> >            Ident();
> >        }else{
> >            //EmitLn("MOVE #" + GetNum() + ",D0");
> >            IntPtg p = new IntPtg();
> >            p.setValue(Short.parseShort(GetNum()));
> >            tokens.add(p);
> >        }
> >    }
> >
> >    
> >    /** Recognize and Translate a Multiply */
> >    private void Multiply(){
> >        Match('*');
> >        Factor();
> >        tokens.add(new MultiplyPtg());
> >        //EmitLn("MULS (SP)+,D0");
> >    }
> >    
> >    
> >    /** Recognize and Translate a Divide */
> >    private void Divide() {
> >        Match('/');
> >        Factor();
> >        tokens.add(new DividePtg());
> >        //EmitLn("MOVE (SP)+,D1");
> >        //EmitLn("EXS.L D0");
> >        //EmitLn("DIVS D1,D0");
> >    }
> >    
> >    
> >    /** Parse and Translate a Math Term */
> >    private void  Term(){
> >        Factor();
> >        while (Look == '*' || Look == '/' ) {
> >            //EmitLn("MOVE D0,-(SP)");
> >            ///TODO do we need to do anything here??
> >            if (Look == '*') Multiply();
> >            if (Look == '/') Divide();
> >        }
> >    }
> >    
> >    /** Recognize and Translate an Add */
> >    private void Add() {
> >        Match('+');
> >        Term();
> >        tokens.add(new AddPtg());
> >    }
> >    
> >    
> >    /** Recognize and Translate a Subtract */
> >    private void Subtract() {
> >        Match('-');
> >        Term();
> >        tokens.add(new SubtractPtg());
> >    }
> >    
> >    
> >    /** Parse and Translate an Expression */
> >    private void Expression() {
> >        if (IsAddop(Look)) {
> >            EmitLn("CLR D0");  //unaryAdd ptg???
> >        } else {
> >            Term();
> >        }
> >        while (IsAddop(Look)) {
> >            if ( Look == '+' )  Add();
> >            if (Look == '-') Subtract();
> >            // if (Look == '*') Multiply();
> >           // if (Look == '/') Divide();
> >        }
> >    }
> >    
> >    
> >    //{--------------------------------------------------------------}
> >    //{ 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();
> >        }
> >    }
> >    
> >    /** API call to retrive the array of Ptgs created as 
> >     * a result of the parsing
> >     */
> >    public Ptg[] getRPNPtg() {
> >       synchronized (tokens) {
> >            if (tokens == null) throw new IllegalStateException("Please
> parse a string before trying to access the parse result");
> >            Ptg[] retval = new Ptg[tokens.size()];
> >            return (Ptg[]) tokens.toArray(retval);
> >       }
> >    }
> >    
> >    /** Static method to convert an array of Ptgs in RPN order 
> >     *  to a human readable string format in infix mode
> >     *  TODO - extra brackets might appear, but string will be semantically
> correct. 
> >     */
> >    public static String toFormulaString(Ptg[] ptgs) {
> >        java.util.Stack stack = new java.util.Stack();
> >        int numPtgs = ptgs.length;
> >        OperationPtg o;
> >        int numOperands;
> >        String[] operands;
> >        for (int i=0;i<numPtgs;i++) {
> >            if (ptgs[i] instanceof OperationPtg) {
> >                o = (OperationPtg) ptgs[i];
> >                numOperands = o.getNumberOfOperands();
> >                operands = new String[numOperands];
> >                for (int j=0;j<numOperands;j++) {
> >                    operands[numOperands-j-1] = (String) stack.pop();
> //TODO: catch stack underflow and throw parse exception. 
> >                    
> >                }  
> >                String result = o.toFormulaString(operands);
> >                if (! (o instanceof DummyFunctionPtg) ) result =
> "("+result+")" ;
> >                stack.push(result);
> >            } else {
> >                stack.push(ptgs[i].toFormulaString());
> >            }
> >        }
> >        return (String) stack.pop(); //TODO: catch stack underflow and throw
> parse exception. 
> >    }
> >   
> >    public String toString() {
> >        StringBuffer buf = new StringBuffer();
> >           for (int i=0;i<tokens.size();i++) {
> >            buf.append( ( (Ptg)tokens.get(i)).toFormulaString());
> >            buf.append(' ');
> >        } 
> >        return buf.toString();
> >    }
> >    
> >    
> >    /** Main Program for testing*/
> >    public static void main(String[] argv) {
> >        FormulaParser fp = new FormulaParser(argv[0]+";");
> >        System.out.println("\nFormula is: ");
> >        fp.parse();
> >        System.out.println("RPN Form is: " +fp.toString());
> >        
> >        System.out.println("Converted Text form is :
> "+fp.toFormulaString(fp.getRPNPtg()));
> >        
> >        //If Look <> CR then Expected('NewLine');
> >    }
> >    
> >} 
> >
> 
> 
> 
> 


Reply via email to