1*d107581fSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*d107581fSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*d107581fSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*d107581fSAndrew Rist * distributed with this work for additional information 6*d107581fSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*d107581fSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*d107581fSAndrew Rist * "License"); you may not use this file except in compliance 9*d107581fSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*d107581fSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*d107581fSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*d107581fSAndrew Rist * software distributed under the License is distributed on an 15*d107581fSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*d107581fSAndrew Rist * KIND, either express or implied. See the License for the 17*d107581fSAndrew Rist * specific language governing permissions and limitations 18*d107581fSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*d107581fSAndrew Rist *************************************************************/ 21*d107581fSAndrew Rist 22*d107581fSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_starmath.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir 28cdf0e10cSrcweir #include <stdio.h> 29cdf0e10cSrcweir 30cdf0e10cSrcweir #define SMDLL 1 31cdf0e10cSrcweir 32cdf0e10cSrcweir #include <com/sun/star/i18n/UnicodeType.hpp> 33cdf0e10cSrcweir #include <i18npool/lang.h> 34cdf0e10cSrcweir #include <unotools/charclass.hxx> 35cdf0e10cSrcweir #include <editeng/unolingu.hxx> 36cdf0e10cSrcweir #include <unotools/syslocale.hxx> 37cdf0e10cSrcweir #include "parse.hxx" 38cdf0e10cSrcweir #ifndef _STARMATH_HRC 39cdf0e10cSrcweir #include "starmath.hrc" 40cdf0e10cSrcweir #endif 41cdf0e10cSrcweir #ifndef _SMDLL_HXX 42cdf0e10cSrcweir #include "smdll.hxx" 43cdf0e10cSrcweir #endif 44cdf0e10cSrcweir #include "smmod.hxx" 45cdf0e10cSrcweir #include "config.hxx" 46cdf0e10cSrcweir 47cdf0e10cSrcweir #include "node.hxx" 48cdf0e10cSrcweir 49cdf0e10cSrcweir using namespace ::com::sun::star; 50cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 51cdf0e10cSrcweir 52cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////// 53cdf0e10cSrcweir 54cdf0e10cSrcweir static inline sal_Bool strnccmp(const String &u1, xub_StrLen nIdx, 55cdf0e10cSrcweir const sal_Char *s2, xub_StrLen nLen) 56cdf0e10cSrcweir { 57cdf0e10cSrcweir return u1.EqualsIgnoreCaseAscii( s2, nIdx, nLen ); 58cdf0e10cSrcweir } 59cdf0e10cSrcweir 60cdf0e10cSrcweir static const sal_Unicode aDelimiterTable[] = 61cdf0e10cSrcweir { 62cdf0e10cSrcweir ' ', '\t', '\n', '\r', '+', '-', '*', '/', '=', '#', 63cdf0e10cSrcweir '%', '\\', '"', '~', '`', '>', '<', '&', '|', '(', 64cdf0e10cSrcweir ')', '{', '}', '[', ']', '^', '_', 65cdf0e10cSrcweir '\0' // end of list symbol 66cdf0e10cSrcweir }; 67cdf0e10cSrcweir 68cdf0e10cSrcweir 69cdf0e10cSrcweir static inline sal_Bool IsDigit( sal_Unicode cChar ) 70cdf0e10cSrcweir { 71cdf0e10cSrcweir return '0' <= cChar && cChar <= '9'; 72cdf0e10cSrcweir } 73cdf0e10cSrcweir 74cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////// 75cdf0e10cSrcweir 76cdf0e10cSrcweir SmToken::SmToken() : 77cdf0e10cSrcweir eType (TUNKNOWN), 78cdf0e10cSrcweir cMathChar ('\0') 79cdf0e10cSrcweir { 80cdf0e10cSrcweir nGroup = nCol = nRow = nLevel = 0; 81cdf0e10cSrcweir } 82cdf0e10cSrcweir 83cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////// 84cdf0e10cSrcweir 85cdf0e10cSrcweir struct SmTokenTableEntry 86cdf0e10cSrcweir { 87cdf0e10cSrcweir const sal_Char* pIdent; 88cdf0e10cSrcweir SmTokenType eType; 89cdf0e10cSrcweir sal_Unicode cMathChar; 90cdf0e10cSrcweir sal_uLong nGroup; 91cdf0e10cSrcweir sal_uInt16 nLevel; 92cdf0e10cSrcweir }; 93cdf0e10cSrcweir 94cdf0e10cSrcweir static const SmTokenTableEntry aTokenTable[] = 95cdf0e10cSrcweir { 96cdf0e10cSrcweir // { "#", TPOUND, '\0', 0, 0 }, 97cdf0e10cSrcweir // { "##", TDPOUND, '\0', 0, 0 }, 98cdf0e10cSrcweir // { "&", TAND, MS_AND, TGPRODUCT, 0 }, 99cdf0e10cSrcweir // { "(", TLPARENT, MS_LPARENT, TGLBRACES, 5 }, //! 5 to continue expression 100cdf0e10cSrcweir // { ")", TRPARENT, MS_RPARENT, TGRBRACES, 0 }, //! 0 to terminate expression 101cdf0e10cSrcweir // { "*", TMULTIPLY, MS_MULTIPLY, TGPRODUCT, 0 }, 102cdf0e10cSrcweir // { "+", TPLUS, MS_PLUS, TGUNOPER | TGSUM, 5 }, 103cdf0e10cSrcweir // { "+-", TPLUSMINUS, MS_PLUSMINUS, TGUNOPER | TGSUM, 5 }, 104cdf0e10cSrcweir // { "-", TMINUS, MS_MINUS, TGUNOPER | TGSUM, 5 }, 105cdf0e10cSrcweir // { "-+", TMINUSPLUS, MS_MINUSPLUS, TGUNOPER | TGSUM, 5 }, 106cdf0e10cSrcweir // { ".", TPOINT, '\0', 0, 0 }, 107cdf0e10cSrcweir // { "/", TDIVIDEBY, MS_SLASH, TGPRODUCT, 0 }, 108cdf0e10cSrcweir // { "<", TLT, MS_LT, TGRELATION, 0 }, 109cdf0e10cSrcweir // { "<<", TLL, MS_LL, TGRELATION, 0 }, 110cdf0e10cSrcweir // { "<=", TLE, MS_LE, TGRELATION, 0 }, 111cdf0e10cSrcweir // { "<>", TNEQ, MS_NEQ, TGRELATION, 0}, 112cdf0e10cSrcweir // { "<?>", TPLACE, MS_PLACE, 0, 5 }, 113cdf0e10cSrcweir // { "=", TASSIGN, MS_ASSIGN, TGRELATION, 0}, 114cdf0e10cSrcweir // { ">", TGT, MS_GT, TGRELATION, 0 }, 115cdf0e10cSrcweir // { ">=", TGE, MS_GE, TGRELATION, 0 }, 116cdf0e10cSrcweir // { ">>", TGG, MS_GG, TGRELATION, 0 }, 117cdf0e10cSrcweir { "Im" , TIM, MS_IM, TGSTANDALONE, 5 }, 118cdf0e10cSrcweir { "MZ23", TDEBUG, '\0', TGATTRIBUT, 0 }, 119cdf0e10cSrcweir { "Re" , TRE, MS_RE, TGSTANDALONE, 5 }, 120cdf0e10cSrcweir { "abs", TABS, '\0', TGUNOPER, 13 }, 121cdf0e10cSrcweir { "arcosh", TACOSH, '\0', TGFUNCTION, 5 }, 122cdf0e10cSrcweir { "arcoth", TACOTH, '\0', TGFUNCTION, 5 }, 123cdf0e10cSrcweir { "acute", TACUTE, MS_ACUTE, TGATTRIBUT, 5 }, 124cdf0e10cSrcweir { "aleph" , TALEPH, MS_ALEPH, TGSTANDALONE, 5 }, 125cdf0e10cSrcweir { "alignb", TALIGNC, '\0', TGALIGN | TGDISCARDED, 0}, 126cdf0e10cSrcweir { "alignc", TALIGNC, '\0', TGALIGN, 0}, 127cdf0e10cSrcweir { "alignl", TALIGNL, '\0', TGALIGN, 0}, 128cdf0e10cSrcweir { "alignm", TALIGNC, '\0', TGALIGN | TGDISCARDED, 0}, 129cdf0e10cSrcweir { "alignr", TALIGNR, '\0', TGALIGN, 0}, 130cdf0e10cSrcweir { "alignt", TALIGNC, '\0', TGALIGN | TGDISCARDED, 0}, 131cdf0e10cSrcweir { "and", TAND, MS_AND, TGPRODUCT, 0}, 132cdf0e10cSrcweir { "approx", TAPPROX, MS_APPROX, TGRELATION, 0}, 133cdf0e10cSrcweir { "arccos", TACOS, '\0', TGFUNCTION, 5}, 134cdf0e10cSrcweir { "arccot", TACOT, '\0', TGFUNCTION, 5}, 135cdf0e10cSrcweir { "arcsin", TASIN, '\0', TGFUNCTION, 5}, 136cdf0e10cSrcweir { "arctan", TATAN, '\0', TGFUNCTION, 5}, 137cdf0e10cSrcweir { "arsinh", TASINH, '\0', TGFUNCTION, 5}, 138cdf0e10cSrcweir { "artanh", TATANH, '\0', TGFUNCTION, 5}, 139cdf0e10cSrcweir { "backepsilon" , TBACKEPSILON, MS_BACKEPSILON, TGSTANDALONE, 5}, 140cdf0e10cSrcweir { "bar", TBAR, MS_BAR, TGATTRIBUT, 5}, 141cdf0e10cSrcweir { "binom", TBINOM, '\0', 0, 5 }, 142cdf0e10cSrcweir { "black", TBLACK, '\0', TGCOLOR, 0}, 143cdf0e10cSrcweir { "blue", TBLUE, '\0', TGCOLOR, 0}, 144cdf0e10cSrcweir { "bold", TBOLD, '\0', TGFONTATTR, 5}, 145cdf0e10cSrcweir { "boper", TBOPER, '\0', TGPRODUCT, 0}, 146cdf0e10cSrcweir { "breve", TBREVE, MS_BREVE, TGATTRIBUT, 5}, 147cdf0e10cSrcweir { "bslash", TBACKSLASH, MS_BACKSLASH, TGPRODUCT, 0 }, 148cdf0e10cSrcweir { "cdot", TCDOT, MS_CDOT, TGPRODUCT, 0}, 149cdf0e10cSrcweir { "check", TCHECK, MS_CHECK, TGATTRIBUT, 5}, 150cdf0e10cSrcweir { "circ" , TCIRC, MS_CIRC, TGSTANDALONE, 5}, 151cdf0e10cSrcweir { "circle", TCIRCLE, MS_CIRCLE, TGATTRIBUT, 5}, 152cdf0e10cSrcweir { "color", TCOLOR, '\0', TGFONTATTR, 5}, 153cdf0e10cSrcweir { "coprod", TCOPROD, MS_COPROD, TGOPER, 5}, 154cdf0e10cSrcweir { "cos", TCOS, '\0', TGFUNCTION, 5}, 155cdf0e10cSrcweir { "cosh", TCOSH, '\0', TGFUNCTION, 5}, 156cdf0e10cSrcweir { "cot", TCOT, '\0', TGFUNCTION, 5}, 157cdf0e10cSrcweir { "coth", TCOTH, '\0', TGFUNCTION, 5}, 158cdf0e10cSrcweir { "csub", TCSUB, '\0', TGPOWER, 0}, 159cdf0e10cSrcweir { "csup", TCSUP, '\0', TGPOWER, 0}, 160cdf0e10cSrcweir { "cyan", TCYAN, '\0', TGCOLOR, 0}, 161cdf0e10cSrcweir { "dddot", TDDDOT, MS_DDDOT, TGATTRIBUT, 5}, 162cdf0e10cSrcweir { "ddot", TDDOT, MS_DDOT, TGATTRIBUT, 5}, 163cdf0e10cSrcweir { "def", TDEF, MS_DEF, TGRELATION, 0}, 164cdf0e10cSrcweir { "div", TDIV, MS_DIV, TGPRODUCT, 0}, 165cdf0e10cSrcweir { "divides", TDIVIDES, MS_LINE, TGRELATION, 0}, 166cdf0e10cSrcweir { "dlarrow" , TDLARROW, MS_DLARROW, TGSTANDALONE, 5}, 167cdf0e10cSrcweir { "dlrarrow" , TDLRARROW, MS_DLRARROW, TGSTANDALONE, 5}, 168cdf0e10cSrcweir { "dot", TDOT, MS_DOT, TGATTRIBUT, 5}, 169cdf0e10cSrcweir { "dotsaxis", TDOTSAXIS, MS_DOTSAXIS, TGSTANDALONE, 5}, // 5 to continue expression 170cdf0e10cSrcweir { "dotsdiag", TDOTSDIAG, MS_DOTSUP, TGSTANDALONE, 5}, // 171cdf0e10cSrcweir { "dotsdown", TDOTSDOWN, MS_DOTSDOWN, TGSTANDALONE, 5}, // 172cdf0e10cSrcweir { "dotslow", TDOTSLOW, MS_DOTSLOW, TGSTANDALONE, 5}, // 173cdf0e10cSrcweir { "dotsup", TDOTSUP, MS_DOTSUP, TGSTANDALONE, 5}, // 174cdf0e10cSrcweir { "dotsvert", TDOTSVERT, MS_DOTSVERT, TGSTANDALONE, 5}, // 175cdf0e10cSrcweir { "downarrow" , TDOWNARROW, MS_DOWNARROW, TGSTANDALONE, 5}, 176cdf0e10cSrcweir { "drarrow" , TDRARROW, MS_DRARROW, TGSTANDALONE, 5}, 177cdf0e10cSrcweir { "emptyset" , TEMPTYSET, MS_EMPTYSET, TGSTANDALONE, 5}, 178cdf0e10cSrcweir { "equiv", TEQUIV, MS_EQUIV, TGRELATION, 0}, 179cdf0e10cSrcweir { "exists", TEXISTS, MS_EXISTS, TGSTANDALONE, 5}, 180cdf0e10cSrcweir { "exp", TEXP, '\0', TGFUNCTION, 5}, 181cdf0e10cSrcweir { "fact", TFACT, MS_FACT, TGUNOPER, 5}, 182cdf0e10cSrcweir { "fixed", TFIXED, '\0', TGFONT, 0}, 183cdf0e10cSrcweir { "font", TFONT, '\0', TGFONTATTR, 5}, 184cdf0e10cSrcweir { "forall", TFORALL, MS_FORALL, TGSTANDALONE, 5}, 185cdf0e10cSrcweir { "from", TFROM, '\0', TGLIMIT, 0}, 186cdf0e10cSrcweir { "func", TFUNC, '\0', TGFUNCTION, 5}, 187cdf0e10cSrcweir { "ge", TGE, MS_GE, TGRELATION, 0}, 188cdf0e10cSrcweir { "geslant", TGESLANT, MS_GESLANT, TGRELATION, 0 }, 189cdf0e10cSrcweir { "gg", TGG, MS_GG, TGRELATION, 0}, 190cdf0e10cSrcweir { "grave", TGRAVE, MS_GRAVE, TGATTRIBUT, 5}, 191cdf0e10cSrcweir { "green", TGREEN, '\0', TGCOLOR, 0}, 192cdf0e10cSrcweir { "gt", TGT, MS_GT, TGRELATION, 0}, 193cdf0e10cSrcweir { "hat", THAT, MS_HAT, TGATTRIBUT, 5}, 194cdf0e10cSrcweir { "hbar" , THBAR, MS_HBAR, TGSTANDALONE, 5}, 195cdf0e10cSrcweir { "iiint", TIIINT, MS_IIINT, TGOPER, 5}, 196cdf0e10cSrcweir { "iint", TIINT, MS_IINT, TGOPER, 5}, 197cdf0e10cSrcweir { "in", TIN, MS_IN, TGRELATION, 0}, 198cdf0e10cSrcweir { "infinity" , TINFINITY, MS_INFINITY, TGSTANDALONE, 5}, 199cdf0e10cSrcweir { "infty" , TINFINITY, MS_INFINITY, TGSTANDALONE, 5}, 200cdf0e10cSrcweir { "int", TINT, MS_INT, TGOPER, 5}, 201cdf0e10cSrcweir { "intersection", TINTERSECT, MS_INTERSECT, TGPRODUCT, 0}, 202cdf0e10cSrcweir { "ital", TITALIC, '\0', TGFONTATTR, 5}, 203cdf0e10cSrcweir { "italic", TITALIC, '\0', TGFONTATTR, 5}, 204cdf0e10cSrcweir { "lambdabar" , TLAMBDABAR, MS_LAMBDABAR, TGSTANDALONE, 5}, 205cdf0e10cSrcweir { "langle", TLANGLE, MS_LANGLE, TGLBRACES, 5}, 206cdf0e10cSrcweir { "lbrace", TLBRACE, MS_LBRACE, TGLBRACES, 5}, 207cdf0e10cSrcweir { "lceil", TLCEIL, MS_LCEIL, TGLBRACES, 5}, 208cdf0e10cSrcweir { "ldbracket", TLDBRACKET, MS_LDBRACKET, TGLBRACES, 5}, 209cdf0e10cSrcweir { "ldline", TLDLINE, MS_DLINE, TGLBRACES, 5}, 210cdf0e10cSrcweir { "le", TLE, MS_LE, TGRELATION, 0}, 211cdf0e10cSrcweir { "left", TLEFT, '\0', 0, 5}, 212cdf0e10cSrcweir { "leftarrow" , TLEFTARROW, MS_LEFTARROW, TGSTANDALONE, 5}, 213cdf0e10cSrcweir { "leslant", TLESLANT, MS_LESLANT, TGRELATION, 0 }, 214cdf0e10cSrcweir { "lfloor", TLFLOOR, MS_LFLOOR, TGLBRACES, 5}, 215cdf0e10cSrcweir { "lim", TLIM, '\0', TGOPER, 5}, 216cdf0e10cSrcweir { "liminf", TLIMINF, '\0', TGOPER, 5}, 217cdf0e10cSrcweir { "limsup", TLIMSUP, '\0', TGOPER, 5}, 218cdf0e10cSrcweir { "lint", TLINT, MS_LINT, TGOPER, 5}, 219cdf0e10cSrcweir { "ll", TLL, MS_LL, TGRELATION, 0}, 220cdf0e10cSrcweir { "lline", TLLINE, MS_LINE, TGLBRACES, 5}, 221cdf0e10cSrcweir { "llint", TLLINT, MS_LLINT, TGOPER, 5}, 222cdf0e10cSrcweir { "lllint", TLLLINT, MS_LLLINT, TGOPER, 5}, 223cdf0e10cSrcweir { "ln", TLN, '\0', TGFUNCTION, 5}, 224cdf0e10cSrcweir { "log", TLOG, '\0', TGFUNCTION, 5}, 225cdf0e10cSrcweir { "lsub", TLSUB, '\0', TGPOWER, 0}, 226cdf0e10cSrcweir { "lsup", TLSUP, '\0', TGPOWER, 0}, 227cdf0e10cSrcweir { "lt", TLT, MS_LT, TGRELATION, 0}, 228cdf0e10cSrcweir { "magenta", TMAGENTA, '\0', TGCOLOR, 0}, 229cdf0e10cSrcweir { "matrix", TMATRIX, '\0', 0, 5}, 230cdf0e10cSrcweir { "minusplus", TMINUSPLUS, MS_MINUSPLUS, TGUNOPER | TGSUM, 5}, 231cdf0e10cSrcweir { "mline", TMLINE, MS_LINE, 0, 0}, //! nicht in TGRBRACES, Level 0 232cdf0e10cSrcweir { "nabla", TNABLA, MS_NABLA, TGSTANDALONE, 5}, 233cdf0e10cSrcweir { "nbold", TNBOLD, '\0', TGFONTATTR, 5}, 234cdf0e10cSrcweir { "ndivides", TNDIVIDES, MS_NDIVIDES, TGRELATION, 0}, 235cdf0e10cSrcweir { "neg", TNEG, MS_NEG, TGUNOPER, 5 }, 236cdf0e10cSrcweir { "neq", TNEQ, MS_NEQ, TGRELATION, 0}, 237cdf0e10cSrcweir { "newline", TNEWLINE, '\0', 0, 0}, 238cdf0e10cSrcweir { "ni", TNI, MS_NI, TGRELATION, 0}, 239cdf0e10cSrcweir { "nitalic", TNITALIC, '\0', TGFONTATTR, 5}, 240cdf0e10cSrcweir { "none", TNONE, '\0', TGLBRACES | TGRBRACES, 0}, 241cdf0e10cSrcweir { "nospace", TNOSPACE, '\0', TGSTANDALONE, 5}, 242cdf0e10cSrcweir { "notin", TNOTIN, MS_NOTIN, TGRELATION, 0}, 243cdf0e10cSrcweir { "nroot", TNROOT, MS_SQRT, TGUNOPER, 5}, 244cdf0e10cSrcweir { "nsubset", TNSUBSET, MS_NSUBSET, TGRELATION, 0 }, 245cdf0e10cSrcweir { "nsupset", TNSUPSET, MS_NSUPSET, TGRELATION, 0 }, 246cdf0e10cSrcweir { "nsubseteq", TNSUBSETEQ, MS_NSUBSETEQ, TGRELATION, 0 }, 247cdf0e10cSrcweir { "nsupseteq", TNSUPSETEQ, MS_NSUPSETEQ, TGRELATION, 0 }, 248cdf0e10cSrcweir { "odivide", TODIVIDE, MS_ODIVIDE, TGPRODUCT, 0}, 249cdf0e10cSrcweir { "odot", TODOT, MS_ODOT, TGPRODUCT, 0}, 250cdf0e10cSrcweir { "ominus", TOMINUS, MS_OMINUS, TGSUM, 0}, 251cdf0e10cSrcweir { "oper", TOPER, '\0', TGOPER, 5}, 252cdf0e10cSrcweir { "oplus", TOPLUS, MS_OPLUS, TGSUM, 0}, 253cdf0e10cSrcweir { "or", TOR, MS_OR, TGSUM, 0}, 254cdf0e10cSrcweir { "ortho", TORTHO, MS_ORTHO, TGRELATION, 0}, 255cdf0e10cSrcweir { "otimes", TOTIMES, MS_OTIMES, TGPRODUCT, 0}, 256cdf0e10cSrcweir { "over", TOVER, '\0', TGPRODUCT, 0}, 257cdf0e10cSrcweir { "overbrace", TOVERBRACE, MS_OVERBRACE, TGPRODUCT, 5}, 258cdf0e10cSrcweir { "overline", TOVERLINE, '\0', TGATTRIBUT, 5}, 259cdf0e10cSrcweir { "overstrike", TOVERSTRIKE, '\0', TGATTRIBUT, 5}, 260cdf0e10cSrcweir { "owns", TNI, MS_NI, TGRELATION, 0}, 261cdf0e10cSrcweir { "parallel", TPARALLEL, MS_DLINE, TGRELATION, 0}, 262cdf0e10cSrcweir { "partial", TPARTIAL, MS_PARTIAL, TGSTANDALONE, 5 }, 263cdf0e10cSrcweir { "phantom", TPHANTOM, '\0', TGFONTATTR, 5}, 264cdf0e10cSrcweir { "plusminus", TPLUSMINUS, MS_PLUSMINUS, TGUNOPER | TGSUM, 5}, 265cdf0e10cSrcweir { "prod", TPROD, MS_PROD, TGOPER, 5}, 266cdf0e10cSrcweir { "prop", TPROP, MS_PROP, TGRELATION, 0}, 267cdf0e10cSrcweir { "rangle", TRANGLE, MS_RANGLE, TGRBRACES, 0}, //! 0 to terminate expression 268cdf0e10cSrcweir { "rbrace", TRBRACE, MS_RBRACE, TGRBRACES, 0}, // 269cdf0e10cSrcweir { "rceil", TRCEIL, MS_RCEIL, TGRBRACES, 0}, // 270cdf0e10cSrcweir { "rdbracket", TRDBRACKET, MS_RDBRACKET, TGRBRACES, 0}, // 271cdf0e10cSrcweir { "rdline", TRDLINE, MS_DLINE, TGRBRACES, 0}, // 272cdf0e10cSrcweir { "red", TRED, '\0', TGCOLOR, 0}, 273cdf0e10cSrcweir { "rfloor", TRFLOOR, MS_RFLOOR, TGRBRACES, 0}, //! 0 to terminate expression 274cdf0e10cSrcweir { "right", TRIGHT, '\0', 0, 0}, 275cdf0e10cSrcweir { "rightarrow" , TRIGHTARROW, MS_RIGHTARROW, TGSTANDALONE, 5}, 276cdf0e10cSrcweir { "rline", TRLINE, MS_LINE, TGRBRACES, 0}, //! 0 to terminate expression 277cdf0e10cSrcweir { "rsub", TRSUB, '\0', TGPOWER, 0}, 278cdf0e10cSrcweir { "rsup", TRSUP, '\0', TGPOWER, 0}, 279cdf0e10cSrcweir { "sans", TSANS, '\0', TGFONT, 0}, 280cdf0e10cSrcweir { "serif", TSERIF, '\0', TGFONT, 0}, 281cdf0e10cSrcweir { "setC" , TSETC, MS_SETC, TGSTANDALONE, 5}, 282cdf0e10cSrcweir { "setN" , TSETN, MS_SETN, TGSTANDALONE, 5}, 283cdf0e10cSrcweir { "setQ" , TSETQ, MS_SETQ, TGSTANDALONE, 5}, 284cdf0e10cSrcweir { "setR" , TSETR, MS_SETR, TGSTANDALONE, 5}, 285cdf0e10cSrcweir { "setZ" , TSETZ, MS_SETZ, TGSTANDALONE, 5}, 286cdf0e10cSrcweir { "setminus", TBACKSLASH, MS_BACKSLASH, TGPRODUCT, 0 }, 287cdf0e10cSrcweir { "sim", TSIM, MS_SIM, TGRELATION, 0}, 288cdf0e10cSrcweir { "simeq", TSIMEQ, MS_SIMEQ, TGRELATION, 0}, 289cdf0e10cSrcweir { "sin", TSIN, '\0', TGFUNCTION, 5}, 290cdf0e10cSrcweir { "sinh", TSINH, '\0', TGFUNCTION, 5}, 291cdf0e10cSrcweir { "size", TSIZE, '\0', TGFONTATTR, 5}, 292cdf0e10cSrcweir { "slash", TSLASH, MS_SLASH, TGPRODUCT, 0 }, 293cdf0e10cSrcweir { "sqrt", TSQRT, MS_SQRT, TGUNOPER, 5}, 294cdf0e10cSrcweir { "stack", TSTACK, '\0', 0, 5}, 295cdf0e10cSrcweir { "sub", TRSUB, '\0', TGPOWER, 0}, 296cdf0e10cSrcweir { "subset", TSUBSET, MS_SUBSET, TGRELATION, 0}, 297cdf0e10cSrcweir { "subseteq", TSUBSETEQ, MS_SUBSETEQ, TGRELATION, 0}, 298cdf0e10cSrcweir { "sum", TSUM, MS_SUM, TGOPER, 5}, 299cdf0e10cSrcweir { "sup", TRSUP, '\0', TGPOWER, 0}, 300cdf0e10cSrcweir { "supset", TSUPSET, MS_SUPSET, TGRELATION, 0}, 301cdf0e10cSrcweir { "supseteq", TSUPSETEQ, MS_SUPSETEQ, TGRELATION, 0}, 302cdf0e10cSrcweir { "tan", TTAN, '\0', TGFUNCTION, 5}, 303cdf0e10cSrcweir { "tanh", TTANH, '\0', TGFUNCTION, 5}, 304cdf0e10cSrcweir { "tilde", TTILDE, MS_TILDE, TGATTRIBUT, 5}, 305cdf0e10cSrcweir { "times", TTIMES, MS_TIMES, TGPRODUCT, 0}, 306cdf0e10cSrcweir { "to", TTO, '\0', TGLIMIT, 0}, 307cdf0e10cSrcweir { "toward", TTOWARD, MS_RIGHTARROW, TGRELATION, 0}, 308cdf0e10cSrcweir { "transl", TTRANSL, MS_TRANSL, TGRELATION, 0}, 309cdf0e10cSrcweir { "transr", TTRANSR, MS_TRANSR, TGRELATION, 0}, 310cdf0e10cSrcweir { "underbrace", TUNDERBRACE, MS_UNDERBRACE, TGPRODUCT, 5}, 311cdf0e10cSrcweir { "underline", TUNDERLINE, '\0', TGATTRIBUT, 5}, 312cdf0e10cSrcweir { "union", TUNION, MS_UNION, TGSUM, 0}, 313cdf0e10cSrcweir { "uoper", TUOPER, '\0', TGUNOPER, 5}, 314cdf0e10cSrcweir { "uparrow" , TUPARROW, MS_UPARROW, TGSTANDALONE, 5}, 315cdf0e10cSrcweir { "vec", TVEC, MS_VEC, TGATTRIBUT, 5}, 316cdf0e10cSrcweir { "white", TWHITE, '\0', TGCOLOR, 0}, 317cdf0e10cSrcweir { "widebslash", TWIDEBACKSLASH, MS_BACKSLASH, TGPRODUCT, 0 }, 318cdf0e10cSrcweir { "widehat", TWIDEHAT, MS_HAT, TGATTRIBUT, 5}, 319cdf0e10cSrcweir { "widetilde", TWIDETILDE, MS_TILDE, TGATTRIBUT, 5}, 320cdf0e10cSrcweir { "wideslash", TWIDESLASH, MS_SLASH, TGPRODUCT, 0 }, 321cdf0e10cSrcweir { "widevec", TWIDEVEC, MS_VEC, TGATTRIBUT, 5}, 322cdf0e10cSrcweir { "wp" , TWP, MS_WP, TGSTANDALONE, 5}, 323cdf0e10cSrcweir { "yellow", TYELLOW, '\0', TGCOLOR, 0}, 324cdf0e10cSrcweir // { "[", TLBRACKET, MS_LBRACKET, TGLBRACES, 5}, //! 5 to continue expression 325cdf0e10cSrcweir // { "\\", TESCAPE, '\0', 0, 5}, 326cdf0e10cSrcweir // { "]", TRBRACKET, MS_RBRACKET, TGRBRACES, 0}, //! 0 to terminate expression 327cdf0e10cSrcweir // { "^", TRSUP, '\0', TGPOWER, 0}, 328cdf0e10cSrcweir // { "_", TRSUB, '\0', TGPOWER, 0}, 329cdf0e10cSrcweir // { "`", TSBLANK, '\0', TGBLANK, 5}, 330cdf0e10cSrcweir // { "{", TLGROUP, MS_LBRACE, 0, 5}, //! 5 to continue expression 331cdf0e10cSrcweir // { "|", TOR, MS_OR, TGSUM, 0}, 332cdf0e10cSrcweir // { "}", TRGROUP, MS_RBRACE, 0, 0}, //! 0 to terminate expression 333cdf0e10cSrcweir // { "~", TBLANK, '\0', TGBLANK, 5}, 334cdf0e10cSrcweir { "", TEND, '\0', 0, 0} 335cdf0e10cSrcweir }; 336cdf0e10cSrcweir 337cdf0e10cSrcweir 338cdf0e10cSrcweir static const SmTokenTableEntry * GetTokenTableEntry( const String &rName ) 339cdf0e10cSrcweir { 340cdf0e10cSrcweir const SmTokenTableEntry * pRes = 0; 341cdf0e10cSrcweir if (rName.Len()) 342cdf0e10cSrcweir { 343cdf0e10cSrcweir sal_Int32 nEntries = sizeof( aTokenTable ) / sizeof( aTokenTable[0] ); 344cdf0e10cSrcweir for (sal_Int32 i = 0; i < nEntries; ++i) 345cdf0e10cSrcweir { 346cdf0e10cSrcweir if (rName.EqualsIgnoreCaseAscii( aTokenTable[i].pIdent )) 347cdf0e10cSrcweir { 348cdf0e10cSrcweir pRes = &aTokenTable[i]; 349cdf0e10cSrcweir break; 350cdf0e10cSrcweir } 351cdf0e10cSrcweir } 352cdf0e10cSrcweir 353cdf0e10cSrcweir } 354cdf0e10cSrcweir 355cdf0e10cSrcweir return pRes; 356cdf0e10cSrcweir } 357cdf0e10cSrcweir 358cdf0e10cSrcweir 359cdf0e10cSrcweir /////////////////////////////////////////////////////////////////////////// 360cdf0e10cSrcweir 361cdf0e10cSrcweir #if OSL_DEBUG_LEVEL 362cdf0e10cSrcweir 363cdf0e10cSrcweir sal_Bool SmParser::IsDelimiter( const String &rTxt, xub_StrLen nPos ) 364cdf0e10cSrcweir // returns 'sal_True' iff cChar is '\0' or a delimeter 365cdf0e10cSrcweir { 366cdf0e10cSrcweir DBG_ASSERT( nPos <= rTxt.Len(), "index out of range" ); 367cdf0e10cSrcweir 368cdf0e10cSrcweir sal_Unicode cChar = rTxt.GetChar( nPos ); 369cdf0e10cSrcweir if(!cChar) 370cdf0e10cSrcweir return sal_True; 371cdf0e10cSrcweir 372cdf0e10cSrcweir // check if 'cChar' is in the delimeter table 373cdf0e10cSrcweir const sal_Unicode *pDelim = &aDelimiterTable[0]; 374cdf0e10cSrcweir for ( ; *pDelim != 0; pDelim++) 375cdf0e10cSrcweir if (*pDelim == cChar) 376cdf0e10cSrcweir break; 377cdf0e10cSrcweir 378cdf0e10cSrcweir sal_Bool bIsDelim = *pDelim != 0; 379cdf0e10cSrcweir 380cdf0e10cSrcweir sal_Int16 nTypJp = SM_MOD()->GetSysLocale().GetCharClass().getType( rTxt, nPos ); 381cdf0e10cSrcweir bIsDelim |= nTypJp == com::sun::star::i18n::UnicodeType::SPACE_SEPARATOR || 382cdf0e10cSrcweir nTypJp == com::sun::star::i18n::UnicodeType::CONTROL; 383cdf0e10cSrcweir 384cdf0e10cSrcweir return bIsDelim; 385cdf0e10cSrcweir } 386cdf0e10cSrcweir 387cdf0e10cSrcweir #endif 388cdf0e10cSrcweir 389cdf0e10cSrcweir void SmParser::Insert(const String &rText, sal_uInt16 nPos) 390cdf0e10cSrcweir { 391cdf0e10cSrcweir m_aBufferString.Insert(rText, nPos); 392cdf0e10cSrcweir 393cdf0e10cSrcweir xub_StrLen nLen = rText.Len(); 394cdf0e10cSrcweir m_nBufferIndex = m_nBufferIndex + nLen; 395cdf0e10cSrcweir m_nTokenIndex = m_nTokenIndex + nLen; 396cdf0e10cSrcweir } 397cdf0e10cSrcweir 398cdf0e10cSrcweir 399cdf0e10cSrcweir void SmParser::Replace( sal_uInt16 nPos, sal_uInt16 nLen, const String &rText ) 400cdf0e10cSrcweir { 401cdf0e10cSrcweir DBG_ASSERT( nPos + nLen <= m_aBufferString.Len(), "argument mismatch" ); 402cdf0e10cSrcweir 403cdf0e10cSrcweir m_aBufferString.Replace( nPos, nLen, rText ); 404cdf0e10cSrcweir sal_Int16 nChg = rText.Len() - nLen; 405cdf0e10cSrcweir m_nBufferIndex = m_nBufferIndex + nChg; 406cdf0e10cSrcweir m_nTokenIndex = m_nTokenIndex + nChg; 407cdf0e10cSrcweir } 408cdf0e10cSrcweir 409cdf0e10cSrcweir 410cdf0e10cSrcweir // First character may be any alphabetic 411cdf0e10cSrcweir const sal_Int32 coStartFlags = 412cdf0e10cSrcweir KParseTokens::ANY_LETTER_OR_NUMBER | 413cdf0e10cSrcweir KParseTokens::IGNORE_LEADING_WS; 414cdf0e10cSrcweir 415cdf0e10cSrcweir // Continuing characters may be any alphanumeric or dot. 416cdf0e10cSrcweir const sal_Int32 coContFlags = 417cdf0e10cSrcweir ((coStartFlags | KParseTokens::ASC_DOT) & ~KParseTokens::IGNORE_LEADING_WS) 418cdf0e10cSrcweir | KParseTokens::TWO_DOUBLE_QUOTES_BREAK_STRING; 419cdf0e10cSrcweir 420cdf0e10cSrcweir // First character for numbers, may be any numeric or dot 421cdf0e10cSrcweir const sal_Int32 coNumStartFlags = 422cdf0e10cSrcweir KParseTokens::ASC_DIGIT | 423cdf0e10cSrcweir KParseTokens::ASC_DOT | 424cdf0e10cSrcweir KParseTokens::IGNORE_LEADING_WS; 425cdf0e10cSrcweir // Continuing characters for numbers, may be any numeric or dot. 426cdf0e10cSrcweir const sal_Int32 coNumContFlags = 427cdf0e10cSrcweir (coNumStartFlags | KParseTokens::ASC_DOT) & ~KParseTokens::IGNORE_LEADING_WS; 428cdf0e10cSrcweir 429cdf0e10cSrcweir void SmParser::NextToken() 430cdf0e10cSrcweir { 431cdf0e10cSrcweir static const String aEmptyStr; 432cdf0e10cSrcweir 433cdf0e10cSrcweir xub_StrLen nBufLen = m_aBufferString.Len(); 434cdf0e10cSrcweir ParseResult aRes; 435cdf0e10cSrcweir xub_StrLen nRealStart; 436cdf0e10cSrcweir sal_Bool bCont; 437cdf0e10cSrcweir sal_Bool bNumStart = sal_False; 438cdf0e10cSrcweir CharClass aCC(SM_MOD()->GetSysLocale().GetCharClass().getLocale()); 439cdf0e10cSrcweir do 440cdf0e10cSrcweir { 441cdf0e10cSrcweir // skip white spaces 442cdf0e10cSrcweir while (UnicodeType::SPACE_SEPARATOR == 443cdf0e10cSrcweir aCC.getType( m_aBufferString, m_nBufferIndex )) 444cdf0e10cSrcweir ++m_nBufferIndex; 445cdf0e10cSrcweir 446cdf0e10cSrcweir sal_Int32 nStartFlags = coStartFlags; 447cdf0e10cSrcweir sal_Int32 nContFlags = coContFlags; 448cdf0e10cSrcweir sal_Unicode cFirstChar = m_aBufferString.GetChar( m_nBufferIndex ); 449cdf0e10cSrcweir /* 450cdf0e10cSrcweir removed because of #i11752# 451cdf0e10cSrcweir bNumStart = cFirstChar == '.' || ('0' <= cFirstChar && cFirstChar <= '9'); 452cdf0e10cSrcweir if (bNumStart) 453cdf0e10cSrcweir { 454cdf0e10cSrcweir nStartFlags = coNumStartFlags; 455cdf0e10cSrcweir nContFlags = coNumContFlags; 456cdf0e10cSrcweir } 457cdf0e10cSrcweir */ 458cdf0e10cSrcweir aRes = aCC.parseAnyToken( m_aBufferString, m_nBufferIndex, 459cdf0e10cSrcweir nStartFlags, aEmptyStr, 460cdf0e10cSrcweir nContFlags, aEmptyStr ); 461cdf0e10cSrcweir 462cdf0e10cSrcweir // #i45779# parse numbers correctly 463cdf0e10cSrcweir // i.e. independent from the locale setting. 464cdf0e10cSrcweir // (note that #i11752# remains fixed) 465cdf0e10cSrcweir if ((aRes.TokenType & KParseType::IDENTNAME) && IsDigit( cFirstChar )) 466cdf0e10cSrcweir { 467cdf0e10cSrcweir //! locale where '.' is decimal seperator! 468cdf0e10cSrcweir static lang::Locale aDotLoc( SvxCreateLocale( LANGUAGE_ENGLISH_US ) ); 469cdf0e10cSrcweir 470cdf0e10cSrcweir ParseResult aTmpRes; 471cdf0e10cSrcweir lang::Locale aOldLoc( aCC.getLocale() ); 472cdf0e10cSrcweir aCC.setLocale( aDotLoc ); 473cdf0e10cSrcweir aTmpRes = aCC.parsePredefinedToken( 474cdf0e10cSrcweir KParseType::ASC_NUMBER, 475cdf0e10cSrcweir m_aBufferString, m_nBufferIndex, 476cdf0e10cSrcweir KParseTokens::ASC_DIGIT, aEmptyStr, 477cdf0e10cSrcweir KParseTokens::ASC_DIGIT | KParseTokens::ASC_DOT, aEmptyStr ); 478cdf0e10cSrcweir aCC.setLocale( aOldLoc ); 479cdf0e10cSrcweir if (aTmpRes.TokenType & KParseType::ASC_NUMBER) 480cdf0e10cSrcweir aRes.TokenType = aTmpRes.TokenType; 481cdf0e10cSrcweir } 482cdf0e10cSrcweir 483cdf0e10cSrcweir nRealStart = m_nBufferIndex + sal::static_int_cast< xub_StrLen >(aRes.LeadingWhiteSpace); 484cdf0e10cSrcweir m_nBufferIndex = nRealStart; 485cdf0e10cSrcweir 486cdf0e10cSrcweir bCont = sal_False; 487cdf0e10cSrcweir if ( aRes.TokenType == 0 && 488cdf0e10cSrcweir nRealStart < nBufLen && 489cdf0e10cSrcweir '\n' == m_aBufferString.GetChar( nRealStart ) ) 490cdf0e10cSrcweir { 491cdf0e10cSrcweir // keep data needed for tokens row and col entry up to date 492cdf0e10cSrcweir ++m_Row; 493cdf0e10cSrcweir m_nBufferIndex = m_nColOff = nRealStart + 1; 494cdf0e10cSrcweir bCont = sal_True; 495cdf0e10cSrcweir } 496cdf0e10cSrcweir else if (aRes.TokenType & KParseType::ONE_SINGLE_CHAR) 497cdf0e10cSrcweir { 498cdf0e10cSrcweir String aName( m_aBufferString.Copy( nRealStart, 2 )); 499cdf0e10cSrcweir if ( aName.EqualsAscii( "%%" )) 500cdf0e10cSrcweir { 501cdf0e10cSrcweir //SkipComment 502cdf0e10cSrcweir m_nBufferIndex = nRealStart + 2; 503cdf0e10cSrcweir while (m_nBufferIndex < nBufLen && 504cdf0e10cSrcweir '\n' != m_aBufferString.GetChar( m_nBufferIndex )) 505cdf0e10cSrcweir ++m_nBufferIndex; 506cdf0e10cSrcweir bCont = sal_True; 507cdf0e10cSrcweir } 508cdf0e10cSrcweir } 509cdf0e10cSrcweir 510cdf0e10cSrcweir } while (bCont); 511cdf0e10cSrcweir 512cdf0e10cSrcweir // set index of current token 513cdf0e10cSrcweir m_nTokenIndex = m_nBufferIndex; 514cdf0e10cSrcweir 515cdf0e10cSrcweir m_aCurToken.nRow = m_Row; 516cdf0e10cSrcweir m_aCurToken.nCol = nRealStart - m_nColOff + 1; 517cdf0e10cSrcweir 518cdf0e10cSrcweir sal_Bool bHandled = sal_True; 519cdf0e10cSrcweir if (nRealStart >= nBufLen) 520cdf0e10cSrcweir { 521cdf0e10cSrcweir m_aCurToken.eType = TEND; 522cdf0e10cSrcweir m_aCurToken.cMathChar = '\0'; 523cdf0e10cSrcweir m_aCurToken.nGroup = 0; 524cdf0e10cSrcweir m_aCurToken.nLevel = 0; 525cdf0e10cSrcweir m_aCurToken.aText.Erase(); 526cdf0e10cSrcweir } 527cdf0e10cSrcweir else if ((aRes.TokenType & (KParseType::ASC_NUMBER | KParseType::UNI_NUMBER)) 528cdf0e10cSrcweir || (bNumStart && (aRes.TokenType & KParseType::IDENTNAME))) 529cdf0e10cSrcweir { 530cdf0e10cSrcweir sal_Int32 n = aRes.EndPos - nRealStart; 531cdf0e10cSrcweir DBG_ASSERT( n >= 0, "length < 0" ); 532cdf0e10cSrcweir m_aCurToken.eType = TNUMBER; 533cdf0e10cSrcweir m_aCurToken.cMathChar = '\0'; 534cdf0e10cSrcweir m_aCurToken.nGroup = 0; 535cdf0e10cSrcweir m_aCurToken.nLevel = 5; 536cdf0e10cSrcweir m_aCurToken.aText = m_aBufferString.Copy( nRealStart, sal::static_int_cast< xub_StrLen >(n) ); 537cdf0e10cSrcweir 538cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 539cdf0e10cSrcweir if (!IsDelimiter( m_aBufferString, static_cast< xub_StrLen >(aRes.EndPos) )) 540cdf0e10cSrcweir { 541cdf0e10cSrcweir DBG_WARNING( "identifier really finished? (compatibility!)" ); 542cdf0e10cSrcweir } 543cdf0e10cSrcweir #endif 544cdf0e10cSrcweir } 545cdf0e10cSrcweir else if (aRes.TokenType & KParseType::DOUBLE_QUOTE_STRING) 546cdf0e10cSrcweir { 547cdf0e10cSrcweir m_aCurToken.eType = TTEXT; 548cdf0e10cSrcweir m_aCurToken.cMathChar = '\0'; 549cdf0e10cSrcweir m_aCurToken.nGroup = 0; 550cdf0e10cSrcweir m_aCurToken.nLevel = 5; 551cdf0e10cSrcweir m_aCurToken.aText = aRes.DequotedNameOrString; 552cdf0e10cSrcweir m_aCurToken.nRow = m_Row; 553cdf0e10cSrcweir m_aCurToken.nCol = nRealStart - m_nColOff + 2; 554cdf0e10cSrcweir } 555cdf0e10cSrcweir else if (aRes.TokenType & KParseType::IDENTNAME) 556cdf0e10cSrcweir { 557cdf0e10cSrcweir sal_Int32 n = aRes.EndPos - nRealStart; 558cdf0e10cSrcweir DBG_ASSERT( n >= 0, "length < 0" ); 559cdf0e10cSrcweir String aName( m_aBufferString.Copy( nRealStart, sal::static_int_cast< xub_StrLen >(n) ) ); 560cdf0e10cSrcweir const SmTokenTableEntry *pEntry = GetTokenTableEntry( aName ); 561cdf0e10cSrcweir 562cdf0e10cSrcweir if (pEntry) 563cdf0e10cSrcweir { 564cdf0e10cSrcweir m_aCurToken.eType = pEntry->eType; 565cdf0e10cSrcweir m_aCurToken.cMathChar = pEntry->cMathChar; 566cdf0e10cSrcweir m_aCurToken.nGroup = pEntry->nGroup; 567cdf0e10cSrcweir m_aCurToken.nLevel = pEntry->nLevel; 568cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( pEntry->pIdent ); 569cdf0e10cSrcweir } 570cdf0e10cSrcweir else 571cdf0e10cSrcweir { 572cdf0e10cSrcweir m_aCurToken.eType = TIDENT; 573cdf0e10cSrcweir m_aCurToken.cMathChar = '\0'; 574cdf0e10cSrcweir m_aCurToken.nGroup = 0; 575cdf0e10cSrcweir m_aCurToken.nLevel = 5; 576cdf0e10cSrcweir m_aCurToken.aText = aName; 577cdf0e10cSrcweir 578cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 579cdf0e10cSrcweir if (!IsDelimiter( m_aBufferString, static_cast< xub_StrLen >(aRes.EndPos) )) 580cdf0e10cSrcweir { 581cdf0e10cSrcweir DBG_WARNING( "identifier really finished? (compatibility!)" ); 582cdf0e10cSrcweir } 583cdf0e10cSrcweir #endif 584cdf0e10cSrcweir } 585cdf0e10cSrcweir } 586cdf0e10cSrcweir else if (aRes.TokenType == 0 && '_' == m_aBufferString.GetChar( nRealStart )) 587cdf0e10cSrcweir { 588cdf0e10cSrcweir m_aCurToken.eType = TRSUB; 589cdf0e10cSrcweir m_aCurToken.cMathChar = '\0'; 590cdf0e10cSrcweir m_aCurToken.nGroup = TGPOWER; 591cdf0e10cSrcweir m_aCurToken.nLevel = 0; 592cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "_" ); 593cdf0e10cSrcweir 594cdf0e10cSrcweir aRes.EndPos = nRealStart + 1; 595cdf0e10cSrcweir } 596cdf0e10cSrcweir else if (aRes.TokenType & KParseType::BOOLEAN) 597cdf0e10cSrcweir { 598cdf0e10cSrcweir sal_Int32 &rnEndPos = aRes.EndPos; 599cdf0e10cSrcweir String aName( m_aBufferString.Copy( nRealStart, 600cdf0e10cSrcweir sal::static_int_cast< xub_StrLen >(rnEndPos - nRealStart) )); 601cdf0e10cSrcweir if (2 >= aName.Len()) 602cdf0e10cSrcweir { 603cdf0e10cSrcweir sal_Unicode ch = aName.GetChar( 0 ); 604cdf0e10cSrcweir switch (ch) 605cdf0e10cSrcweir { 606cdf0e10cSrcweir case '<': 607cdf0e10cSrcweir { 608cdf0e10cSrcweir if (m_aBufferString.Copy( nRealStart, 2 ). 609cdf0e10cSrcweir EqualsAscii( "<<" )) 610cdf0e10cSrcweir { 611cdf0e10cSrcweir m_aCurToken.eType = TLL; 612cdf0e10cSrcweir m_aCurToken.cMathChar = MS_LL; 613cdf0e10cSrcweir m_aCurToken.nGroup = TGRELATION; 614cdf0e10cSrcweir m_aCurToken.nLevel = 0; 615cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "<<" ); 616cdf0e10cSrcweir 617cdf0e10cSrcweir rnEndPos = nRealStart + 2; 618cdf0e10cSrcweir } 619cdf0e10cSrcweir else if (m_aBufferString.Copy( nRealStart, 2 ). 620cdf0e10cSrcweir EqualsAscii( "<=" )) 621cdf0e10cSrcweir { 622cdf0e10cSrcweir m_aCurToken.eType = TLE; 623cdf0e10cSrcweir m_aCurToken.cMathChar = MS_LE; 624cdf0e10cSrcweir m_aCurToken.nGroup = TGRELATION; 625cdf0e10cSrcweir m_aCurToken.nLevel = 0; 626cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "<=" ); 627cdf0e10cSrcweir 628cdf0e10cSrcweir rnEndPos = nRealStart + 2; 629cdf0e10cSrcweir } 630cdf0e10cSrcweir else if (m_aBufferString.Copy( nRealStart, 2 ). 631cdf0e10cSrcweir EqualsAscii( "<>" )) 632cdf0e10cSrcweir { 633cdf0e10cSrcweir m_aCurToken.eType = TNEQ; 634cdf0e10cSrcweir m_aCurToken.cMathChar = MS_NEQ; 635cdf0e10cSrcweir m_aCurToken.nGroup = TGRELATION; 636cdf0e10cSrcweir m_aCurToken.nLevel = 0; 637cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "<>" ); 638cdf0e10cSrcweir 639cdf0e10cSrcweir rnEndPos = nRealStart + 2; 640cdf0e10cSrcweir } 641cdf0e10cSrcweir else if (m_aBufferString.Copy( nRealStart, 3 ). 642cdf0e10cSrcweir EqualsAscii( "<?>" )) 643cdf0e10cSrcweir { 644cdf0e10cSrcweir m_aCurToken.eType = TPLACE; 645cdf0e10cSrcweir m_aCurToken.cMathChar = MS_PLACE; 646cdf0e10cSrcweir m_aCurToken.nGroup = 0; 647cdf0e10cSrcweir m_aCurToken.nLevel = 5; 648cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "<?>" ); 649cdf0e10cSrcweir 650cdf0e10cSrcweir rnEndPos = nRealStart + 3; 651cdf0e10cSrcweir } 652cdf0e10cSrcweir else 653cdf0e10cSrcweir { 654cdf0e10cSrcweir m_aCurToken.eType = TLT; 655cdf0e10cSrcweir m_aCurToken.cMathChar = MS_LT; 656cdf0e10cSrcweir m_aCurToken.nGroup = TGRELATION; 657cdf0e10cSrcweir m_aCurToken.nLevel = 0; 658cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "<" ); 659cdf0e10cSrcweir } 660cdf0e10cSrcweir } 661cdf0e10cSrcweir break; 662cdf0e10cSrcweir case '>': 663cdf0e10cSrcweir { 664cdf0e10cSrcweir if (m_aBufferString.Copy( nRealStart, 2 ). 665cdf0e10cSrcweir EqualsAscii( ">=" )) 666cdf0e10cSrcweir { 667cdf0e10cSrcweir m_aCurToken.eType = TGE; 668cdf0e10cSrcweir m_aCurToken.cMathChar = MS_GE; 669cdf0e10cSrcweir m_aCurToken.nGroup = TGRELATION; 670cdf0e10cSrcweir m_aCurToken.nLevel = 0; 671cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( ">=" ); 672cdf0e10cSrcweir 673cdf0e10cSrcweir rnEndPos = nRealStart + 2; 674cdf0e10cSrcweir } 675cdf0e10cSrcweir else if (m_aBufferString.Copy( nRealStart, 2 ). 676cdf0e10cSrcweir EqualsAscii( ">>" )) 677cdf0e10cSrcweir { 678cdf0e10cSrcweir m_aCurToken.eType = TGG; 679cdf0e10cSrcweir m_aCurToken.cMathChar = MS_GG; 680cdf0e10cSrcweir m_aCurToken.nGroup = TGRELATION; 681cdf0e10cSrcweir m_aCurToken.nLevel = 0; 682cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( ">>" ); 683cdf0e10cSrcweir 684cdf0e10cSrcweir rnEndPos = nRealStart + 2; 685cdf0e10cSrcweir } 686cdf0e10cSrcweir else 687cdf0e10cSrcweir { 688cdf0e10cSrcweir m_aCurToken.eType = TGT; 689cdf0e10cSrcweir m_aCurToken.cMathChar = MS_GT; 690cdf0e10cSrcweir m_aCurToken.nGroup = TGRELATION; 691cdf0e10cSrcweir m_aCurToken.nLevel = 0; 692cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( ">" ); 693cdf0e10cSrcweir } 694cdf0e10cSrcweir } 695cdf0e10cSrcweir break; 696cdf0e10cSrcweir default: 697cdf0e10cSrcweir bHandled = sal_False; 698cdf0e10cSrcweir } 699cdf0e10cSrcweir } 700cdf0e10cSrcweir } 701cdf0e10cSrcweir else if (aRes.TokenType & KParseType::ONE_SINGLE_CHAR) 702cdf0e10cSrcweir { 703cdf0e10cSrcweir sal_Int32 &rnEndPos = aRes.EndPos; 704cdf0e10cSrcweir String aName( m_aBufferString.Copy( nRealStart, 705cdf0e10cSrcweir sal::static_int_cast< xub_StrLen >(rnEndPos - nRealStart) ) ); 706cdf0e10cSrcweir 707cdf0e10cSrcweir if (1 == aName.Len()) 708cdf0e10cSrcweir { 709cdf0e10cSrcweir sal_Unicode ch = aName.GetChar( 0 ); 710cdf0e10cSrcweir switch (ch) 711cdf0e10cSrcweir { 712cdf0e10cSrcweir case '%': 713cdf0e10cSrcweir { 714cdf0e10cSrcweir //! modifies aRes.EndPos 715cdf0e10cSrcweir 716cdf0e10cSrcweir DBG_ASSERT( rnEndPos >= nBufLen || 717cdf0e10cSrcweir '%' != m_aBufferString.GetChar( sal::static_int_cast< xub_StrLen >(rnEndPos) ), 718cdf0e10cSrcweir "unexpected comment start" ); 719cdf0e10cSrcweir 720cdf0e10cSrcweir // get identifier of user-defined character 721cdf0e10cSrcweir ParseResult aTmpRes = aCC.parseAnyToken( 722cdf0e10cSrcweir m_aBufferString, rnEndPos, 723cdf0e10cSrcweir KParseTokens::ANY_LETTER, 724cdf0e10cSrcweir aEmptyStr, 725cdf0e10cSrcweir coContFlags, 726cdf0e10cSrcweir aEmptyStr ); 727cdf0e10cSrcweir 728cdf0e10cSrcweir xub_StrLen nTmpStart = sal::static_int_cast< xub_StrLen >(rnEndPos + 729cdf0e10cSrcweir aTmpRes.LeadingWhiteSpace); 730cdf0e10cSrcweir 731cdf0e10cSrcweir // default setting for the case that no identifier 732cdf0e10cSrcweir // i.e. a valid symbol-name is following the '%' 733cdf0e10cSrcweir // character 734cdf0e10cSrcweir m_aCurToken.eType = TTEXT; 735cdf0e10cSrcweir m_aCurToken.cMathChar = '\0'; 736cdf0e10cSrcweir m_aCurToken.nGroup = 0; 737cdf0e10cSrcweir m_aCurToken.nLevel = 5; 738cdf0e10cSrcweir m_aCurToken.aText = String(); 739cdf0e10cSrcweir m_aCurToken.nRow = sal::static_int_cast< xub_StrLen >(m_Row); 740cdf0e10cSrcweir m_aCurToken.nCol = nTmpStart - m_nColOff; 741cdf0e10cSrcweir 742cdf0e10cSrcweir if (aTmpRes.TokenType & KParseType::IDENTNAME) 743cdf0e10cSrcweir { 744cdf0e10cSrcweir 745cdf0e10cSrcweir xub_StrLen n = sal::static_int_cast< xub_StrLen >(aTmpRes.EndPos - nTmpStart); 746cdf0e10cSrcweir m_aCurToken.eType = TSPECIAL; 747cdf0e10cSrcweir m_aCurToken.aText = m_aBufferString.Copy( sal::static_int_cast< xub_StrLen >(nTmpStart-1), n+1 ); 748cdf0e10cSrcweir 749cdf0e10cSrcweir DBG_ASSERT( aTmpRes.EndPos > rnEndPos, 750cdf0e10cSrcweir "empty identifier" ); 751cdf0e10cSrcweir if (aTmpRes.EndPos > rnEndPos) 752cdf0e10cSrcweir rnEndPos = aTmpRes.EndPos; 753cdf0e10cSrcweir else 754cdf0e10cSrcweir ++rnEndPos; 755cdf0e10cSrcweir } 756cdf0e10cSrcweir 757cdf0e10cSrcweir // if no symbol-name was found we start-over with 758cdf0e10cSrcweir // finding the next token right afer the '%' sign. 759cdf0e10cSrcweir // I.e. we leave rnEndPos unmodified. 760cdf0e10cSrcweir } 761cdf0e10cSrcweir break; 762cdf0e10cSrcweir case '[': 763cdf0e10cSrcweir { 764cdf0e10cSrcweir m_aCurToken.eType = TLBRACKET; 765cdf0e10cSrcweir m_aCurToken.cMathChar = MS_LBRACKET; 766cdf0e10cSrcweir m_aCurToken.nGroup = TGLBRACES; 767cdf0e10cSrcweir m_aCurToken.nLevel = 5; 768cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "[" ); 769cdf0e10cSrcweir } 770cdf0e10cSrcweir break; 771cdf0e10cSrcweir case '\\': 772cdf0e10cSrcweir { 773cdf0e10cSrcweir m_aCurToken.eType = TESCAPE; 774cdf0e10cSrcweir m_aCurToken.cMathChar = '\0'; 775cdf0e10cSrcweir m_aCurToken.nGroup = 0; 776cdf0e10cSrcweir m_aCurToken.nLevel = 5; 777cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "\\" ); 778cdf0e10cSrcweir } 779cdf0e10cSrcweir break; 780cdf0e10cSrcweir case ']': 781cdf0e10cSrcweir { 782cdf0e10cSrcweir m_aCurToken.eType = TRBRACKET; 783cdf0e10cSrcweir m_aCurToken.cMathChar = MS_RBRACKET; 784cdf0e10cSrcweir m_aCurToken.nGroup = TGRBRACES; 785cdf0e10cSrcweir m_aCurToken.nLevel = 0; 786cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "]" ); 787cdf0e10cSrcweir } 788cdf0e10cSrcweir break; 789cdf0e10cSrcweir case '^': 790cdf0e10cSrcweir { 791cdf0e10cSrcweir m_aCurToken.eType = TRSUP; 792cdf0e10cSrcweir m_aCurToken.cMathChar = '\0'; 793cdf0e10cSrcweir m_aCurToken.nGroup = TGPOWER; 794cdf0e10cSrcweir m_aCurToken.nLevel = 0; 795cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "^" ); 796cdf0e10cSrcweir } 797cdf0e10cSrcweir break; 798cdf0e10cSrcweir case '`': 799cdf0e10cSrcweir { 800cdf0e10cSrcweir m_aCurToken.eType = TSBLANK; 801cdf0e10cSrcweir m_aCurToken.cMathChar = '\0'; 802cdf0e10cSrcweir m_aCurToken.nGroup = TGBLANK; 803cdf0e10cSrcweir m_aCurToken.nLevel = 5; 804cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "`" ); 805cdf0e10cSrcweir } 806cdf0e10cSrcweir break; 807cdf0e10cSrcweir case '{': 808cdf0e10cSrcweir { 809cdf0e10cSrcweir m_aCurToken.eType = TLGROUP; 810cdf0e10cSrcweir m_aCurToken.cMathChar = MS_LBRACE; 811cdf0e10cSrcweir m_aCurToken.nGroup = 0; 812cdf0e10cSrcweir m_aCurToken.nLevel = 5; 813cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "{" ); 814cdf0e10cSrcweir } 815cdf0e10cSrcweir break; 816cdf0e10cSrcweir case '|': 817cdf0e10cSrcweir { 818cdf0e10cSrcweir m_aCurToken.eType = TOR; 819cdf0e10cSrcweir m_aCurToken.cMathChar = MS_OR; 820cdf0e10cSrcweir m_aCurToken.nGroup = TGSUM; 821cdf0e10cSrcweir m_aCurToken.nLevel = 0; 822cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "|" ); 823cdf0e10cSrcweir } 824cdf0e10cSrcweir break; 825cdf0e10cSrcweir case '}': 826cdf0e10cSrcweir { 827cdf0e10cSrcweir m_aCurToken.eType = TRGROUP; 828cdf0e10cSrcweir m_aCurToken.cMathChar = MS_RBRACE; 829cdf0e10cSrcweir m_aCurToken.nGroup = 0; 830cdf0e10cSrcweir m_aCurToken.nLevel = 0; 831cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "}" ); 832cdf0e10cSrcweir } 833cdf0e10cSrcweir break; 834cdf0e10cSrcweir case '~': 835cdf0e10cSrcweir { 836cdf0e10cSrcweir m_aCurToken.eType = TBLANK; 837cdf0e10cSrcweir m_aCurToken.cMathChar = '\0'; 838cdf0e10cSrcweir m_aCurToken.nGroup = TGBLANK; 839cdf0e10cSrcweir m_aCurToken.nLevel = 5; 840cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "~" ); 841cdf0e10cSrcweir } 842cdf0e10cSrcweir break; 843cdf0e10cSrcweir case '#': 844cdf0e10cSrcweir { 845cdf0e10cSrcweir if (m_aBufferString.Copy( nRealStart, 2 ). 846cdf0e10cSrcweir EqualsAscii( "##" )) 847cdf0e10cSrcweir { 848cdf0e10cSrcweir m_aCurToken.eType = TDPOUND; 849cdf0e10cSrcweir m_aCurToken.cMathChar = '\0'; 850cdf0e10cSrcweir m_aCurToken.nGroup = 0; 851cdf0e10cSrcweir m_aCurToken.nLevel = 0; 852cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "##" ); 853cdf0e10cSrcweir 854cdf0e10cSrcweir rnEndPos = nRealStart + 2; 855cdf0e10cSrcweir } 856cdf0e10cSrcweir else 857cdf0e10cSrcweir { 858cdf0e10cSrcweir m_aCurToken.eType = TPOUND; 859cdf0e10cSrcweir m_aCurToken.cMathChar = '\0'; 860cdf0e10cSrcweir m_aCurToken.nGroup = 0; 861cdf0e10cSrcweir m_aCurToken.nLevel = 0; 862cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "#" ); 863cdf0e10cSrcweir } 864cdf0e10cSrcweir } 865cdf0e10cSrcweir break; 866cdf0e10cSrcweir case '&': 867cdf0e10cSrcweir { 868cdf0e10cSrcweir m_aCurToken.eType = TAND; 869cdf0e10cSrcweir m_aCurToken.cMathChar = MS_AND; 870cdf0e10cSrcweir m_aCurToken.nGroup = TGPRODUCT; 871cdf0e10cSrcweir m_aCurToken.nLevel = 0; 872cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "&" ); 873cdf0e10cSrcweir } 874cdf0e10cSrcweir break; 875cdf0e10cSrcweir case '(': 876cdf0e10cSrcweir { 877cdf0e10cSrcweir m_aCurToken.eType = TLPARENT; 878cdf0e10cSrcweir m_aCurToken.cMathChar = MS_LPARENT; 879cdf0e10cSrcweir m_aCurToken.nGroup = TGLBRACES; 880cdf0e10cSrcweir m_aCurToken.nLevel = 5; //! 0 to continue expression 881cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "(" ); 882cdf0e10cSrcweir } 883cdf0e10cSrcweir break; 884cdf0e10cSrcweir case ')': 885cdf0e10cSrcweir { 886cdf0e10cSrcweir m_aCurToken.eType = TRPARENT; 887cdf0e10cSrcweir m_aCurToken.cMathChar = MS_RPARENT; 888cdf0e10cSrcweir m_aCurToken.nGroup = TGRBRACES; 889cdf0e10cSrcweir m_aCurToken.nLevel = 0; //! 0 to terminate expression 890cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( ")" ); 891cdf0e10cSrcweir } 892cdf0e10cSrcweir break; 893cdf0e10cSrcweir case '*': 894cdf0e10cSrcweir { 895cdf0e10cSrcweir m_aCurToken.eType = TMULTIPLY; 896cdf0e10cSrcweir m_aCurToken.cMathChar = MS_MULTIPLY; 897cdf0e10cSrcweir m_aCurToken.nGroup = TGPRODUCT; 898cdf0e10cSrcweir m_aCurToken.nLevel = 0; 899cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "*" ); 900cdf0e10cSrcweir } 901cdf0e10cSrcweir break; 902cdf0e10cSrcweir case '+': 903cdf0e10cSrcweir { 904cdf0e10cSrcweir if (m_aBufferString.Copy( nRealStart, 2 ). 905cdf0e10cSrcweir EqualsAscii( "+-" )) 906cdf0e10cSrcweir { 907cdf0e10cSrcweir m_aCurToken.eType = TPLUSMINUS; 908cdf0e10cSrcweir m_aCurToken.cMathChar = MS_PLUSMINUS; 909cdf0e10cSrcweir m_aCurToken.nGroup = TGUNOPER | TGSUM; 910cdf0e10cSrcweir m_aCurToken.nLevel = 5; 911cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "+-" ); 912cdf0e10cSrcweir 913cdf0e10cSrcweir rnEndPos = nRealStart + 2; 914cdf0e10cSrcweir } 915cdf0e10cSrcweir else 916cdf0e10cSrcweir { 917cdf0e10cSrcweir m_aCurToken.eType = TPLUS; 918cdf0e10cSrcweir m_aCurToken.cMathChar = MS_PLUS; 919cdf0e10cSrcweir m_aCurToken.nGroup = TGUNOPER | TGSUM; 920cdf0e10cSrcweir m_aCurToken.nLevel = 5; 921cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "+" ); 922cdf0e10cSrcweir } 923cdf0e10cSrcweir } 924cdf0e10cSrcweir break; 925cdf0e10cSrcweir case '-': 926cdf0e10cSrcweir { 927cdf0e10cSrcweir if (m_aBufferString.Copy( nRealStart, 2 ). 928cdf0e10cSrcweir EqualsAscii( "-+" )) 929cdf0e10cSrcweir { 930cdf0e10cSrcweir m_aCurToken.eType = TMINUSPLUS; 931cdf0e10cSrcweir m_aCurToken.cMathChar = MS_MINUSPLUS; 932cdf0e10cSrcweir m_aCurToken.nGroup = TGUNOPER | TGSUM; 933cdf0e10cSrcweir m_aCurToken.nLevel = 5; 934cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "-+" ); 935cdf0e10cSrcweir 936cdf0e10cSrcweir rnEndPos = nRealStart + 2; 937cdf0e10cSrcweir } 938cdf0e10cSrcweir else 939cdf0e10cSrcweir { 940cdf0e10cSrcweir m_aCurToken.eType = TMINUS; 941cdf0e10cSrcweir m_aCurToken.cMathChar = MS_MINUS; 942cdf0e10cSrcweir m_aCurToken.nGroup = TGUNOPER | TGSUM; 943cdf0e10cSrcweir m_aCurToken.nLevel = 5; 944cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "-" ); 945cdf0e10cSrcweir } 946cdf0e10cSrcweir } 947cdf0e10cSrcweir break; 948cdf0e10cSrcweir case '.': 949cdf0e10cSrcweir { 950cdf0e10cSrcweir // for compatibility with SO5.2 951cdf0e10cSrcweir // texts like .34 ...56 ... h ...78..90 952cdf0e10cSrcweir // will be treated as numbers 953cdf0e10cSrcweir m_aCurToken.eType = TNUMBER; 954cdf0e10cSrcweir m_aCurToken.cMathChar = '\0'; 955cdf0e10cSrcweir m_aCurToken.nGroup = 0; 956cdf0e10cSrcweir m_aCurToken.nLevel = 5; 957cdf0e10cSrcweir 958cdf0e10cSrcweir xub_StrLen nTxtStart = m_nBufferIndex; 959cdf0e10cSrcweir sal_Unicode cChar; 960cdf0e10cSrcweir do 961cdf0e10cSrcweir { 962cdf0e10cSrcweir cChar = m_aBufferString.GetChar( ++m_nBufferIndex ); 963cdf0e10cSrcweir } 964cdf0e10cSrcweir while ( cChar == '.' || IsDigit( cChar ) ); 965cdf0e10cSrcweir 966cdf0e10cSrcweir m_aCurToken.aText = m_aBufferString.Copy( sal::static_int_cast< xub_StrLen >(nTxtStart), 967cdf0e10cSrcweir sal::static_int_cast< xub_StrLen >(m_nBufferIndex - nTxtStart) ); 968cdf0e10cSrcweir aRes.EndPos = m_nBufferIndex; 969cdf0e10cSrcweir } 970cdf0e10cSrcweir break; 971cdf0e10cSrcweir case '/': 972cdf0e10cSrcweir { 973cdf0e10cSrcweir m_aCurToken.eType = TDIVIDEBY; 974cdf0e10cSrcweir m_aCurToken.cMathChar = MS_SLASH; 975cdf0e10cSrcweir m_aCurToken.nGroup = TGPRODUCT; 976cdf0e10cSrcweir m_aCurToken.nLevel = 0; 977cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "/" ); 978cdf0e10cSrcweir } 979cdf0e10cSrcweir break; 980cdf0e10cSrcweir case '=': 981cdf0e10cSrcweir { 982cdf0e10cSrcweir m_aCurToken.eType = TASSIGN; 983cdf0e10cSrcweir m_aCurToken.cMathChar = MS_ASSIGN; 984cdf0e10cSrcweir m_aCurToken.nGroup = TGRELATION; 985cdf0e10cSrcweir m_aCurToken.nLevel = 0; 986cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( "=" ); 987cdf0e10cSrcweir } 988cdf0e10cSrcweir break; 989cdf0e10cSrcweir default: 990cdf0e10cSrcweir bHandled = sal_False; 991cdf0e10cSrcweir } 992cdf0e10cSrcweir } 993cdf0e10cSrcweir } 994cdf0e10cSrcweir else 995cdf0e10cSrcweir bHandled = sal_False; 996cdf0e10cSrcweir 997cdf0e10cSrcweir if (!bHandled) 998cdf0e10cSrcweir { 999cdf0e10cSrcweir m_aCurToken.eType = TCHARACTER; 1000cdf0e10cSrcweir m_aCurToken.cMathChar = '\0'; 1001cdf0e10cSrcweir m_aCurToken.nGroup = 0; 1002cdf0e10cSrcweir m_aCurToken.nLevel = 5; 1003cdf0e10cSrcweir m_aCurToken.aText = m_aBufferString.Copy( nRealStart, 1 ); 1004cdf0e10cSrcweir 1005cdf0e10cSrcweir aRes.EndPos = nRealStart + 1; 1006cdf0e10cSrcweir } 1007cdf0e10cSrcweir 1008cdf0e10cSrcweir if (TEND != m_aCurToken.eType) 1009cdf0e10cSrcweir m_nBufferIndex = sal::static_int_cast< xub_StrLen >(aRes.EndPos); 1010cdf0e10cSrcweir } 1011cdf0e10cSrcweir 1012cdf0e10cSrcweir 1013cdf0e10cSrcweir //////////////////////////////////////// 1014cdf0e10cSrcweir // grammar 1015cdf0e10cSrcweir // 1016cdf0e10cSrcweir 1017cdf0e10cSrcweir 1018cdf0e10cSrcweir void SmParser::Table() 1019cdf0e10cSrcweir { 1020cdf0e10cSrcweir SmNodeArray LineArray; 1021cdf0e10cSrcweir 1022cdf0e10cSrcweir Line(); 1023cdf0e10cSrcweir while (m_aCurToken.eType == TNEWLINE) 1024cdf0e10cSrcweir { 1025cdf0e10cSrcweir NextToken(); 1026cdf0e10cSrcweir Line(); 1027cdf0e10cSrcweir } 1028cdf0e10cSrcweir 1029cdf0e10cSrcweir if (m_aCurToken.eType != TEND) 1030cdf0e10cSrcweir Error(PE_UNEXPECTED_CHAR); 1031cdf0e10cSrcweir 1032cdf0e10cSrcweir sal_uLong n = m_aNodeStack.Count(); 1033cdf0e10cSrcweir 1034cdf0e10cSrcweir LineArray.resize(n); 1035cdf0e10cSrcweir 1036cdf0e10cSrcweir for (sal_uLong i = 0; i < n; i++) 1037cdf0e10cSrcweir LineArray[n - (i + 1)] = m_aNodeStack.Pop(); 1038cdf0e10cSrcweir 1039cdf0e10cSrcweir SmStructureNode *pSNode = new SmTableNode(m_aCurToken); 1040cdf0e10cSrcweir pSNode->SetSubNodes(LineArray); 1041cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 1042cdf0e10cSrcweir } 1043cdf0e10cSrcweir 1044cdf0e10cSrcweir 1045cdf0e10cSrcweir void SmParser::Align() 1046cdf0e10cSrcweir // parse alignment info (if any), then go on with rest of expression 1047cdf0e10cSrcweir { 1048cdf0e10cSrcweir SmStructureNode *pSNode = 0; 1049cdf0e10cSrcweir sal_Bool bNeedGroupClose = sal_False; 1050cdf0e10cSrcweir 1051cdf0e10cSrcweir if (TokenInGroup(TGALIGN)) 1052cdf0e10cSrcweir { 1053cdf0e10cSrcweir if (CONVERT_40_TO_50 == GetConversion()) 1054cdf0e10cSrcweir // encapsulate expression to be aligned in group braces 1055cdf0e10cSrcweir // (here group-open brace) 1056cdf0e10cSrcweir { Insert('{', GetTokenIndex()); 1057cdf0e10cSrcweir bNeedGroupClose = sal_True; 1058cdf0e10cSrcweir 1059cdf0e10cSrcweir // get first valid align statement in sequence 1060cdf0e10cSrcweir // (the dominant one in 4.0) and erase all others (especially old 1061cdf0e10cSrcweir // discarded tokens) from command string. 1062cdf0e10cSrcweir while (TokenInGroup(TGALIGN)) 1063cdf0e10cSrcweir { 1064cdf0e10cSrcweir if (TokenInGroup(TGDISCARDED) || pSNode) 1065cdf0e10cSrcweir { 1066cdf0e10cSrcweir m_nBufferIndex = GetTokenIndex(); 1067cdf0e10cSrcweir m_aBufferString.Erase(m_nBufferIndex, m_aCurToken.aText.Len()); 1068cdf0e10cSrcweir } 1069cdf0e10cSrcweir else 1070cdf0e10cSrcweir pSNode = new SmAlignNode(m_aCurToken); 1071cdf0e10cSrcweir 1072cdf0e10cSrcweir NextToken(); 1073cdf0e10cSrcweir } 1074cdf0e10cSrcweir } 1075cdf0e10cSrcweir else 1076cdf0e10cSrcweir { 1077cdf0e10cSrcweir pSNode = new SmAlignNode(m_aCurToken); 1078cdf0e10cSrcweir 1079cdf0e10cSrcweir NextToken(); 1080cdf0e10cSrcweir 1081cdf0e10cSrcweir // allow for just one align statement in 5.0 1082cdf0e10cSrcweir if (CONVERT_40_TO_50 != GetConversion() && TokenInGroup(TGALIGN)) 1083cdf0e10cSrcweir { Error(PE_DOUBLE_ALIGN); 1084cdf0e10cSrcweir return; 1085cdf0e10cSrcweir } 1086cdf0e10cSrcweir } 1087cdf0e10cSrcweir } 1088cdf0e10cSrcweir 1089cdf0e10cSrcweir Expression(); 1090cdf0e10cSrcweir 1091cdf0e10cSrcweir if (bNeedGroupClose) 1092cdf0e10cSrcweir Insert('}', GetTokenIndex()); 1093cdf0e10cSrcweir 1094cdf0e10cSrcweir if (pSNode) 1095cdf0e10cSrcweir { pSNode->SetSubNodes(m_aNodeStack.Pop(), 0); 1096cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 1097cdf0e10cSrcweir } 1098cdf0e10cSrcweir } 1099cdf0e10cSrcweir 1100cdf0e10cSrcweir 1101cdf0e10cSrcweir void SmParser::Line() 1102cdf0e10cSrcweir { 1103cdf0e10cSrcweir sal_uInt16 n = 0; 1104cdf0e10cSrcweir SmNodeArray ExpressionArray; 1105cdf0e10cSrcweir 1106cdf0e10cSrcweir ExpressionArray.resize(n); 1107cdf0e10cSrcweir 1108cdf0e10cSrcweir // start with single expression that may have an alignment statement 1109cdf0e10cSrcweir // (and go on with expressions that must not have alignment 1110cdf0e10cSrcweir // statements in 'while' loop below. See also 'Expression()'.) 1111cdf0e10cSrcweir if (m_aCurToken.eType != TEND && m_aCurToken.eType != TNEWLINE) 1112cdf0e10cSrcweir { Align(); 1113cdf0e10cSrcweir ExpressionArray.resize(++n); 1114cdf0e10cSrcweir ExpressionArray[n - 1] = m_aNodeStack.Pop(); 1115cdf0e10cSrcweir } 1116cdf0e10cSrcweir 1117cdf0e10cSrcweir while (m_aCurToken.eType != TEND && m_aCurToken.eType != TNEWLINE) 1118cdf0e10cSrcweir { if (CONVERT_40_TO_50 != GetConversion()) 1119cdf0e10cSrcweir Expression(); 1120cdf0e10cSrcweir else 1121cdf0e10cSrcweir Align(); 1122cdf0e10cSrcweir ExpressionArray.resize(++n); 1123cdf0e10cSrcweir ExpressionArray[n - 1] = m_aNodeStack.Pop(); 1124cdf0e10cSrcweir } 1125cdf0e10cSrcweir 1126cdf0e10cSrcweir SmStructureNode *pSNode = new SmLineNode(m_aCurToken); 1127cdf0e10cSrcweir pSNode->SetSubNodes(ExpressionArray); 1128cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 1129cdf0e10cSrcweir } 1130cdf0e10cSrcweir 1131cdf0e10cSrcweir 1132cdf0e10cSrcweir void SmParser::Expression() 1133cdf0e10cSrcweir { 1134cdf0e10cSrcweir sal_Bool bUseExtraSpaces = sal_True; 1135cdf0e10cSrcweir SmNode *pNode = m_aNodeStack.Pop(); 1136cdf0e10cSrcweir if (pNode) 1137cdf0e10cSrcweir { 1138cdf0e10cSrcweir if (pNode->GetToken().eType == TNOSPACE) 1139cdf0e10cSrcweir bUseExtraSpaces = sal_False; 1140cdf0e10cSrcweir else 1141cdf0e10cSrcweir m_aNodeStack.Push(pNode); // push the node from above again (now to be used as argument to this current 'nospace' node) 1142cdf0e10cSrcweir } 1143cdf0e10cSrcweir 1144cdf0e10cSrcweir sal_uInt16 n = 0; 1145cdf0e10cSrcweir SmNodeArray RelationArray; 1146cdf0e10cSrcweir 1147cdf0e10cSrcweir RelationArray.resize(n); 1148cdf0e10cSrcweir 1149cdf0e10cSrcweir Relation(); 1150cdf0e10cSrcweir RelationArray.resize(++n); 1151cdf0e10cSrcweir RelationArray[n - 1] = m_aNodeStack.Pop(); 1152cdf0e10cSrcweir 1153cdf0e10cSrcweir while (m_aCurToken.nLevel >= 4) 1154cdf0e10cSrcweir { Relation(); 1155cdf0e10cSrcweir RelationArray.resize(++n); 1156cdf0e10cSrcweir RelationArray[n - 1] = m_aNodeStack.Pop(); 1157cdf0e10cSrcweir } 1158cdf0e10cSrcweir 1159cdf0e10cSrcweir SmExpressionNode *pSNode = new SmExpressionNode(m_aCurToken); 1160cdf0e10cSrcweir pSNode->SetSubNodes(RelationArray); 1161cdf0e10cSrcweir pSNode->SetUseExtraSpaces(bUseExtraSpaces); 1162cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 1163cdf0e10cSrcweir } 1164cdf0e10cSrcweir 1165cdf0e10cSrcweir 1166cdf0e10cSrcweir void SmParser::Relation() 1167cdf0e10cSrcweir { 1168cdf0e10cSrcweir Sum(); 1169cdf0e10cSrcweir while (TokenInGroup(TGRELATION)) 1170cdf0e10cSrcweir { 1171cdf0e10cSrcweir SmStructureNode *pSNode = new SmBinHorNode(m_aCurToken); 1172cdf0e10cSrcweir SmNode *pFirst = m_aNodeStack.Pop(); 1173cdf0e10cSrcweir 1174cdf0e10cSrcweir OpSubSup(); 1175cdf0e10cSrcweir SmNode *pSecond = m_aNodeStack.Pop(); 1176cdf0e10cSrcweir 1177cdf0e10cSrcweir Sum(); 1178cdf0e10cSrcweir 1179cdf0e10cSrcweir pSNode->SetSubNodes(pFirst, pSecond, m_aNodeStack.Pop()); 1180cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 1181cdf0e10cSrcweir } 1182cdf0e10cSrcweir } 1183cdf0e10cSrcweir 1184cdf0e10cSrcweir 1185cdf0e10cSrcweir void SmParser::Sum() 1186cdf0e10cSrcweir { 1187cdf0e10cSrcweir Product(); 1188cdf0e10cSrcweir while (TokenInGroup(TGSUM)) 1189cdf0e10cSrcweir { 1190cdf0e10cSrcweir SmStructureNode *pSNode = new SmBinHorNode(m_aCurToken); 1191cdf0e10cSrcweir SmNode *pFirst = m_aNodeStack.Pop(); 1192cdf0e10cSrcweir 1193cdf0e10cSrcweir OpSubSup(); 1194cdf0e10cSrcweir SmNode *pSecond = m_aNodeStack.Pop(); 1195cdf0e10cSrcweir 1196cdf0e10cSrcweir Product(); 1197cdf0e10cSrcweir 1198cdf0e10cSrcweir pSNode->SetSubNodes(pFirst, pSecond, m_aNodeStack.Pop()); 1199cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 1200cdf0e10cSrcweir } 1201cdf0e10cSrcweir } 1202cdf0e10cSrcweir 1203cdf0e10cSrcweir 1204cdf0e10cSrcweir void SmParser::Product() 1205cdf0e10cSrcweir { 1206cdf0e10cSrcweir Power(); 1207cdf0e10cSrcweir 1208cdf0e10cSrcweir while (TokenInGroup(TGPRODUCT)) 1209cdf0e10cSrcweir { SmStructureNode *pSNode; 1210cdf0e10cSrcweir SmNode *pFirst = m_aNodeStack.Pop(), 1211cdf0e10cSrcweir *pOper; 1212cdf0e10cSrcweir sal_Bool bSwitchArgs = sal_False; 1213cdf0e10cSrcweir 1214cdf0e10cSrcweir SmTokenType eType = m_aCurToken.eType; 1215cdf0e10cSrcweir switch (eType) 1216cdf0e10cSrcweir { 1217cdf0e10cSrcweir case TOVER: 1218cdf0e10cSrcweir pSNode = new SmBinVerNode(m_aCurToken); 1219cdf0e10cSrcweir pOper = new SmRectangleNode(m_aCurToken); 1220cdf0e10cSrcweir NextToken(); 1221cdf0e10cSrcweir break; 1222cdf0e10cSrcweir 1223cdf0e10cSrcweir case TBOPER: 1224cdf0e10cSrcweir pSNode = new SmBinHorNode(m_aCurToken); 1225cdf0e10cSrcweir 1226cdf0e10cSrcweir NextToken(); 1227cdf0e10cSrcweir 1228cdf0e10cSrcweir GlyphSpecial(); 1229cdf0e10cSrcweir pOper = m_aNodeStack.Pop(); 1230cdf0e10cSrcweir break; 1231cdf0e10cSrcweir 1232cdf0e10cSrcweir case TOVERBRACE : 1233cdf0e10cSrcweir case TUNDERBRACE : 1234cdf0e10cSrcweir pSNode = new SmVerticalBraceNode(m_aCurToken); 1235cdf0e10cSrcweir pOper = new SmMathSymbolNode(m_aCurToken); 1236cdf0e10cSrcweir 1237cdf0e10cSrcweir NextToken(); 1238cdf0e10cSrcweir break; 1239cdf0e10cSrcweir 1240cdf0e10cSrcweir case TWIDEBACKSLASH: 1241cdf0e10cSrcweir case TWIDESLASH: 1242cdf0e10cSrcweir { 1243cdf0e10cSrcweir SmBinDiagonalNode *pSTmp = new SmBinDiagonalNode(m_aCurToken); 1244cdf0e10cSrcweir pSTmp->SetAscending(eType == TWIDESLASH); 1245cdf0e10cSrcweir pSNode = pSTmp; 1246cdf0e10cSrcweir 1247cdf0e10cSrcweir pOper = new SmPolyLineNode(m_aCurToken); 1248cdf0e10cSrcweir NextToken(); 1249cdf0e10cSrcweir 1250cdf0e10cSrcweir bSwitchArgs =sal_True; 1251cdf0e10cSrcweir break; 1252cdf0e10cSrcweir } 1253cdf0e10cSrcweir 1254cdf0e10cSrcweir default: 1255cdf0e10cSrcweir pSNode = new SmBinHorNode(m_aCurToken); 1256cdf0e10cSrcweir 1257cdf0e10cSrcweir OpSubSup(); 1258cdf0e10cSrcweir pOper = m_aNodeStack.Pop(); 1259cdf0e10cSrcweir } 1260cdf0e10cSrcweir 1261cdf0e10cSrcweir Power(); 1262cdf0e10cSrcweir 1263cdf0e10cSrcweir if (bSwitchArgs) 1264cdf0e10cSrcweir //! vgl siehe SmBinDiagonalNode::Arrange 1265cdf0e10cSrcweir pSNode->SetSubNodes(pFirst, m_aNodeStack.Pop(), pOper); 1266cdf0e10cSrcweir else 1267cdf0e10cSrcweir pSNode->SetSubNodes(pFirst, pOper, m_aNodeStack.Pop()); 1268cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 1269cdf0e10cSrcweir } 1270cdf0e10cSrcweir } 1271cdf0e10cSrcweir 1272cdf0e10cSrcweir 1273cdf0e10cSrcweir void SmParser::SubSup(sal_uLong nActiveGroup) 1274cdf0e10cSrcweir { 1275cdf0e10cSrcweir DBG_ASSERT(nActiveGroup == TGPOWER || nActiveGroup == TGLIMIT, 1276cdf0e10cSrcweir "Sm: falsche Tokengruppe"); 1277cdf0e10cSrcweir 1278cdf0e10cSrcweir if (!TokenInGroup(nActiveGroup)) 1279cdf0e10cSrcweir // already finish 1280cdf0e10cSrcweir return; 1281cdf0e10cSrcweir 1282cdf0e10cSrcweir SmSubSupNode *pNode = new SmSubSupNode(m_aCurToken); 1283cdf0e10cSrcweir //! Of course 'm_aCurToken' is just the first sub-/supscript token. 1284cdf0e10cSrcweir //! It should be of no further interest. The positions of the 1285cdf0e10cSrcweir //! sub-/supscripts will be identified by the corresponding subnodes 1286cdf0e10cSrcweir //! index in the 'aSubNodes' array (enum value from 'SmSubSup'). 1287cdf0e10cSrcweir 1288cdf0e10cSrcweir pNode->SetUseLimits(nActiveGroup == TGLIMIT); 1289cdf0e10cSrcweir 1290cdf0e10cSrcweir // initialize subnodes array 1291cdf0e10cSrcweir SmNodeArray aSubNodes; 1292cdf0e10cSrcweir aSubNodes.resize(1 + SUBSUP_NUM_ENTRIES); 1293cdf0e10cSrcweir aSubNodes[0] = m_aNodeStack.Pop(); 1294cdf0e10cSrcweir for (sal_uInt16 i = 1; i < aSubNodes.size(); i++) 1295cdf0e10cSrcweir aSubNodes[i] = NULL; 1296cdf0e10cSrcweir 1297cdf0e10cSrcweir // process all sub-/supscripts 1298cdf0e10cSrcweir int nIndex = 0; 1299cdf0e10cSrcweir while (TokenInGroup(nActiveGroup)) 1300cdf0e10cSrcweir { SmTokenType eType (m_aCurToken.eType); 1301cdf0e10cSrcweir 1302cdf0e10cSrcweir // skip sub-/supscript token 1303cdf0e10cSrcweir NextToken(); 1304cdf0e10cSrcweir 1305cdf0e10cSrcweir // get sub-/supscript node on top of stack 1306cdf0e10cSrcweir if (eType == TFROM || eType == TTO) 1307cdf0e10cSrcweir { 1308cdf0e10cSrcweir // parse limits in old 4.0 and 5.0 style 1309cdf0e10cSrcweir Relation(); 1310cdf0e10cSrcweir } 1311cdf0e10cSrcweir else 1312cdf0e10cSrcweir Term(); 1313cdf0e10cSrcweir 1314cdf0e10cSrcweir switch (eType) 1315cdf0e10cSrcweir { case TRSUB : nIndex = (int) RSUB; break; 1316cdf0e10cSrcweir case TRSUP : nIndex = (int) RSUP; break; 1317cdf0e10cSrcweir case TFROM : 1318cdf0e10cSrcweir case TCSUB : nIndex = (int) CSUB; break; 1319cdf0e10cSrcweir case TTO : 1320cdf0e10cSrcweir case TCSUP : nIndex = (int) CSUP; break; 1321cdf0e10cSrcweir case TLSUB : nIndex = (int) LSUB; break; 1322cdf0e10cSrcweir case TLSUP : nIndex = (int) LSUP; break; 1323cdf0e10cSrcweir default : 1324cdf0e10cSrcweir DBG_ASSERT(sal_False, "Sm: unbekannter Fall"); 1325cdf0e10cSrcweir } 1326cdf0e10cSrcweir nIndex++; 1327cdf0e10cSrcweir DBG_ASSERT(1 <= nIndex && nIndex <= 1 + SUBSUP_NUM_ENTRIES, 1328cdf0e10cSrcweir "SmParser::Power() : sub-/supscript index falsch"); 1329cdf0e10cSrcweir 1330cdf0e10cSrcweir // set sub-/supscript if not already done 1331cdf0e10cSrcweir if (aSubNodes[nIndex] != NULL) 1332cdf0e10cSrcweir Error(PE_DOUBLE_SUBSUPSCRIPT); 1333cdf0e10cSrcweir aSubNodes[nIndex] = m_aNodeStack.Pop(); 1334cdf0e10cSrcweir } 1335cdf0e10cSrcweir 1336cdf0e10cSrcweir pNode->SetSubNodes(aSubNodes); 1337cdf0e10cSrcweir m_aNodeStack.Push(pNode); 1338cdf0e10cSrcweir } 1339cdf0e10cSrcweir 1340cdf0e10cSrcweir 1341cdf0e10cSrcweir void SmParser::OpSubSup() 1342cdf0e10cSrcweir { 1343cdf0e10cSrcweir // push operator symbol 1344cdf0e10cSrcweir m_aNodeStack.Push(new SmMathSymbolNode(m_aCurToken)); 1345cdf0e10cSrcweir // skip operator token 1346cdf0e10cSrcweir NextToken(); 1347cdf0e10cSrcweir // get sub- supscripts if any 1348cdf0e10cSrcweir if (TokenInGroup(TGPOWER)) 1349cdf0e10cSrcweir SubSup(TGPOWER); 1350cdf0e10cSrcweir } 1351cdf0e10cSrcweir 1352cdf0e10cSrcweir 1353cdf0e10cSrcweir void SmParser::Power() 1354cdf0e10cSrcweir { 1355cdf0e10cSrcweir // get body for sub- supscripts on top of stack 1356cdf0e10cSrcweir Term(); 1357cdf0e10cSrcweir 1358cdf0e10cSrcweir SubSup(TGPOWER); 1359cdf0e10cSrcweir } 1360cdf0e10cSrcweir 1361cdf0e10cSrcweir 1362cdf0e10cSrcweir void SmParser::Blank() 1363cdf0e10cSrcweir { 1364cdf0e10cSrcweir DBG_ASSERT(TokenInGroup(TGBLANK), "Sm : falsches Token"); 1365cdf0e10cSrcweir SmBlankNode *pBlankNode = new SmBlankNode(m_aCurToken); 1366cdf0e10cSrcweir 1367cdf0e10cSrcweir while (TokenInGroup(TGBLANK)) 1368cdf0e10cSrcweir { 1369cdf0e10cSrcweir pBlankNode->IncreaseBy(m_aCurToken); 1370cdf0e10cSrcweir NextToken(); 1371cdf0e10cSrcweir } 1372cdf0e10cSrcweir 1373cdf0e10cSrcweir // Blanks am Zeilenende ignorieren wenn die entsprechende Option gesetzt ist 1374cdf0e10cSrcweir if ( m_aCurToken.eType == TNEWLINE || 1375cdf0e10cSrcweir (m_aCurToken.eType == TEND && SM_MOD()->GetConfig()->IsIgnoreSpacesRight()) ) 1376cdf0e10cSrcweir { 1377cdf0e10cSrcweir pBlankNode->Clear(); 1378cdf0e10cSrcweir } 1379cdf0e10cSrcweir 1380cdf0e10cSrcweir m_aNodeStack.Push(pBlankNode); 1381cdf0e10cSrcweir } 1382cdf0e10cSrcweir 1383cdf0e10cSrcweir 1384cdf0e10cSrcweir void SmParser::Term() 1385cdf0e10cSrcweir { 1386cdf0e10cSrcweir switch (m_aCurToken.eType) 1387cdf0e10cSrcweir { 1388cdf0e10cSrcweir case TESCAPE : 1389cdf0e10cSrcweir Escape(); 1390cdf0e10cSrcweir break; 1391cdf0e10cSrcweir 1392cdf0e10cSrcweir case TNOSPACE : 1393cdf0e10cSrcweir case TLGROUP : 1394cdf0e10cSrcweir { 1395cdf0e10cSrcweir bool bNoSpace = m_aCurToken.eType == TNOSPACE; 1396cdf0e10cSrcweir if (bNoSpace) // push 'no space' node and continue to parse expression 1397cdf0e10cSrcweir { 1398cdf0e10cSrcweir m_aNodeStack.Push(new SmExpressionNode(m_aCurToken)); 1399cdf0e10cSrcweir NextToken(); 1400cdf0e10cSrcweir } 1401cdf0e10cSrcweir if (m_aCurToken.eType != TLGROUP) 1402cdf0e10cSrcweir { 1403cdf0e10cSrcweir m_aNodeStack.Pop(); // get rid of the 'no space' node pushed above 1404cdf0e10cSrcweir Term(); 1405cdf0e10cSrcweir } 1406cdf0e10cSrcweir else 1407cdf0e10cSrcweir { 1408cdf0e10cSrcweir NextToken(); 1409cdf0e10cSrcweir 1410cdf0e10cSrcweir // allow for empty group 1411cdf0e10cSrcweir if (m_aCurToken.eType == TRGROUP) 1412cdf0e10cSrcweir { 1413cdf0e10cSrcweir if (bNoSpace) // get rid of the 'no space' node pushed above 1414cdf0e10cSrcweir m_aNodeStack.Pop(); 1415cdf0e10cSrcweir SmStructureNode *pSNode = new SmExpressionNode(m_aCurToken); 1416cdf0e10cSrcweir pSNode->SetSubNodes(NULL, NULL); 1417cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 1418cdf0e10cSrcweir 1419cdf0e10cSrcweir NextToken(); 1420cdf0e10cSrcweir } 1421cdf0e10cSrcweir else // go as usual 1422cdf0e10cSrcweir { 1423cdf0e10cSrcweir Align(); 1424cdf0e10cSrcweir if (m_aCurToken.eType != TRGROUP) 1425cdf0e10cSrcweir Error(PE_RGROUP_EXPECTED); 1426cdf0e10cSrcweir else 1427cdf0e10cSrcweir NextToken(); 1428cdf0e10cSrcweir } 1429cdf0e10cSrcweir } 1430cdf0e10cSrcweir } 1431cdf0e10cSrcweir break; 1432cdf0e10cSrcweir 1433cdf0e10cSrcweir case TLEFT : 1434cdf0e10cSrcweir Brace(); 1435cdf0e10cSrcweir break; 1436cdf0e10cSrcweir 1437cdf0e10cSrcweir case TBLANK : 1438cdf0e10cSrcweir case TSBLANK : 1439cdf0e10cSrcweir Blank(); 1440cdf0e10cSrcweir break; 1441cdf0e10cSrcweir 1442cdf0e10cSrcweir case TTEXT : 1443cdf0e10cSrcweir m_aNodeStack.Push(new SmTextNode(m_aCurToken, FNT_TEXT)); 1444cdf0e10cSrcweir NextToken(); 1445cdf0e10cSrcweir break; 1446cdf0e10cSrcweir case TIDENT : 1447cdf0e10cSrcweir case TCHARACTER : 1448cdf0e10cSrcweir m_aNodeStack.Push(new SmTextNode(m_aCurToken, FNT_VARIABLE)); 1449cdf0e10cSrcweir NextToken(); 1450cdf0e10cSrcweir break; 1451cdf0e10cSrcweir case TNUMBER : 1452cdf0e10cSrcweir m_aNodeStack.Push(new SmTextNode(m_aCurToken, FNT_NUMBER)); 1453cdf0e10cSrcweir NextToken(); 1454cdf0e10cSrcweir break; 1455cdf0e10cSrcweir 1456cdf0e10cSrcweir case TLEFTARROW : 1457cdf0e10cSrcweir case TRIGHTARROW : 1458cdf0e10cSrcweir case TUPARROW : 1459cdf0e10cSrcweir case TDOWNARROW : 1460cdf0e10cSrcweir case TSETN : 1461cdf0e10cSrcweir case TSETZ : 1462cdf0e10cSrcweir case TSETQ : 1463cdf0e10cSrcweir case TSETR : 1464cdf0e10cSrcweir case TSETC : 1465cdf0e10cSrcweir case THBAR : 1466cdf0e10cSrcweir case TLAMBDABAR : 1467cdf0e10cSrcweir case TCIRC : 1468cdf0e10cSrcweir case TDRARROW : 1469cdf0e10cSrcweir case TDLARROW : 1470cdf0e10cSrcweir case TDLRARROW : 1471cdf0e10cSrcweir case TBACKEPSILON : 1472cdf0e10cSrcweir case TALEPH : 1473cdf0e10cSrcweir case TIM : 1474cdf0e10cSrcweir case TRE : 1475cdf0e10cSrcweir case TWP : 1476cdf0e10cSrcweir case TEMPTYSET : 1477cdf0e10cSrcweir case TINFINITY : 1478cdf0e10cSrcweir case TEXISTS : 1479cdf0e10cSrcweir case TFORALL : 1480cdf0e10cSrcweir case TPARTIAL : 1481cdf0e10cSrcweir case TNABLA : 1482cdf0e10cSrcweir case TTOWARD : 1483cdf0e10cSrcweir case TDOTSAXIS : 1484cdf0e10cSrcweir case TDOTSDIAG : 1485cdf0e10cSrcweir case TDOTSDOWN : 1486cdf0e10cSrcweir case TDOTSLOW : 1487cdf0e10cSrcweir case TDOTSUP : 1488cdf0e10cSrcweir case TDOTSVERT : 1489cdf0e10cSrcweir m_aNodeStack.Push(new SmMathSymbolNode(m_aCurToken)); 1490cdf0e10cSrcweir NextToken(); 1491cdf0e10cSrcweir break; 1492cdf0e10cSrcweir 1493cdf0e10cSrcweir case TPLACE: 1494cdf0e10cSrcweir m_aNodeStack.Push(new SmPlaceNode(m_aCurToken)); 1495cdf0e10cSrcweir NextToken(); 1496cdf0e10cSrcweir break; 1497cdf0e10cSrcweir 1498cdf0e10cSrcweir case TSPECIAL: 1499cdf0e10cSrcweir Special(); 1500cdf0e10cSrcweir break; 1501cdf0e10cSrcweir 1502cdf0e10cSrcweir case TBINOM: 1503cdf0e10cSrcweir Binom(); 1504cdf0e10cSrcweir break; 1505cdf0e10cSrcweir 1506cdf0e10cSrcweir case TSTACK: 1507cdf0e10cSrcweir Stack(); 1508cdf0e10cSrcweir break; 1509cdf0e10cSrcweir 1510cdf0e10cSrcweir case TMATRIX: 1511cdf0e10cSrcweir Matrix(); 1512cdf0e10cSrcweir break; 1513cdf0e10cSrcweir 1514cdf0e10cSrcweir default: 1515cdf0e10cSrcweir if (TokenInGroup(TGLBRACES)) 1516cdf0e10cSrcweir { Brace(); 1517cdf0e10cSrcweir } 1518cdf0e10cSrcweir else if (TokenInGroup(TGOPER)) 1519cdf0e10cSrcweir { Operator(); 1520cdf0e10cSrcweir } 1521cdf0e10cSrcweir else if (TokenInGroup(TGUNOPER)) 1522cdf0e10cSrcweir { UnOper(); 1523cdf0e10cSrcweir } 1524cdf0e10cSrcweir else if ( TokenInGroup(TGATTRIBUT) 1525cdf0e10cSrcweir || TokenInGroup(TGFONTATTR)) 1526cdf0e10cSrcweir { SmStructureNodeArray aArray; 1527cdf0e10cSrcweir 1528cdf0e10cSrcweir sal_Bool bIsAttr; 1529cdf0e10cSrcweir sal_uInt16 n = 0; 1530cdf0e10cSrcweir while (sal_True == (bIsAttr = TokenInGroup(TGATTRIBUT)) 1531cdf0e10cSrcweir || TokenInGroup(TGFONTATTR)) 1532cdf0e10cSrcweir { aArray.resize(n + 1); 1533cdf0e10cSrcweir 1534cdf0e10cSrcweir if (bIsAttr) 1535cdf0e10cSrcweir Attribut(); 1536cdf0e10cSrcweir else 1537cdf0e10cSrcweir FontAttribut(); 1538cdf0e10cSrcweir 1539cdf0e10cSrcweir // check if casting in following line is ok 1540cdf0e10cSrcweir DBG_ASSERT(!m_aNodeStack.Top()->IsVisible(), "Sm : Ooops..."); 1541cdf0e10cSrcweir 1542cdf0e10cSrcweir aArray[n] = (SmStructureNode *) m_aNodeStack.Pop(); 1543cdf0e10cSrcweir n++; 1544cdf0e10cSrcweir } 1545cdf0e10cSrcweir 1546cdf0e10cSrcweir Power(); 1547cdf0e10cSrcweir 1548cdf0e10cSrcweir SmNode *pFirstNode = m_aNodeStack.Pop(); 1549cdf0e10cSrcweir while (n > 0) 1550cdf0e10cSrcweir { aArray[n - 1]->SetSubNodes(0, pFirstNode); 1551cdf0e10cSrcweir pFirstNode = aArray[n - 1]; 1552cdf0e10cSrcweir n--; 1553cdf0e10cSrcweir } 1554cdf0e10cSrcweir m_aNodeStack.Push(pFirstNode); 1555cdf0e10cSrcweir } 1556cdf0e10cSrcweir else if (TokenInGroup(TGFUNCTION)) 1557cdf0e10cSrcweir { if (CONVERT_40_TO_50 != GetConversion()) 1558cdf0e10cSrcweir { Function(); 1559cdf0e10cSrcweir } 1560cdf0e10cSrcweir else // encapsulate old 4.0 style parsing in braces 1561cdf0e10cSrcweir { 1562cdf0e10cSrcweir // insert opening brace 1563cdf0e10cSrcweir Insert('{', GetTokenIndex()); 1564cdf0e10cSrcweir 1565cdf0e10cSrcweir // 1566cdf0e10cSrcweir // parse in 4.0 style 1567cdf0e10cSrcweir // 1568cdf0e10cSrcweir Function(); 1569cdf0e10cSrcweir 1570cdf0e10cSrcweir SmNode *pFunc = m_aNodeStack.Pop(); 1571cdf0e10cSrcweir 1572cdf0e10cSrcweir if (m_aCurToken.eType == TLPARENT) 1573cdf0e10cSrcweir { Term(); 1574cdf0e10cSrcweir } 1575cdf0e10cSrcweir else 1576cdf0e10cSrcweir { Align(); 1577cdf0e10cSrcweir } 1578cdf0e10cSrcweir 1579cdf0e10cSrcweir // insert closing brace 1580cdf0e10cSrcweir Insert('}', GetTokenIndex()); 1581cdf0e10cSrcweir 1582cdf0e10cSrcweir SmStructureNode *pSNode = new SmExpressionNode(pFunc->GetToken()); 1583cdf0e10cSrcweir pSNode->SetSubNodes(pFunc, m_aNodeStack.Pop()); 1584cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 1585cdf0e10cSrcweir } 1586cdf0e10cSrcweir } 1587cdf0e10cSrcweir else 1588cdf0e10cSrcweir Error(PE_UNEXPECTED_CHAR); 1589cdf0e10cSrcweir } 1590cdf0e10cSrcweir } 1591cdf0e10cSrcweir 1592cdf0e10cSrcweir 1593cdf0e10cSrcweir void SmParser::Escape() 1594cdf0e10cSrcweir { 1595cdf0e10cSrcweir NextToken(); 1596cdf0e10cSrcweir 1597cdf0e10cSrcweir sal_Unicode cChar; 1598cdf0e10cSrcweir switch (m_aCurToken.eType) 1599cdf0e10cSrcweir { case TLPARENT : cChar = MS_LPARENT; break; 1600cdf0e10cSrcweir case TRPARENT : cChar = MS_RPARENT; break; 1601cdf0e10cSrcweir case TLBRACKET : cChar = MS_LBRACKET; break; 1602cdf0e10cSrcweir case TRBRACKET : cChar = MS_RBRACKET; break; 1603cdf0e10cSrcweir case TLDBRACKET : cChar = MS_LDBRACKET; break; 1604cdf0e10cSrcweir case TRDBRACKET : cChar = MS_RDBRACKET; break; 1605cdf0e10cSrcweir case TLBRACE : 1606cdf0e10cSrcweir case TLGROUP : cChar = MS_LBRACE; break; 1607cdf0e10cSrcweir case TRBRACE : 1608cdf0e10cSrcweir case TRGROUP : cChar = MS_RBRACE; break; 1609cdf0e10cSrcweir case TLANGLE : cChar = MS_LANGLE; break; 1610cdf0e10cSrcweir case TRANGLE : cChar = MS_RANGLE; break; 1611cdf0e10cSrcweir case TLCEIL : cChar = MS_LCEIL; break; 1612cdf0e10cSrcweir case TRCEIL : cChar = MS_RCEIL; break; 1613cdf0e10cSrcweir case TLFLOOR : cChar = MS_LFLOOR; break; 1614cdf0e10cSrcweir case TRFLOOR : cChar = MS_RFLOOR; break; 1615cdf0e10cSrcweir case TLLINE : 1616cdf0e10cSrcweir case TRLINE : cChar = MS_LINE; break; 1617cdf0e10cSrcweir case TLDLINE : 1618cdf0e10cSrcweir case TRDLINE : cChar = MS_DLINE; break; 1619cdf0e10cSrcweir default: 1620cdf0e10cSrcweir Error(PE_UNEXPECTED_TOKEN); 1621cdf0e10cSrcweir } 1622cdf0e10cSrcweir 1623cdf0e10cSrcweir SmNode *pNode = new SmMathSymbolNode(m_aCurToken); 1624cdf0e10cSrcweir m_aNodeStack.Push(pNode); 1625cdf0e10cSrcweir 1626cdf0e10cSrcweir NextToken(); 1627cdf0e10cSrcweir } 1628cdf0e10cSrcweir 1629cdf0e10cSrcweir 1630cdf0e10cSrcweir void SmParser::Operator() 1631cdf0e10cSrcweir { 1632cdf0e10cSrcweir if (TokenInGroup(TGOPER)) 1633cdf0e10cSrcweir { SmStructureNode *pSNode = new SmOperNode(m_aCurToken); 1634cdf0e10cSrcweir 1635cdf0e10cSrcweir // put operator on top of stack 1636cdf0e10cSrcweir Oper(); 1637cdf0e10cSrcweir 1638cdf0e10cSrcweir if (TokenInGroup(TGLIMIT) || TokenInGroup(TGPOWER)) 1639cdf0e10cSrcweir SubSup(m_aCurToken.nGroup); 1640cdf0e10cSrcweir SmNode *pOperator = m_aNodeStack.Pop(); 1641cdf0e10cSrcweir 1642cdf0e10cSrcweir // get argument 1643cdf0e10cSrcweir Power(); 1644cdf0e10cSrcweir 1645cdf0e10cSrcweir pSNode->SetSubNodes(pOperator, m_aNodeStack.Pop()); 1646cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 1647cdf0e10cSrcweir } 1648cdf0e10cSrcweir } 1649cdf0e10cSrcweir 1650cdf0e10cSrcweir 1651cdf0e10cSrcweir void SmParser::Oper() 1652cdf0e10cSrcweir { 1653cdf0e10cSrcweir SmTokenType eType (m_aCurToken.eType); 1654cdf0e10cSrcweir SmNode *pNode = NULL; 1655cdf0e10cSrcweir 1656cdf0e10cSrcweir switch (eType) 1657cdf0e10cSrcweir { 1658cdf0e10cSrcweir case TSUM : 1659cdf0e10cSrcweir case TPROD : 1660cdf0e10cSrcweir case TCOPROD : 1661cdf0e10cSrcweir case TINT : 1662cdf0e10cSrcweir case TIINT : 1663cdf0e10cSrcweir case TIIINT : 1664cdf0e10cSrcweir case TLINT : 1665cdf0e10cSrcweir case TLLINT : 1666cdf0e10cSrcweir case TLLLINT : 1667cdf0e10cSrcweir pNode = new SmMathSymbolNode(m_aCurToken); 1668cdf0e10cSrcweir break; 1669cdf0e10cSrcweir 1670cdf0e10cSrcweir case TLIM : 1671cdf0e10cSrcweir case TLIMSUP : 1672cdf0e10cSrcweir case TLIMINF : 1673cdf0e10cSrcweir { 1674cdf0e10cSrcweir const sal_Char* pLim = 0; 1675cdf0e10cSrcweir switch (eType) 1676cdf0e10cSrcweir { 1677cdf0e10cSrcweir case TLIM : pLim = "lim"; break; 1678cdf0e10cSrcweir case TLIMSUP : pLim = "lim sup"; break; 1679cdf0e10cSrcweir case TLIMINF : pLim = "lim inf"; break; 1680cdf0e10cSrcweir default: 1681cdf0e10cSrcweir break; 1682cdf0e10cSrcweir } 1683cdf0e10cSrcweir if( pLim ) 1684cdf0e10cSrcweir m_aCurToken.aText.AssignAscii( pLim ); 1685cdf0e10cSrcweir pNode = new SmTextNode(m_aCurToken, FNT_TEXT); 1686cdf0e10cSrcweir } 1687cdf0e10cSrcweir break; 1688cdf0e10cSrcweir 1689cdf0e10cSrcweir case TOVERBRACE : 1690cdf0e10cSrcweir case TUNDERBRACE : 1691cdf0e10cSrcweir pNode = new SmMathSymbolNode(m_aCurToken); 1692cdf0e10cSrcweir break; 1693cdf0e10cSrcweir 1694cdf0e10cSrcweir case TOPER : 1695cdf0e10cSrcweir NextToken(); 1696cdf0e10cSrcweir 1697cdf0e10cSrcweir DBG_ASSERT(m_aCurToken.eType == TSPECIAL, "Sm: falsches Token"); 1698cdf0e10cSrcweir pNode = new SmGlyphSpecialNode(m_aCurToken); 1699cdf0e10cSrcweir break; 1700cdf0e10cSrcweir 1701cdf0e10cSrcweir default : 1702cdf0e10cSrcweir DBG_ASSERT(0, "Sm: unbekannter Fall"); 1703cdf0e10cSrcweir } 1704cdf0e10cSrcweir m_aNodeStack.Push(pNode); 1705cdf0e10cSrcweir 1706cdf0e10cSrcweir NextToken(); 1707cdf0e10cSrcweir } 1708cdf0e10cSrcweir 1709cdf0e10cSrcweir 1710cdf0e10cSrcweir void SmParser::UnOper() 1711cdf0e10cSrcweir { 1712cdf0e10cSrcweir DBG_ASSERT(TokenInGroup(TGUNOPER), "Sm: falsches Token"); 1713cdf0e10cSrcweir 1714cdf0e10cSrcweir SmToken aNodeToken = m_aCurToken; 1715cdf0e10cSrcweir SmTokenType eType = m_aCurToken.eType; 1716cdf0e10cSrcweir sal_Bool bIsPostfix = eType == TFACT; 1717cdf0e10cSrcweir 1718cdf0e10cSrcweir SmStructureNode *pSNode; 1719cdf0e10cSrcweir SmNode *pOper = 0, 1720cdf0e10cSrcweir *pExtra = 0, 1721cdf0e10cSrcweir *pArg; 1722cdf0e10cSrcweir 1723cdf0e10cSrcweir switch (eType) 1724cdf0e10cSrcweir { 1725cdf0e10cSrcweir case TABS : 1726cdf0e10cSrcweir case TSQRT : 1727cdf0e10cSrcweir NextToken(); 1728cdf0e10cSrcweir break; 1729cdf0e10cSrcweir 1730cdf0e10cSrcweir case TNROOT : 1731cdf0e10cSrcweir NextToken(); 1732cdf0e10cSrcweir Power(); 1733cdf0e10cSrcweir pExtra = m_aNodeStack.Pop(); 1734cdf0e10cSrcweir break; 1735cdf0e10cSrcweir 1736cdf0e10cSrcweir case TUOPER : 1737cdf0e10cSrcweir NextToken(); 1738cdf0e10cSrcweir GlyphSpecial(); 1739cdf0e10cSrcweir pOper = m_aNodeStack.Pop(); 1740cdf0e10cSrcweir break; 1741cdf0e10cSrcweir 1742cdf0e10cSrcweir case TPLUS : 1743cdf0e10cSrcweir case TMINUS : 1744cdf0e10cSrcweir case TPLUSMINUS : 1745cdf0e10cSrcweir case TMINUSPLUS : 1746cdf0e10cSrcweir case TNEG : 1747cdf0e10cSrcweir case TFACT : 1748cdf0e10cSrcweir OpSubSup(); 1749cdf0e10cSrcweir pOper = m_aNodeStack.Pop(); 1750cdf0e10cSrcweir break; 1751cdf0e10cSrcweir 1752cdf0e10cSrcweir default : 1753cdf0e10cSrcweir Error(PE_UNOPER_EXPECTED); 1754cdf0e10cSrcweir } 1755cdf0e10cSrcweir 1756cdf0e10cSrcweir // get argument 1757cdf0e10cSrcweir Power(); 1758cdf0e10cSrcweir pArg = m_aNodeStack.Pop(); 1759cdf0e10cSrcweir 1760cdf0e10cSrcweir if (eType == TABS) 1761cdf0e10cSrcweir { pSNode = new SmBraceNode(aNodeToken); 1762cdf0e10cSrcweir pSNode->SetScaleMode(SCALE_HEIGHT); 1763cdf0e10cSrcweir 1764cdf0e10cSrcweir // build nodes for left & right lines 1765cdf0e10cSrcweir // (text, group, level of the used token are of no interrest here) 1766cdf0e10cSrcweir // we'll use row & column of the keyword for abs 1767cdf0e10cSrcweir aNodeToken.eType = TABS; 1768cdf0e10cSrcweir // 1769cdf0e10cSrcweir aNodeToken.cMathChar = MS_LINE; 1770cdf0e10cSrcweir SmNode* pLeft = new SmMathSymbolNode(aNodeToken); 1771cdf0e10cSrcweir // 1772cdf0e10cSrcweir aNodeToken.cMathChar = MS_LINE; 1773cdf0e10cSrcweir SmNode* pRight = new SmMathSymbolNode(aNodeToken); 1774cdf0e10cSrcweir 1775cdf0e10cSrcweir pSNode->SetSubNodes(pLeft, pArg, pRight); 1776cdf0e10cSrcweir } 1777cdf0e10cSrcweir else if (eType == TSQRT || eType == TNROOT) 1778cdf0e10cSrcweir { pSNode = new SmRootNode(aNodeToken); 1779cdf0e10cSrcweir pOper = new SmRootSymbolNode(aNodeToken); 1780cdf0e10cSrcweir pSNode->SetSubNodes(pExtra, pOper, pArg); 1781cdf0e10cSrcweir } 1782cdf0e10cSrcweir else 1783cdf0e10cSrcweir { pSNode = new SmUnHorNode(aNodeToken); 1784cdf0e10cSrcweir 1785cdf0e10cSrcweir if (bIsPostfix) 1786cdf0e10cSrcweir pSNode->SetSubNodes(pArg, pOper); 1787cdf0e10cSrcweir else 1788cdf0e10cSrcweir // prefix operator 1789cdf0e10cSrcweir pSNode->SetSubNodes(pOper, pArg); 1790cdf0e10cSrcweir } 1791cdf0e10cSrcweir 1792cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 1793cdf0e10cSrcweir } 1794cdf0e10cSrcweir 1795cdf0e10cSrcweir 1796cdf0e10cSrcweir void SmParser::Attribut() 1797cdf0e10cSrcweir { 1798cdf0e10cSrcweir DBG_ASSERT(TokenInGroup(TGATTRIBUT), "Sm: falsche Tokengruppe"); 1799cdf0e10cSrcweir 1800cdf0e10cSrcweir SmStructureNode *pSNode = new SmAttributNode(m_aCurToken); 1801cdf0e10cSrcweir SmNode *pAttr; 1802cdf0e10cSrcweir SmScaleMode eScaleMode = SCALE_NONE; 1803cdf0e10cSrcweir 1804cdf0e10cSrcweir // get appropriate node for the attribut itself 1805cdf0e10cSrcweir switch (m_aCurToken.eType) 1806cdf0e10cSrcweir { case TUNDERLINE : 1807cdf0e10cSrcweir case TOVERLINE : 1808cdf0e10cSrcweir case TOVERSTRIKE : 1809cdf0e10cSrcweir pAttr = new SmRectangleNode(m_aCurToken); 1810cdf0e10cSrcweir eScaleMode = SCALE_WIDTH; 1811cdf0e10cSrcweir break; 1812cdf0e10cSrcweir 1813cdf0e10cSrcweir case TWIDEVEC : 1814cdf0e10cSrcweir case TWIDEHAT : 1815cdf0e10cSrcweir case TWIDETILDE : 1816cdf0e10cSrcweir pAttr = new SmMathSymbolNode(m_aCurToken); 1817cdf0e10cSrcweir eScaleMode = SCALE_WIDTH; 1818cdf0e10cSrcweir break; 1819cdf0e10cSrcweir 1820cdf0e10cSrcweir default : 1821cdf0e10cSrcweir pAttr = new SmMathSymbolNode(m_aCurToken); 1822cdf0e10cSrcweir } 1823cdf0e10cSrcweir 1824cdf0e10cSrcweir NextToken(); 1825cdf0e10cSrcweir 1826cdf0e10cSrcweir pSNode->SetSubNodes(pAttr, 0); 1827cdf0e10cSrcweir pSNode->SetScaleMode(eScaleMode); 1828cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 1829cdf0e10cSrcweir } 1830cdf0e10cSrcweir 1831cdf0e10cSrcweir 1832cdf0e10cSrcweir void SmParser::FontAttribut() 1833cdf0e10cSrcweir { 1834cdf0e10cSrcweir DBG_ASSERT(TokenInGroup(TGFONTATTR), "Sm: falsche Tokengruppe"); 1835cdf0e10cSrcweir 1836cdf0e10cSrcweir switch (m_aCurToken.eType) 1837cdf0e10cSrcweir { 1838cdf0e10cSrcweir case TITALIC : 1839cdf0e10cSrcweir case TNITALIC : 1840cdf0e10cSrcweir case TBOLD : 1841cdf0e10cSrcweir case TNBOLD : 1842cdf0e10cSrcweir case TPHANTOM : 1843cdf0e10cSrcweir m_aNodeStack.Push(new SmFontNode(m_aCurToken)); 1844cdf0e10cSrcweir NextToken(); 1845cdf0e10cSrcweir break; 1846cdf0e10cSrcweir 1847cdf0e10cSrcweir case TSIZE : 1848cdf0e10cSrcweir FontSize(); 1849cdf0e10cSrcweir break; 1850cdf0e10cSrcweir 1851cdf0e10cSrcweir case TFONT : 1852cdf0e10cSrcweir Font(); 1853cdf0e10cSrcweir break; 1854cdf0e10cSrcweir 1855cdf0e10cSrcweir case TCOLOR : 1856cdf0e10cSrcweir Color(); 1857cdf0e10cSrcweir break; 1858cdf0e10cSrcweir 1859cdf0e10cSrcweir default : 1860cdf0e10cSrcweir DBG_ASSERT(0, "Sm: unbekannter Fall"); 1861cdf0e10cSrcweir } 1862cdf0e10cSrcweir } 1863cdf0e10cSrcweir 1864cdf0e10cSrcweir 1865cdf0e10cSrcweir void SmParser::Color() 1866cdf0e10cSrcweir { 1867cdf0e10cSrcweir DBG_ASSERT(m_aCurToken.eType == TCOLOR, "Sm : Ooops..."); 1868cdf0e10cSrcweir 1869cdf0e10cSrcweir // last color rules, get that one 1870cdf0e10cSrcweir SmToken aToken; 1871cdf0e10cSrcweir do 1872cdf0e10cSrcweir { NextToken(); 1873cdf0e10cSrcweir 1874cdf0e10cSrcweir if (TokenInGroup(TGCOLOR)) 1875cdf0e10cSrcweir { aToken = m_aCurToken; 1876cdf0e10cSrcweir NextToken(); 1877cdf0e10cSrcweir } 1878cdf0e10cSrcweir else 1879cdf0e10cSrcweir Error(PE_COLOR_EXPECTED); 1880cdf0e10cSrcweir } while (m_aCurToken.eType == TCOLOR); 1881cdf0e10cSrcweir 1882cdf0e10cSrcweir m_aNodeStack.Push(new SmFontNode(aToken)); 1883cdf0e10cSrcweir } 1884cdf0e10cSrcweir 1885cdf0e10cSrcweir 1886cdf0e10cSrcweir void SmParser::Font() 1887cdf0e10cSrcweir { 1888cdf0e10cSrcweir DBG_ASSERT(m_aCurToken.eType == TFONT, "Sm : Ooops..."); 1889cdf0e10cSrcweir 1890cdf0e10cSrcweir // last font rules, get that one 1891cdf0e10cSrcweir SmToken aToken; 1892cdf0e10cSrcweir do 1893cdf0e10cSrcweir { NextToken(); 1894cdf0e10cSrcweir 1895cdf0e10cSrcweir if (TokenInGroup(TGFONT)) 1896cdf0e10cSrcweir { aToken = m_aCurToken; 1897cdf0e10cSrcweir NextToken(); 1898cdf0e10cSrcweir } 1899cdf0e10cSrcweir else 1900cdf0e10cSrcweir Error(PE_FONT_EXPECTED); 1901cdf0e10cSrcweir } while (m_aCurToken.eType == TFONT); 1902cdf0e10cSrcweir 1903cdf0e10cSrcweir m_aNodeStack.Push(new SmFontNode(aToken)); 1904cdf0e10cSrcweir } 1905cdf0e10cSrcweir 1906cdf0e10cSrcweir 1907cdf0e10cSrcweir // gets number used as arguments in Math formulas (e.g. 'size' command) 1908cdf0e10cSrcweir // Format: no negative numbers, must start with a digit, no exponent notation, ... 1909cdf0e10cSrcweir sal_Bool lcl_IsNumber(const UniString& rText) 1910cdf0e10cSrcweir { 1911cdf0e10cSrcweir sal_Bool bPoint = sal_False; 1912cdf0e10cSrcweir const sal_Unicode* pBuffer = rText.GetBuffer(); 1913cdf0e10cSrcweir for(xub_StrLen nPos = 0; nPos < rText.Len(); nPos++, pBuffer++) 1914cdf0e10cSrcweir { 1915cdf0e10cSrcweir const sal_Unicode cChar = *pBuffer; 1916cdf0e10cSrcweir if(cChar == '.') 1917cdf0e10cSrcweir { 1918cdf0e10cSrcweir if(bPoint) 1919cdf0e10cSrcweir return sal_False; 1920cdf0e10cSrcweir else 1921cdf0e10cSrcweir bPoint = sal_True; 1922cdf0e10cSrcweir } 1923cdf0e10cSrcweir else if ( !IsDigit( cChar ) ) 1924cdf0e10cSrcweir return sal_False; 1925cdf0e10cSrcweir } 1926cdf0e10cSrcweir return sal_True; 1927cdf0e10cSrcweir } 1928cdf0e10cSrcweir 1929cdf0e10cSrcweir void SmParser::FontSize() 1930cdf0e10cSrcweir { 1931cdf0e10cSrcweir DBG_ASSERT(m_aCurToken.eType == TSIZE, "Sm : Ooops..."); 1932cdf0e10cSrcweir 1933cdf0e10cSrcweir sal_uInt16 Type; 1934cdf0e10cSrcweir SmFontNode *pFontNode = new SmFontNode(m_aCurToken); 1935cdf0e10cSrcweir 1936cdf0e10cSrcweir NextToken(); 1937cdf0e10cSrcweir 1938cdf0e10cSrcweir switch (m_aCurToken.eType) 1939cdf0e10cSrcweir { 1940cdf0e10cSrcweir case TNUMBER: Type = FNTSIZ_ABSOLUT; break; 1941cdf0e10cSrcweir case TPLUS: Type = FNTSIZ_PLUS; break; 1942cdf0e10cSrcweir case TMINUS: Type = FNTSIZ_MINUS; break; 1943cdf0e10cSrcweir case TMULTIPLY: Type = FNTSIZ_MULTIPLY; break; 1944cdf0e10cSrcweir case TDIVIDEBY: Type = FNTSIZ_DIVIDE; break; 1945cdf0e10cSrcweir 1946cdf0e10cSrcweir default: 1947cdf0e10cSrcweir delete pFontNode; 1948cdf0e10cSrcweir Error(PE_SIZE_EXPECTED); 1949cdf0e10cSrcweir return; 1950cdf0e10cSrcweir } 1951cdf0e10cSrcweir 1952cdf0e10cSrcweir if (Type != FNTSIZ_ABSOLUT) 1953cdf0e10cSrcweir { 1954cdf0e10cSrcweir NextToken(); 1955cdf0e10cSrcweir if (m_aCurToken.eType != TNUMBER) 1956cdf0e10cSrcweir { 1957cdf0e10cSrcweir delete pFontNode; 1958cdf0e10cSrcweir Error(PE_SIZE_EXPECTED); 1959cdf0e10cSrcweir return; 1960cdf0e10cSrcweir } 1961cdf0e10cSrcweir } 1962cdf0e10cSrcweir 1963cdf0e10cSrcweir // get number argument 1964cdf0e10cSrcweir Fraction aValue( 1L ); 1965cdf0e10cSrcweir if (lcl_IsNumber( m_aCurToken.aText )) 1966cdf0e10cSrcweir { 1967cdf0e10cSrcweir double fTmp; 1968cdf0e10cSrcweir if ((fTmp = m_aCurToken.aText.ToDouble()) != 0.0) 1969cdf0e10cSrcweir { 1970cdf0e10cSrcweir aValue = fTmp; 1971cdf0e10cSrcweir 1972cdf0e10cSrcweir //!! keep the numerator and denominator from being to large 1973cdf0e10cSrcweir //!! otherwise ongoing multiplications may result in overflows 1974cdf0e10cSrcweir //!! (for example in SmNode::SetFontSize the font size calculated 1975cdf0e10cSrcweir //!! may become 0 because of this!!! Happens e.g. for ftmp = 2.9 with Linux 1976cdf0e10cSrcweir //!! or ftmp = 1.11111111111111111... (11/9) on every platform.) 1977cdf0e10cSrcweir if (aValue.GetDenominator() > 1000) 1978cdf0e10cSrcweir { 1979cdf0e10cSrcweir long nNum = aValue.GetNumerator(); 1980cdf0e10cSrcweir long nDenom = aValue.GetDenominator(); 1981cdf0e10cSrcweir while (nDenom > 1000) 1982cdf0e10cSrcweir { 1983cdf0e10cSrcweir nNum /= 10; 1984cdf0e10cSrcweir nDenom /= 10; 1985cdf0e10cSrcweir } 1986cdf0e10cSrcweir aValue = Fraction( nNum, nDenom ); 1987cdf0e10cSrcweir } 1988cdf0e10cSrcweir } 1989cdf0e10cSrcweir } 1990cdf0e10cSrcweir 1991cdf0e10cSrcweir NextToken(); 1992cdf0e10cSrcweir 1993cdf0e10cSrcweir pFontNode->SetSizeParameter(aValue, Type); 1994cdf0e10cSrcweir m_aNodeStack.Push(pFontNode); 1995cdf0e10cSrcweir } 1996cdf0e10cSrcweir 1997cdf0e10cSrcweir 1998cdf0e10cSrcweir void SmParser::Brace() 1999cdf0e10cSrcweir { 2000cdf0e10cSrcweir DBG_ASSERT(m_aCurToken.eType == TLEFT || TokenInGroup(TGLBRACES), 2001cdf0e10cSrcweir "Sm: kein Klammer Ausdruck"); 2002cdf0e10cSrcweir 2003cdf0e10cSrcweir SmStructureNode *pSNode = new SmBraceNode(m_aCurToken); 2004cdf0e10cSrcweir SmNode *pBody = 0, 2005cdf0e10cSrcweir *pLeft = 0, 2006cdf0e10cSrcweir *pRight = 0; 2007cdf0e10cSrcweir SmScaleMode eScaleMode = SCALE_NONE; 2008cdf0e10cSrcweir SmParseError eError = PE_NONE; 2009cdf0e10cSrcweir 2010cdf0e10cSrcweir if (m_aCurToken.eType == TLEFT) 2011cdf0e10cSrcweir { NextToken(); 2012cdf0e10cSrcweir 2013cdf0e10cSrcweir eScaleMode = SCALE_HEIGHT; 2014cdf0e10cSrcweir 2015cdf0e10cSrcweir // check for left bracket 2016cdf0e10cSrcweir if (TokenInGroup(TGLBRACES) || TokenInGroup(TGRBRACES)) 2017cdf0e10cSrcweir { 2018cdf0e10cSrcweir pLeft = new SmMathSymbolNode(m_aCurToken); 2019cdf0e10cSrcweir 2020cdf0e10cSrcweir NextToken(); 2021cdf0e10cSrcweir Bracebody(sal_True); 2022cdf0e10cSrcweir pBody = m_aNodeStack.Pop(); 2023cdf0e10cSrcweir 2024cdf0e10cSrcweir if (m_aCurToken.eType == TRIGHT) 2025cdf0e10cSrcweir { NextToken(); 2026cdf0e10cSrcweir 2027cdf0e10cSrcweir // check for right bracket 2028cdf0e10cSrcweir if (TokenInGroup(TGLBRACES) || TokenInGroup(TGRBRACES)) 2029cdf0e10cSrcweir { 2030cdf0e10cSrcweir pRight = new SmMathSymbolNode(m_aCurToken); 2031cdf0e10cSrcweir NextToken(); 2032cdf0e10cSrcweir } 2033cdf0e10cSrcweir else 2034cdf0e10cSrcweir eError = PE_RBRACE_EXPECTED; 2035cdf0e10cSrcweir } 2036cdf0e10cSrcweir else 2037cdf0e10cSrcweir eError = PE_RIGHT_EXPECTED; 2038cdf0e10cSrcweir } 2039cdf0e10cSrcweir else 2040cdf0e10cSrcweir eError = PE_LBRACE_EXPECTED; 2041cdf0e10cSrcweir } 2042cdf0e10cSrcweir else 2043cdf0e10cSrcweir { 2044cdf0e10cSrcweir if (TokenInGroup(TGLBRACES)) 2045cdf0e10cSrcweir { 2046cdf0e10cSrcweir pLeft = new SmMathSymbolNode(m_aCurToken); 2047cdf0e10cSrcweir 2048cdf0e10cSrcweir NextToken(); 2049cdf0e10cSrcweir Bracebody(sal_False); 2050cdf0e10cSrcweir pBody = m_aNodeStack.Pop(); 2051cdf0e10cSrcweir 2052cdf0e10cSrcweir SmTokenType eExpectedType = TUNKNOWN; 2053cdf0e10cSrcweir switch (pLeft->GetToken().eType) 2054cdf0e10cSrcweir { case TLPARENT : eExpectedType = TRPARENT; break; 2055cdf0e10cSrcweir case TLBRACKET : eExpectedType = TRBRACKET; break; 2056cdf0e10cSrcweir case TLBRACE : eExpectedType = TRBRACE; break; 2057cdf0e10cSrcweir case TLDBRACKET : eExpectedType = TRDBRACKET; break; 2058cdf0e10cSrcweir case TLLINE : eExpectedType = TRLINE; break; 2059cdf0e10cSrcweir case TLDLINE : eExpectedType = TRDLINE; break; 2060cdf0e10cSrcweir case TLANGLE : eExpectedType = TRANGLE; break; 2061cdf0e10cSrcweir case TLFLOOR : eExpectedType = TRFLOOR; break; 2062cdf0e10cSrcweir case TLCEIL : eExpectedType = TRCEIL; break; 2063cdf0e10cSrcweir default : 2064cdf0e10cSrcweir DBG_ASSERT(0, "Sm: unbekannter Fall"); 2065cdf0e10cSrcweir } 2066cdf0e10cSrcweir 2067cdf0e10cSrcweir if (m_aCurToken.eType == eExpectedType) 2068cdf0e10cSrcweir { 2069cdf0e10cSrcweir pRight = new SmMathSymbolNode(m_aCurToken); 2070cdf0e10cSrcweir NextToken(); 2071cdf0e10cSrcweir } 2072cdf0e10cSrcweir else 2073cdf0e10cSrcweir eError = PE_PARENT_MISMATCH; 2074cdf0e10cSrcweir } 2075cdf0e10cSrcweir else 2076cdf0e10cSrcweir eError = PE_LBRACE_EXPECTED; 2077cdf0e10cSrcweir } 2078cdf0e10cSrcweir 2079cdf0e10cSrcweir if (eError == PE_NONE) 2080cdf0e10cSrcweir { DBG_ASSERT(pLeft, "Sm: NULL pointer"); 2081cdf0e10cSrcweir DBG_ASSERT(pRight, "Sm: NULL pointer"); 2082cdf0e10cSrcweir pSNode->SetSubNodes(pLeft, pBody, pRight); 2083cdf0e10cSrcweir pSNode->SetScaleMode(eScaleMode); 2084cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 2085cdf0e10cSrcweir } 2086cdf0e10cSrcweir else 2087cdf0e10cSrcweir { delete pSNode; 2088cdf0e10cSrcweir delete pBody; 2089cdf0e10cSrcweir delete pLeft; 2090cdf0e10cSrcweir delete pRight; 2091cdf0e10cSrcweir 2092cdf0e10cSrcweir Error(eError); 2093cdf0e10cSrcweir } 2094cdf0e10cSrcweir } 2095cdf0e10cSrcweir 2096cdf0e10cSrcweir 2097cdf0e10cSrcweir void SmParser::Bracebody(sal_Bool bIsLeftRight) 2098cdf0e10cSrcweir { 2099cdf0e10cSrcweir SmStructureNode *pBody = new SmBracebodyNode(m_aCurToken); 2100cdf0e10cSrcweir SmNodeArray aNodes; 2101cdf0e10cSrcweir sal_uInt16 nNum = 0; 2102cdf0e10cSrcweir 2103cdf0e10cSrcweir // get body if any 2104cdf0e10cSrcweir if (bIsLeftRight) 2105cdf0e10cSrcweir { 2106cdf0e10cSrcweir do 2107cdf0e10cSrcweir { 2108cdf0e10cSrcweir if (m_aCurToken.eType == TMLINE) 2109cdf0e10cSrcweir { 2110cdf0e10cSrcweir m_aNodeStack.Push(new SmMathSymbolNode(m_aCurToken)); 2111cdf0e10cSrcweir NextToken(); 2112cdf0e10cSrcweir nNum++; 2113cdf0e10cSrcweir } 2114cdf0e10cSrcweir else if (m_aCurToken.eType != TRIGHT) 2115cdf0e10cSrcweir { Align(); 2116cdf0e10cSrcweir nNum++; 2117cdf0e10cSrcweir 2118cdf0e10cSrcweir if (m_aCurToken.eType != TMLINE && m_aCurToken.eType != TRIGHT) 2119cdf0e10cSrcweir Error(PE_RIGHT_EXPECTED); 2120cdf0e10cSrcweir } 2121cdf0e10cSrcweir } while (m_aCurToken.eType != TEND && m_aCurToken.eType != TRIGHT); 2122cdf0e10cSrcweir } 2123cdf0e10cSrcweir else 2124cdf0e10cSrcweir { 2125cdf0e10cSrcweir do 2126cdf0e10cSrcweir { 2127cdf0e10cSrcweir if (m_aCurToken.eType == TMLINE) 2128cdf0e10cSrcweir { 2129cdf0e10cSrcweir m_aNodeStack.Push(new SmMathSymbolNode(m_aCurToken)); 2130cdf0e10cSrcweir NextToken(); 2131cdf0e10cSrcweir nNum++; 2132cdf0e10cSrcweir } 2133cdf0e10cSrcweir else if (!TokenInGroup(TGRBRACES)) 2134cdf0e10cSrcweir { Align(); 2135cdf0e10cSrcweir nNum++; 2136cdf0e10cSrcweir 2137cdf0e10cSrcweir if (m_aCurToken.eType != TMLINE && !TokenInGroup(TGRBRACES)) 2138cdf0e10cSrcweir Error(PE_RBRACE_EXPECTED); 2139cdf0e10cSrcweir } 2140cdf0e10cSrcweir } while (m_aCurToken.eType != TEND && !TokenInGroup(TGRBRACES)); 2141cdf0e10cSrcweir } 2142cdf0e10cSrcweir 2143cdf0e10cSrcweir // build argument vector in parsing order 2144cdf0e10cSrcweir aNodes.resize(nNum); 2145cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nNum; i++) 2146cdf0e10cSrcweir aNodes[nNum - 1 - i] = m_aNodeStack.Pop(); 2147cdf0e10cSrcweir 2148cdf0e10cSrcweir pBody->SetSubNodes(aNodes); 2149cdf0e10cSrcweir pBody->SetScaleMode(bIsLeftRight ? SCALE_HEIGHT : SCALE_NONE); 2150cdf0e10cSrcweir m_aNodeStack.Push(pBody); 2151cdf0e10cSrcweir } 2152cdf0e10cSrcweir 2153cdf0e10cSrcweir 2154cdf0e10cSrcweir void SmParser::Function() 2155cdf0e10cSrcweir { 2156cdf0e10cSrcweir switch (m_aCurToken.eType) 2157cdf0e10cSrcweir { 2158cdf0e10cSrcweir case TFUNC: 2159cdf0e10cSrcweir NextToken(); // skip "FUNC"-statement 2160cdf0e10cSrcweir // fall through 2161cdf0e10cSrcweir 2162cdf0e10cSrcweir case TSIN : 2163cdf0e10cSrcweir case TCOS : 2164cdf0e10cSrcweir case TTAN : 2165cdf0e10cSrcweir case TCOT : 2166cdf0e10cSrcweir case TASIN : 2167cdf0e10cSrcweir case TACOS : 2168cdf0e10cSrcweir case TATAN : 2169cdf0e10cSrcweir case TACOT : 2170cdf0e10cSrcweir case TSINH : 2171cdf0e10cSrcweir case TCOSH : 2172cdf0e10cSrcweir case TTANH : 2173cdf0e10cSrcweir case TCOTH : 2174cdf0e10cSrcweir case TASINH : 2175cdf0e10cSrcweir case TACOSH : 2176cdf0e10cSrcweir case TATANH : 2177cdf0e10cSrcweir case TACOTH : 2178cdf0e10cSrcweir case TLN : 2179cdf0e10cSrcweir case TLOG : 2180cdf0e10cSrcweir case TEXP : 2181cdf0e10cSrcweir m_aNodeStack.Push(new SmTextNode(m_aCurToken, FNT_FUNCTION)); 2182cdf0e10cSrcweir NextToken(); 2183cdf0e10cSrcweir break; 2184cdf0e10cSrcweir 2185cdf0e10cSrcweir default: 2186cdf0e10cSrcweir Error(PE_FUNC_EXPECTED); 2187cdf0e10cSrcweir } 2188cdf0e10cSrcweir } 2189cdf0e10cSrcweir 2190cdf0e10cSrcweir 2191cdf0e10cSrcweir void SmParser::Binom() 2192cdf0e10cSrcweir { 2193cdf0e10cSrcweir SmNodeArray ExpressionArray; 2194cdf0e10cSrcweir SmStructureNode *pSNode = new SmTableNode(m_aCurToken); 2195cdf0e10cSrcweir 2196cdf0e10cSrcweir NextToken(); 2197cdf0e10cSrcweir 2198cdf0e10cSrcweir Sum(); 2199cdf0e10cSrcweir Sum(); 2200cdf0e10cSrcweir 2201cdf0e10cSrcweir ExpressionArray.resize(2); 2202cdf0e10cSrcweir 2203cdf0e10cSrcweir for (int i = 0; i < 2; i++) 2204cdf0e10cSrcweir ExpressionArray[2 - (i + 1)] = m_aNodeStack.Pop(); 2205cdf0e10cSrcweir 2206cdf0e10cSrcweir pSNode->SetSubNodes(ExpressionArray); 2207cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 2208cdf0e10cSrcweir } 2209cdf0e10cSrcweir 2210cdf0e10cSrcweir 2211cdf0e10cSrcweir void SmParser::Stack() 2212cdf0e10cSrcweir { 2213cdf0e10cSrcweir SmNodeArray ExpressionArray; 2214cdf0e10cSrcweir NextToken(); 2215cdf0e10cSrcweir if (m_aCurToken.eType == TLGROUP) 2216cdf0e10cSrcweir { 2217cdf0e10cSrcweir sal_uInt16 n = 0; 2218cdf0e10cSrcweir 2219cdf0e10cSrcweir do 2220cdf0e10cSrcweir { 2221cdf0e10cSrcweir NextToken(); 2222cdf0e10cSrcweir Align(); 2223cdf0e10cSrcweir n++; 2224cdf0e10cSrcweir } 2225cdf0e10cSrcweir while (m_aCurToken.eType == TPOUND); 2226cdf0e10cSrcweir 2227cdf0e10cSrcweir ExpressionArray.resize(n); 2228cdf0e10cSrcweir 2229cdf0e10cSrcweir for (sal_uInt16 i = 0; i < n; i++) 2230cdf0e10cSrcweir ExpressionArray[n - (i + 1)] = m_aNodeStack.Pop(); 2231cdf0e10cSrcweir 2232cdf0e10cSrcweir if (m_aCurToken.eType != TRGROUP) 2233cdf0e10cSrcweir Error(PE_RGROUP_EXPECTED); 2234cdf0e10cSrcweir 2235cdf0e10cSrcweir NextToken(); 2236cdf0e10cSrcweir 2237cdf0e10cSrcweir SmStructureNode *pSNode = new SmTableNode(m_aCurToken); 2238cdf0e10cSrcweir pSNode->SetSubNodes(ExpressionArray); 2239cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 2240cdf0e10cSrcweir } 2241cdf0e10cSrcweir else 2242cdf0e10cSrcweir Error(PE_LGROUP_EXPECTED); 2243cdf0e10cSrcweir } 2244cdf0e10cSrcweir 2245cdf0e10cSrcweir 2246cdf0e10cSrcweir void SmParser::Matrix() 2247cdf0e10cSrcweir { 2248cdf0e10cSrcweir SmNodeArray ExpressionArray; 2249cdf0e10cSrcweir 2250cdf0e10cSrcweir NextToken(); 2251cdf0e10cSrcweir if (m_aCurToken.eType == TLGROUP) 2252cdf0e10cSrcweir { 2253cdf0e10cSrcweir sal_uInt16 c = 0; 2254cdf0e10cSrcweir 2255cdf0e10cSrcweir do 2256cdf0e10cSrcweir { 2257cdf0e10cSrcweir NextToken(); 2258cdf0e10cSrcweir Align(); 2259cdf0e10cSrcweir c++; 2260cdf0e10cSrcweir } 2261cdf0e10cSrcweir while (m_aCurToken.eType == TPOUND); 2262cdf0e10cSrcweir 2263cdf0e10cSrcweir sal_uInt16 r = 1; 2264cdf0e10cSrcweir 2265cdf0e10cSrcweir while (m_aCurToken.eType == TDPOUND) 2266cdf0e10cSrcweir { 2267cdf0e10cSrcweir NextToken(); 2268cdf0e10cSrcweir for (sal_uInt16 i = 0; i < c; i++) 2269cdf0e10cSrcweir { 2270cdf0e10cSrcweir Align(); 2271cdf0e10cSrcweir if (i < (c - 1)) 2272cdf0e10cSrcweir { 2273cdf0e10cSrcweir if (m_aCurToken.eType == TPOUND) 2274cdf0e10cSrcweir { 2275cdf0e10cSrcweir NextToken(); 2276cdf0e10cSrcweir } 2277cdf0e10cSrcweir else 2278cdf0e10cSrcweir Error(PE_POUND_EXPECTED); 2279cdf0e10cSrcweir } 2280cdf0e10cSrcweir } 2281cdf0e10cSrcweir 2282cdf0e10cSrcweir r++; 2283cdf0e10cSrcweir } 2284cdf0e10cSrcweir 2285cdf0e10cSrcweir long nRC = r * c; 2286cdf0e10cSrcweir 2287cdf0e10cSrcweir ExpressionArray.resize(nRC); 2288cdf0e10cSrcweir 2289cdf0e10cSrcweir for (sal_uInt16 i = 0; i < (nRC); i++) 2290cdf0e10cSrcweir ExpressionArray[(nRC) - (i + 1)] = m_aNodeStack.Pop(); 2291cdf0e10cSrcweir 2292cdf0e10cSrcweir if (m_aCurToken.eType != TRGROUP) 2293cdf0e10cSrcweir Error(PE_RGROUP_EXPECTED); 2294cdf0e10cSrcweir 2295cdf0e10cSrcweir NextToken(); 2296cdf0e10cSrcweir 2297cdf0e10cSrcweir SmMatrixNode *pMNode = new SmMatrixNode(m_aCurToken); 2298cdf0e10cSrcweir pMNode->SetSubNodes(ExpressionArray); 2299cdf0e10cSrcweir pMNode->SetRowCol(r, c); 2300cdf0e10cSrcweir m_aNodeStack.Push(pMNode); 2301cdf0e10cSrcweir } 2302cdf0e10cSrcweir else 2303cdf0e10cSrcweir Error(PE_LGROUP_EXPECTED); 2304cdf0e10cSrcweir } 2305cdf0e10cSrcweir 2306cdf0e10cSrcweir 2307cdf0e10cSrcweir void SmParser::Special() 2308cdf0e10cSrcweir { 2309cdf0e10cSrcweir sal_Bool bReplace = sal_False; 2310cdf0e10cSrcweir String &rName = m_aCurToken.aText; 2311cdf0e10cSrcweir String aNewName; 2312cdf0e10cSrcweir 2313cdf0e10cSrcweir if (CONVERT_NONE == GetConversion()) 2314cdf0e10cSrcweir { 2315cdf0e10cSrcweir // conversion of symbol names for 6.0 (XML) file format 2316cdf0e10cSrcweir // (name change on import / export. 2317cdf0e10cSrcweir // UI uses localized names XML file format does not.) 2318cdf0e10cSrcweir if( rName.Len() && rName.GetChar( 0 ) == sal_Unicode( '%' ) ) 2319cdf0e10cSrcweir { 2320cdf0e10cSrcweir if (IsImportSymbolNames()) 2321cdf0e10cSrcweir { 2322cdf0e10cSrcweir const SmLocalizedSymbolData &rLSD = SM_MOD()->GetLocSymbolData(); 2323cdf0e10cSrcweir aNewName = rLSD.GetUiSymbolName( rName.Copy( 1 ) ); 2324cdf0e10cSrcweir bReplace = sal_True; 2325cdf0e10cSrcweir } 2326cdf0e10cSrcweir else if (IsExportSymbolNames()) 2327cdf0e10cSrcweir { 2328cdf0e10cSrcweir const SmLocalizedSymbolData &rLSD = SM_MOD()->GetLocSymbolData(); 2329cdf0e10cSrcweir aNewName = rLSD.GetExportSymbolName( rName.Copy( 1 ) ); 2330cdf0e10cSrcweir bReplace = sal_True; 2331cdf0e10cSrcweir } 2332cdf0e10cSrcweir } 2333cdf0e10cSrcweir if( aNewName.Len() ) 2334cdf0e10cSrcweir aNewName.Insert( '%', 0 ); 2335cdf0e10cSrcweir } 2336cdf0e10cSrcweir else // 5.0 <-> 6.0 formula text (symbol name) conversion 2337cdf0e10cSrcweir { 2338cdf0e10cSrcweir LanguageType nLanguage = GetLanguage(); 2339cdf0e10cSrcweir SmLocalizedSymbolData &rData = SM_MOD()->GetLocSymbolData(); 2340cdf0e10cSrcweir const ResStringArray *pFrom = 0; 2341cdf0e10cSrcweir const ResStringArray *pTo = 0; 2342cdf0e10cSrcweir if (CONVERT_50_TO_60 == GetConversion()) 2343cdf0e10cSrcweir { 2344cdf0e10cSrcweir pFrom = rData.Get50NamesArray( nLanguage ); 2345cdf0e10cSrcweir pTo = rData.Get60NamesArray( nLanguage ); 2346cdf0e10cSrcweir } 2347cdf0e10cSrcweir else if (CONVERT_60_TO_50 == GetConversion()) 2348cdf0e10cSrcweir { 2349cdf0e10cSrcweir pFrom = rData.Get60NamesArray( nLanguage ); 2350cdf0e10cSrcweir pTo = rData.Get50NamesArray( nLanguage ); 2351cdf0e10cSrcweir } 2352cdf0e10cSrcweir if (pFrom && pTo) 2353cdf0e10cSrcweir { 2354cdf0e10cSrcweir DBG_ASSERT( pFrom->Count() == pTo->Count(), 2355cdf0e10cSrcweir "array length mismatch" ); 2356cdf0e10cSrcweir sal_uInt16 nCount = sal::static_int_cast< sal_uInt16 >(pFrom->Count()); 2357cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nCount; ++i) 2358cdf0e10cSrcweir { 2359cdf0e10cSrcweir if (pFrom->GetString(i) == rName) 2360cdf0e10cSrcweir { 2361cdf0e10cSrcweir aNewName = pTo->GetString(i); 2362cdf0e10cSrcweir bReplace = sal_True; 2363cdf0e10cSrcweir } 2364cdf0e10cSrcweir } 2365cdf0e10cSrcweir } 2366cdf0e10cSrcweir // else: 2367cdf0e10cSrcweir // conversion arrays not found or (usually) 2368cdf0e10cSrcweir // conversion not necessary 2369cdf0e10cSrcweir } 2370cdf0e10cSrcweir 2371cdf0e10cSrcweir if (bReplace && aNewName.Len() && rName != aNewName) 2372cdf0e10cSrcweir { 2373cdf0e10cSrcweir Replace( GetTokenIndex(), rName.Len(), aNewName ); 2374cdf0e10cSrcweir rName = aNewName; 2375cdf0e10cSrcweir } 2376cdf0e10cSrcweir 2377cdf0e10cSrcweir // add symbol name to list of used symbols 2378cdf0e10cSrcweir const String aSymbolName( m_aCurToken.aText.Copy( 1 ) ); 2379cdf0e10cSrcweir if (aSymbolName.Len() > 0 ) 2380cdf0e10cSrcweir AddToUsedSymbols( aSymbolName ); 2381cdf0e10cSrcweir 2382cdf0e10cSrcweir m_aNodeStack.Push(new SmSpecialNode(m_aCurToken)); 2383cdf0e10cSrcweir NextToken(); 2384cdf0e10cSrcweir } 2385cdf0e10cSrcweir 2386cdf0e10cSrcweir 2387cdf0e10cSrcweir void SmParser::GlyphSpecial() 2388cdf0e10cSrcweir { 2389cdf0e10cSrcweir m_aNodeStack.Push(new SmGlyphSpecialNode(m_aCurToken)); 2390cdf0e10cSrcweir NextToken(); 2391cdf0e10cSrcweir } 2392cdf0e10cSrcweir 2393cdf0e10cSrcweir 2394cdf0e10cSrcweir void SmParser::Error(SmParseError eError) 2395cdf0e10cSrcweir { 2396cdf0e10cSrcweir SmStructureNode *pSNode = new SmExpressionNode(m_aCurToken); 2397cdf0e10cSrcweir SmErrorNode *pErr = new SmErrorNode(eError, m_aCurToken); 2398cdf0e10cSrcweir pSNode->SetSubNodes(pErr, 0); 2399cdf0e10cSrcweir 2400cdf0e10cSrcweir //! put a structure node on the stack (instead of the error node itself) 2401cdf0e10cSrcweir //! because sometimes such a node is expected in order to attach some 2402cdf0e10cSrcweir //! subnodes 2403cdf0e10cSrcweir m_aNodeStack.Push(pSNode); 2404cdf0e10cSrcweir 2405cdf0e10cSrcweir AddError(eError, pSNode); 2406cdf0e10cSrcweir 2407cdf0e10cSrcweir NextToken(); 2408cdf0e10cSrcweir } 2409cdf0e10cSrcweir 2410cdf0e10cSrcweir 2411cdf0e10cSrcweir // end gramar 2412cdf0e10cSrcweir 2413cdf0e10cSrcweir 2414cdf0e10cSrcweir SmParser::SmParser() 2415cdf0e10cSrcweir { 2416cdf0e10cSrcweir m_eConversion = CONVERT_NONE; 2417cdf0e10cSrcweir m_bImportSymNames = m_bExportSymNames = sal_False; 2418cdf0e10cSrcweir m_nLang = Application::GetSettings().GetUILanguage(); 2419cdf0e10cSrcweir } 2420cdf0e10cSrcweir 2421cdf0e10cSrcweir 2422cdf0e10cSrcweir SmNode *SmParser::Parse(const String &rBuffer) 2423cdf0e10cSrcweir { 2424cdf0e10cSrcweir ClearUsedSymbols(); 2425cdf0e10cSrcweir 2426cdf0e10cSrcweir m_aBufferString = rBuffer; 2427cdf0e10cSrcweir m_aBufferString.ConvertLineEnd( LINEEND_LF ); 2428cdf0e10cSrcweir m_nBufferIndex = 2429cdf0e10cSrcweir m_nTokenIndex = 0; 2430cdf0e10cSrcweir m_Row = 1; 2431cdf0e10cSrcweir m_nColOff = 0; 2432cdf0e10cSrcweir m_nCurError = -1; 2433cdf0e10cSrcweir 2434cdf0e10cSrcweir for (sal_uInt16 i = 0; i < m_aErrDescList.Count(); i++) 2435cdf0e10cSrcweir delete m_aErrDescList.Remove(i); 2436cdf0e10cSrcweir 2437cdf0e10cSrcweir m_aErrDescList.Clear(); 2438cdf0e10cSrcweir 2439cdf0e10cSrcweir m_aNodeStack.Clear(); 2440cdf0e10cSrcweir 2441cdf0e10cSrcweir SetLanguage( Application::GetSettings().GetUILanguage() ); 2442cdf0e10cSrcweir NextToken(); 2443cdf0e10cSrcweir Table(); 2444cdf0e10cSrcweir 2445cdf0e10cSrcweir return m_aNodeStack.Pop(); 2446cdf0e10cSrcweir } 2447cdf0e10cSrcweir 2448cdf0e10cSrcweir 2449cdf0e10cSrcweir sal_uInt16 SmParser::AddError(SmParseError Type, SmNode *pNode) 2450cdf0e10cSrcweir { 2451cdf0e10cSrcweir SmErrorDesc *pErrDesc = new SmErrorDesc; 2452cdf0e10cSrcweir 2453cdf0e10cSrcweir pErrDesc->Type = Type; 2454cdf0e10cSrcweir pErrDesc->pNode = pNode; 2455cdf0e10cSrcweir pErrDesc->Text = String(SmResId(RID_ERR_IDENT)); 2456cdf0e10cSrcweir 2457cdf0e10cSrcweir sal_uInt16 nRID; 2458cdf0e10cSrcweir switch (Type) 2459cdf0e10cSrcweir { 2460cdf0e10cSrcweir case PE_UNEXPECTED_CHAR: nRID = RID_ERR_UNEXPECTEDCHARACTER; break; 2461cdf0e10cSrcweir case PE_LGROUP_EXPECTED: nRID = RID_ERR_LGROUPEXPECTED; break; 2462cdf0e10cSrcweir case PE_RGROUP_EXPECTED: nRID = RID_ERR_RGROUPEXPECTED; break; 2463cdf0e10cSrcweir case PE_LBRACE_EXPECTED: nRID = RID_ERR_LBRACEEXPECTED; break; 2464cdf0e10cSrcweir case PE_RBRACE_EXPECTED: nRID = RID_ERR_RBRACEEXPECTED; break; 2465cdf0e10cSrcweir case PE_FUNC_EXPECTED: nRID = RID_ERR_FUNCEXPECTED; break; 2466cdf0e10cSrcweir case PE_UNOPER_EXPECTED: nRID = RID_ERR_UNOPEREXPECTED; break; 2467cdf0e10cSrcweir case PE_BINOPER_EXPECTED: nRID = RID_ERR_BINOPEREXPECTED; break; 2468cdf0e10cSrcweir case PE_SYMBOL_EXPECTED: nRID = RID_ERR_SYMBOLEXPECTED; break; 2469cdf0e10cSrcweir case PE_IDENTIFIER_EXPECTED: nRID = RID_ERR_IDENTEXPECTED; break; 2470cdf0e10cSrcweir case PE_POUND_EXPECTED: nRID = RID_ERR_POUNDEXPECTED; break; 2471cdf0e10cSrcweir case PE_COLOR_EXPECTED: nRID = RID_ERR_COLOREXPECTED; break; 2472cdf0e10cSrcweir case PE_RIGHT_EXPECTED: nRID = RID_ERR_RIGHTEXPECTED; break; 2473cdf0e10cSrcweir 2474cdf0e10cSrcweir default: 2475cdf0e10cSrcweir nRID = RID_ERR_UNKOWN; 2476cdf0e10cSrcweir } 2477cdf0e10cSrcweir pErrDesc->Text += SmResId(nRID); 2478cdf0e10cSrcweir 2479cdf0e10cSrcweir m_aErrDescList.Insert(pErrDesc); 2480cdf0e10cSrcweir 2481cdf0e10cSrcweir return (sal_uInt16) m_aErrDescList.GetPos(pErrDesc); 2482cdf0e10cSrcweir } 2483cdf0e10cSrcweir 2484cdf0e10cSrcweir 2485cdf0e10cSrcweir const SmErrorDesc *SmParser::NextError() 2486cdf0e10cSrcweir { 2487cdf0e10cSrcweir if (m_aErrDescList.Count()) 2488cdf0e10cSrcweir if (m_nCurError > 0) return m_aErrDescList.Seek(--m_nCurError); 2489cdf0e10cSrcweir else 2490cdf0e10cSrcweir { 2491cdf0e10cSrcweir m_nCurError = 0; 2492cdf0e10cSrcweir return m_aErrDescList.Seek(m_nCurError); 2493cdf0e10cSrcweir } 2494cdf0e10cSrcweir else return 0; 2495cdf0e10cSrcweir } 2496cdf0e10cSrcweir 2497cdf0e10cSrcweir 2498cdf0e10cSrcweir const SmErrorDesc *SmParser::PrevError() 2499cdf0e10cSrcweir { 2500cdf0e10cSrcweir if (m_aErrDescList.Count()) 2501cdf0e10cSrcweir if (m_nCurError < (int) (m_aErrDescList.Count() - 1)) return m_aErrDescList.Seek(++m_nCurError); 2502cdf0e10cSrcweir else 2503cdf0e10cSrcweir { 2504cdf0e10cSrcweir m_nCurError = (int) (m_aErrDescList.Count() - 1); 2505cdf0e10cSrcweir return m_aErrDescList.Seek(m_nCurError); 2506cdf0e10cSrcweir } 2507cdf0e10cSrcweir else return 0; 2508cdf0e10cSrcweir } 2509cdf0e10cSrcweir 2510cdf0e10cSrcweir 2511cdf0e10cSrcweir const SmErrorDesc *SmParser::GetError(sal_uInt16 i) 2512cdf0e10cSrcweir { 2513cdf0e10cSrcweir return (/*i >= 0 &&*/ i < m_aErrDescList.Count()) 2514cdf0e10cSrcweir ? m_aErrDescList.Seek(i) 2515cdf0e10cSrcweir : m_aErrDescList.Seek(m_nCurError); 2516cdf0e10cSrcweir } 2517cdf0e10cSrcweir 2518cdf0e10cSrcweir 2519