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