* parse a given string into known Ptg operators
* @param s
* @return
*/
private static CompatibleVector parsePtgOperators(String s, boolean bUnary) {
CompatibleVector ret= new CompatibleVector();
s= StringTool.allTrim(s);
for (int i=0;i<XLSRecordFactory.ptgOps.length; i++){
String ptgOpStr= XLSRecordFactory.ptgOps[i][0];
if (s.startsWith("\"") || s.startsWith("'")) {
int end = s.substring(1).indexOf(s.charAt(0));
end += 1; //include trailing quote
// TEST IF The quoted item is a sheet name
if (end < s.length() && s.charAt(end)=='!') {// then it's part of a reference
end++;
boolean loop= true;
while (end < s.length() && loop) { // if the quoted string is a sheet ref, get rest of reference
char c= s.charAt(end);
if (c=='#' && s.endsWith("#REF!")) {
end+=5;
loop= false;
} else if (!(Character.isLetterOrDigit(c) || c==':' || c=='$') || c=='-' || c=='+') {
loop= false;
} else
end++;
}
}
ret.add(s.substring(0, end+1));
s= s.substring(end+1);
bUnary= false;
if (!s.equals(""))
ret.addAll(parsePtgOperators(s, bUnary));
break;
}
int x = s.indexOf(ptgOpStr);
if(x>-1) { // found instance of an operator
// if encounter a parenthesis, must determine if it is an expression limit OR
// if it is part of a complex range, in which case the expression must be kept together
if (ptgOpStr.equals("(")) {
int end = getMatchOperator(s, x, '(', ')');
ret.add(s); // add entire
break;
/* String ss= s.substring(x, end+1);
ret.add(ss.substring(x)); // add entire
if (FormulaParser.isComplexRange(ss)) {
// ret.add(ss.substring(x+1)); // skip beginning paren as screws up later parsing
ret.add(ss.substring(x));
s= s.substring(end+1);
bUnary= false;
if (!s.isEmpty())
ret.addAll(parsePtgOperators(s, bUnary));
break;
}
} else if (ptgOpStr.equals(")")) {
try {
String ss= s.substring(x+1);
char nextChar= ss.charAt(0);
if (nextChar==' ') { // see if there is another operand after the space
ss= ss.trim();
if (ss.length()>0 && ss.matches("[^(a-zA-Z].*")) {
nextChar= ss.charAt(0);
}
}
// complex ranges can contain parentheses in combo with these operators: :, (
if (nextChar==' ' || nextChar==',' || nextChar==':' || nextChar==')')
continue; // keep complex range expression together
} catch (Exception e) { ; }
*/
}
if (ptgOpStr.equals(")")) // parens are there to keep expression together
continue;
if (x > 0) {// process prefix, if any - unary since it's the first operand
// exception here-- error range in the form of "Sheet!#REF! (eg) needs to be kept whole
if (!(XLSRecordFactory.ptgLookup[i][1].equals("PtgErr") && s.charAt(x-1)=='!')) {
ret.addAll(parsePtgOperators(s.substring(0, x), bUnary));
bUnary= false;
}
else { // keep entire error reference together
ptgOpStr= s;
}
}
x= x+ ptgOpStr.length();
if (bUnary) {
// unary ops +, - ... have a diff't Ptg than regular vers of the operator
if(ptgOpStr.equals("-")&&x==1&&ptgOpStr.length()>1)break; //negative number, NOT a unary -
for (int j= 0; j < XLSRecordFactory.ptgPrefixOperators.length; j++) {
if (ptgOpStr.startsWith(XLSRecordFactory.ptgPrefixOperators[j][0].toString())) {
ptgOpStr= XLSRecordFactory.ptgPrefixOperators[j][1].toString();
}
}
}
ret.add(ptgOpStr);
if (x < s.length()) // process suffix, if any
ret.addAll(parsePtgOperators(s.substring(x), true));
break;
}
}
if (ret.isEmpty())
ret.add(s);
return ret;
}