00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "precompiled_starmath.hxx"
00038
00039
00040 #include <stdio.h>
00041
00042 #define SMDLL 1
00043
00044 #include <com/sun/star/i18n/UnicodeType.hpp>
00045
00046 #ifndef INCLUDED_I18NPOOL_LANG_H
00047 #include <i18npool/lang.h>
00048 #endif
00049 #ifndef _UNOTOOLS_CHARCLASS_HXX
00050 #include <unotools/charclass.hxx>
00051 #endif
00052 #ifndef _UNO_LINGU_HXX
00053 #include <svx/unolingu.hxx>
00054 #endif
00055 #ifndef INCLUDED_SVTOOLS_SYSLOCALE_HXX
00056 #include <svtools/syslocale.hxx>
00057 #endif
00058
00059 #ifndef PARSE_HXX
00060 #include "parse.hxx"
00061 #endif
00062 #ifndef _STARMATH_HRC
00063 #include "starmath.hrc"
00064 #endif
00065 #ifndef _SMDLL_HXX
00066 #include "smdll.hxx"
00067 #endif
00068 #ifndef _SMMOD_HXX
00069 #include "smmod.hxx"
00070 #endif
00071 #ifndef CONFIG_HXX
00072 #include "config.hxx"
00073 #endif
00074
00075 #include "node.hxx"
00076
00077 using namespace ::com::sun::star;
00078 using namespace ::com::sun::star::i18n;
00079
00081
00082 static inline BOOL strnccmp(const String &u1, xub_StrLen nIdx,
00083 const sal_Char *s2, xub_StrLen nLen)
00084 {
00085 return u1.EqualsIgnoreCaseAscii( s2, nIdx, nLen );
00086 }
00087
00088 static const sal_Unicode aDelimiterTable[] =
00089 {
00090 ' ', '\t', '\n', '\r', '+', '-', '*', '/', '=', '#',
00091 '%', '\\', '"', '~', '`', '>', '<', '&', '|', '(',
00092 ')', '{', '}', '[', ']', '^', '_',
00093 '\0'
00094 };
00095
00096
00097 static inline BOOL IsDigit( sal_Unicode cChar )
00098 {
00099 return '0' <= cChar && cChar <= '9';
00100 }
00101
00103
00104 SmToken::SmToken() :
00105 eType (TUNKNOWN),
00106 cMathChar ('\0')
00107 {
00108 nGroup = nCol = nRow = nLevel = 0;
00109 }
00110
00112
00113 struct SmTokenTableEntry
00114 {
00115 const sal_Char* pIdent;
00116 SmTokenType eType;
00117 sal_Unicode cMathChar;
00118 ULONG nGroup;
00119 USHORT nLevel;
00120 };
00121
00122 static const SmTokenTableEntry aTokenTable[] =
00123 {
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 { "Im" , TIM, MS_IM, TGSTANDALONE, 5 },
00146 { "MZ23", TDEBUG, '\0', TGATTRIBUT, 0 },
00147 { "Re" , TRE, MS_RE, TGSTANDALONE, 5 },
00148 { "abs", TABS, '\0', TGUNOPER, 13 },
00149 { "arcosh", TACOSH, '\0', TGFUNCTION, 5 },
00150 { "arcoth", TACOTH, '\0', TGFUNCTION, 5 },
00151 { "acute", TACUTE, MS_ACUTE, TGATTRIBUT, 5 },
00152 { "aleph" , TALEPH, MS_ALEPH, TGSTANDALONE, 5 },
00153 { "alignb", TALIGNC, '\0', TGALIGN | TGDISCARDED, 0},
00154 { "alignc", TALIGNC, '\0', TGALIGN, 0},
00155 { "alignl", TALIGNL, '\0', TGALIGN, 0},
00156 { "alignm", TALIGNC, '\0', TGALIGN | TGDISCARDED, 0},
00157 { "alignr", TALIGNR, '\0', TGALIGN, 0},
00158 { "alignt", TALIGNC, '\0', TGALIGN | TGDISCARDED, 0},
00159 { "and", TAND, MS_AND, TGPRODUCT, 0},
00160 { "approx", TAPPROX, MS_APPROX, TGRELATION, 0},
00161 { "arccos", TACOS, '\0', TGFUNCTION, 5},
00162 { "arccot", TACOT, '\0', TGFUNCTION, 5},
00163 { "arcsin", TASIN, '\0', TGFUNCTION, 5},
00164 { "arctan", TATAN, '\0', TGFUNCTION, 5},
00165 { "arsinh", TASINH, '\0', TGFUNCTION, 5},
00166 { "artanh", TATANH, '\0', TGFUNCTION, 5},
00167 { "backepsilon" , TBACKEPSILON, MS_BACKEPSILON, TGSTANDALONE, 5},
00168 { "bar", TBAR, MS_BAR, TGATTRIBUT, 5},
00169 { "binom", TBINOM, '\0', 0, 5 },
00170 { "black", TBLACK, '\0', TGCOLOR, 0},
00171 { "blue", TBLUE, '\0', TGCOLOR, 0},
00172 { "bold", TBOLD, '\0', TGFONTATTR, 5},
00173 { "boper", TBOPER, '\0', TGPRODUCT, 0},
00174 { "breve", TBREVE, MS_BREVE, TGATTRIBUT, 5},
00175 { "bslash", TBACKSLASH, MS_BACKSLASH, TGPRODUCT, 0 },
00176 { "cdot", TCDOT, MS_CDOT, TGPRODUCT, 0},
00177 { "check", TCHECK, MS_CHECK, TGATTRIBUT, 5},
00178 { "circ" , TCIRC, MS_CIRC, TGSTANDALONE, 5},
00179 { "circle", TCIRCLE, MS_CIRCLE, TGATTRIBUT, 5},
00180 { "color", TCOLOR, '\0', TGFONTATTR, 5},
00181 { "coprod", TCOPROD, MS_COPROD, TGOPER, 5},
00182 { "cos", TCOS, '\0', TGFUNCTION, 5},
00183 { "cosh", TCOSH, '\0', TGFUNCTION, 5},
00184 { "cot", TCOT, '\0', TGFUNCTION, 5},
00185 { "coth", TCOTH, '\0', TGFUNCTION, 5},
00186 { "csub", TCSUB, '\0', TGPOWER, 0},
00187 { "csup", TCSUP, '\0', TGPOWER, 0},
00188 { "cyan", TCYAN, '\0', TGCOLOR, 0},
00189 { "dddot", TDDDOT, MS_DDDOT, TGATTRIBUT, 5},
00190 { "ddot", TDDOT, MS_DDOT, TGATTRIBUT, 5},
00191 { "def", TDEF, MS_DEF, TGRELATION, 0},
00192 { "div", TDIV, MS_DIV, TGPRODUCT, 0},
00193 { "divides", TDIVIDES, MS_LINE, TGRELATION, 0},
00194 { "dlarrow" , TDLARROW, MS_DLARROW, TGSTANDALONE, 5},
00195 { "dlrarrow" , TDLRARROW, MS_DLRARROW, TGSTANDALONE, 5},
00196 { "dot", TDOT, MS_DOT, TGATTRIBUT, 5},
00197 { "dotsaxis", TDOTSAXIS, MS_DOTSAXIS, TGSTANDALONE, 5},
00198 { "dotsdiag", TDOTSDIAG, MS_DOTSUP, TGSTANDALONE, 5},
00199 { "dotsdown", TDOTSDOWN, MS_DOTSDOWN, TGSTANDALONE, 5},
00200 { "dotslow", TDOTSLOW, MS_DOTSLOW, TGSTANDALONE, 5},
00201 { "dotsup", TDOTSUP, MS_DOTSUP, TGSTANDALONE, 5},
00202 { "dotsvert", TDOTSVERT, MS_DOTSVERT, TGSTANDALONE, 5},
00203 { "downarrow" , TDOWNARROW, MS_DOWNARROW, TGSTANDALONE, 5},
00204 { "drarrow" , TDRARROW, MS_DRARROW, TGSTANDALONE, 5},
00205 { "emptyset" , TEMPTYSET, MS_EMPTYSET, TGSTANDALONE, 5},
00206 { "equiv", TEQUIV, MS_EQUIV, TGRELATION, 0},
00207 { "exists", TEXISTS, MS_EXISTS, TGSTANDALONE, 5},
00208 { "exp", TEXP, '\0', TGFUNCTION, 5},
00209 { "fact", TFACT, MS_FACT, TGUNOPER, 5},
00210 { "fixed", TFIXED, '\0', TGFONT, 0},
00211 { "font", TFONT, '\0', TGFONTATTR, 5},
00212 { "forall", TFORALL, MS_FORALL, TGSTANDALONE, 5},
00213 { "from", TFROM, '\0', TGLIMIT, 0},
00214 { "func", TFUNC, '\0', TGFUNCTION, 5},
00215 { "ge", TGE, MS_GE, TGRELATION, 0},
00216 { "geslant", TGESLANT, MS_GESLANT, TGRELATION, 0 },
00217 { "gg", TGG, MS_GG, TGRELATION, 0},
00218 { "grave", TGRAVE, MS_GRAVE, TGATTRIBUT, 5},
00219 { "green", TGREEN, '\0', TGCOLOR, 0},
00220 { "gt", TGT, MS_GT, TGRELATION, 0},
00221 { "hat", THAT, MS_HAT, TGATTRIBUT, 5},
00222 { "hbar" , THBAR, MS_HBAR, TGSTANDALONE, 5},
00223 { "iiint", TIIINT, MS_IIINT, TGOPER, 5},
00224 { "iint", TIINT, MS_IINT, TGOPER, 5},
00225 { "in", TIN, MS_IN, TGRELATION, 0},
00226 { "infinity" , TINFINITY, MS_INFINITY, TGSTANDALONE, 5},
00227 { "infty" , TINFINITY, MS_INFINITY, TGSTANDALONE, 5},
00228 { "int", TINT, MS_INT, TGOPER, 5},
00229 { "intersection", TINTERSECT, MS_INTERSECT, TGPRODUCT, 0},
00230 { "ital", TITALIC, '\0', TGFONTATTR, 5},
00231 { "italic", TITALIC, '\0', TGFONTATTR, 5},
00232 { "lambdabar" , TLAMBDABAR, MS_LAMBDABAR, TGSTANDALONE, 5},
00233 { "langle", TLANGLE, MS_LANGLE, TGLBRACES, 5},
00234 { "lbrace", TLBRACE, MS_LBRACE, TGLBRACES, 5},
00235 { "lceil", TLCEIL, MS_LCEIL, TGLBRACES, 5},
00236 { "ldbracket", TLDBRACKET, MS_LDBRACKET, TGLBRACES, 5},
00237 { "ldline", TLDLINE, MS_DLINE, TGLBRACES, 5},
00238 { "le", TLE, MS_LE, TGRELATION, 0},
00239 { "left", TLEFT, '\0', 0, 5},
00240 { "leftarrow" , TLEFTARROW, MS_LEFTARROW, TGSTANDALONE, 5},
00241 { "leslant", TLESLANT, MS_LESLANT, TGRELATION, 0 },
00242 { "lfloor", TLFLOOR, MS_LFLOOR, TGLBRACES, 5},
00243 { "lim", TLIM, '\0', TGOPER, 5},
00244 { "liminf", TLIMINF, '\0', TGOPER, 5},
00245 { "limsup", TLIMSUP, '\0', TGOPER, 5},
00246 { "lint", TLINT, MS_LINT, TGOPER, 5},
00247 { "ll", TLL, MS_LL, TGRELATION, 0},
00248 { "lline", TLLINE, MS_LINE, TGLBRACES, 5},
00249 { "llint", TLLINT, MS_LLINT, TGOPER, 5},
00250 { "lllint", TLLLINT, MS_LLLINT, TGOPER, 5},
00251 { "ln", TLN, '\0', TGFUNCTION, 5},
00252 { "log", TLOG, '\0', TGFUNCTION, 5},
00253 { "lsub", TLSUB, '\0', TGPOWER, 0},
00254 { "lsup", TLSUP, '\0', TGPOWER, 0},
00255 { "lt", TLT, MS_LT, TGRELATION, 0},
00256 { "magenta", TMAGENTA, '\0', TGCOLOR, 0},
00257 { "matrix", TMATRIX, '\0', 0, 5},
00258 { "minusplus", TMINUSPLUS, MS_MINUSPLUS, TGUNOPER | TGSUM, 5},
00259 { "mline", TMLINE, MS_LINE, 0, 0},
00260 { "nabla", TNABLA, MS_NABLA, TGSTANDALONE, 5},
00261 { "nbold", TNBOLD, '\0', TGFONTATTR, 5},
00262 { "ndivides", TNDIVIDES, MS_NDIVIDES, TGRELATION, 0},
00263 { "neg", TNEG, MS_NEG, TGUNOPER, 5 },
00264 { "neq", TNEQ, MS_NEQ, TGRELATION, 0},
00265 { "newline", TNEWLINE, '\0', 0, 0},
00266 { "ni", TNI, MS_NI, TGRELATION, 0},
00267 { "nitalic", TNITALIC, '\0', TGFONTATTR, 5},
00268 { "none", TNONE, '\0', TGLBRACES | TGRBRACES, 0},
00269 { "notin", TNOTIN, MS_NOTIN, TGRELATION, 0},
00270 { "nsubset", TNSUBSET, MS_NSUBSET, TGRELATION, 0 },
00271 { "nsupset", TNSUPSET, MS_NSUPSET, TGRELATION, 0 },
00272 { "nsubseteq", TNSUBSETEQ, MS_NSUBSETEQ, TGRELATION, 0 },
00273 { "nsupseteq", TNSUPSETEQ, MS_NSUPSETEQ, TGRELATION, 0 },
00274 { "nroot", TNROOT, MS_SQRT, TGUNOPER, 5},
00275 { "odivide", TODIVIDE, MS_ODIVIDE, TGPRODUCT, 0},
00276 { "odot", TODOT, MS_ODOT, TGPRODUCT, 0},
00277 { "ominus", TOMINUS, MS_OMINUS, TGSUM, 0},
00278 { "oper", TOPER, '\0', TGOPER, 5},
00279 { "oplus", TOPLUS, MS_OPLUS, TGSUM, 0},
00280 { "or", TOR, MS_OR, TGSUM, 0},
00281 { "ortho", TORTHO, MS_ORTHO, TGRELATION, 0},
00282 { "otimes", TOTIMES, MS_OTIMES, TGPRODUCT, 0},
00283 { "over", TOVER, '\0', TGPRODUCT, 0},
00284 { "overbrace", TOVERBRACE, MS_OVERBRACE, TGPRODUCT, 5},
00285 { "overline", TOVERLINE, '\0', TGATTRIBUT, 5},
00286 { "overstrike", TOVERSTRIKE, '\0', TGATTRIBUT, 5},
00287 { "owns", TNI, MS_NI, TGRELATION, 0},
00288 { "parallel", TPARALLEL, MS_DLINE, TGRELATION, 0},
00289 { "partial", TPARTIAL, MS_PARTIAL, TGSTANDALONE, 5 },
00290 { "phantom", TPHANTOM, '\0', TGFONTATTR, 5},
00291 { "plusminus", TPLUSMINUS, MS_PLUSMINUS, TGUNOPER | TGSUM, 5},
00292 { "prod", TPROD, MS_PROD, TGOPER, 5},
00293 { "prop", TPROP, MS_PROP, TGRELATION, 0},
00294 { "rangle", TRANGLE, MS_RANGLE, TGRBRACES, 0},
00295 { "rbrace", TRBRACE, MS_RBRACE, TGRBRACES, 0},
00296 { "rceil", TRCEIL, MS_RCEIL, TGRBRACES, 0},
00297 { "rdbracket", TRDBRACKET, MS_RDBRACKET, TGRBRACES, 0},
00298 { "rdline", TRDLINE, MS_DLINE, TGRBRACES, 0},
00299 { "red", TRED, '\0', TGCOLOR, 0},
00300 { "rfloor", TRFLOOR, MS_RFLOOR, TGRBRACES, 0},
00301 { "right", TRIGHT, '\0', 0, 0},
00302 { "rightarrow" , TRIGHTARROW, MS_RIGHTARROW, TGSTANDALONE, 5},
00303 { "rline", TRLINE, MS_LINE, TGRBRACES, 0},
00304 { "rsub", TRSUB, '\0', TGPOWER, 0},
00305 { "rsup", TRSUP, '\0', TGPOWER, 0},
00306 { "sans", TSANS, '\0', TGFONT, 0},
00307 { "serif", TSERIF, '\0', TGFONT, 0},
00308 { "setC" , TSETC, MS_SETC, TGSTANDALONE, 5},
00309 { "setN" , TSETN, MS_SETN, TGSTANDALONE, 5},
00310 { "setQ" , TSETQ, MS_SETQ, TGSTANDALONE, 5},
00311 { "setR" , TSETR, MS_SETR, TGSTANDALONE, 5},
00312 { "setZ" , TSETZ, MS_SETZ, TGSTANDALONE, 5},
00313 { "setminus", TBACKSLASH, MS_BACKSLASH, TGPRODUCT, 0 },
00314 { "sim", TSIM, MS_SIM, TGRELATION, 0},
00315 { "simeq", TSIMEQ, MS_SIMEQ, TGRELATION, 0},
00316 { "sin", TSIN, '\0', TGFUNCTION, 5},
00317 { "sinh", TSINH, '\0', TGFUNCTION, 5},
00318 { "size", TSIZE, '\0', TGFONTATTR, 5},
00319 { "slash", TSLASH, MS_SLASH, TGPRODUCT, 0 },
00320 { "sqrt", TSQRT, MS_SQRT, TGUNOPER, 5},
00321 { "stack", TSTACK, '\0', 0, 5},
00322 { "sub", TRSUB, '\0', TGPOWER, 0},
00323 { "subset", TSUBSET, MS_SUBSET, TGRELATION, 0},
00324 { "subseteq", TSUBSETEQ, MS_SUBSETEQ, TGRELATION, 0},
00325 { "sum", TSUM, MS_SUM, TGOPER, 5},
00326 { "sup", TRSUP, '\0', TGPOWER, 0},
00327 { "supset", TSUPSET, MS_SUPSET, TGRELATION, 0},
00328 { "supseteq", TSUPSETEQ, MS_SUPSETEQ, TGRELATION, 0},
00329 { "tan", TTAN, '\0', TGFUNCTION, 5},
00330 { "tanh", TTANH, '\0', TGFUNCTION, 5},
00331 { "tilde", TTILDE, MS_TILDE, TGATTRIBUT, 5},
00332 { "times", TTIMES, MS_TIMES, TGPRODUCT, 0},
00333 { "to", TTO, '\0', TGLIMIT, 0},
00334 { "toward", TTOWARD, MS_RIGHTARROW, TGRELATION, 0},
00335 { "transl", TTRANSL, MS_TRANSL, TGRELATION, 0},
00336 { "transr", TTRANSR, MS_TRANSR, TGRELATION, 0},
00337 { "underbrace", TUNDERBRACE, MS_UNDERBRACE, TGPRODUCT, 5},
00338 { "underline", TUNDERLINE, '\0', TGATTRIBUT, 5},
00339 { "union", TUNION, MS_UNION, TGSUM, 0},
00340 { "uoper", TUOPER, '\0', TGUNOPER, 5},
00341 { "uparrow" , TUPARROW, MS_UPARROW, TGSTANDALONE, 5},
00342 { "vec", TVEC, MS_VEC, TGATTRIBUT, 5},
00343 { "white", TWHITE, '\0', TGCOLOR, 0},
00344 { "widebslash", TWIDEBACKSLASH, MS_BACKSLASH, TGPRODUCT, 0 },
00345 { "widehat", TWIDEHAT, MS_HAT, TGATTRIBUT, 5},
00346 { "widetilde", TWIDETILDE, MS_TILDE, TGATTRIBUT, 5},
00347 { "wideslash", TWIDESLASH, MS_SLASH, TGPRODUCT, 0 },
00348 { "widevec", TWIDEVEC, MS_VEC, TGATTRIBUT, 5},
00349 { "wp" , TWP, MS_WP, TGSTANDALONE, 5},
00350 { "yellow", TYELLOW, '\0', TGCOLOR, 0},
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 { "", TEND, '\0', 0, 0}
00362 };
00363
00364
00365 static const SmTokenTableEntry * GetTokenTableEntry( const String &rName )
00366 {
00367 const SmTokenTableEntry * pRes = 0;
00368 if (rName.Len())
00369 {
00370 INT32 nEntries = sizeof( aTokenTable ) / sizeof( aTokenTable[0] );
00371 for (INT32 i = 0; i < nEntries; ++i)
00372 {
00373 if (rName.EqualsIgnoreCaseAscii( aTokenTable[i].pIdent ))
00374 {
00375 pRes = &aTokenTable[i];
00376 break;
00377 }
00378 }
00379
00380 }
00381
00382 return pRes;
00383 }
00384
00385
00387
00388 #if OSL_DEBUG_LEVEL
00389
00390 BOOL SmParser::IsDelimiter( const String &rTxt, xub_StrLen nPos )
00391
00392 {
00393 DBG_ASSERT( nPos <= rTxt.Len(), "index out of range" );
00394
00395 sal_Unicode cChar = rTxt.GetChar( nPos );
00396 if(!cChar)
00397 return TRUE;
00398
00399
00400 const sal_Unicode *pDelim = &aDelimiterTable[0];
00401 for ( ; *pDelim != 0; pDelim++)
00402 if (*pDelim == cChar)
00403 break;
00404
00405 BOOL bIsDelim = *pDelim != 0;
00406
00407 INT16 nTypJp = SM_MOD1()->GetSysLocale().GetCharClass().getType( rTxt, nPos );
00408 bIsDelim |= nTypJp == com::sun::star::i18n::UnicodeType::SPACE_SEPARATOR ||
00409 nTypJp == com::sun::star::i18n::UnicodeType::CONTROL;
00410
00411 return bIsDelim;
00412 }
00413
00414 #endif
00415
00416 void SmParser::Insert(const String &rText, USHORT nPos)
00417 {
00418 BufferString.Insert(rText, nPos);
00419
00420 xub_StrLen nLen = rText.Len();
00421 BufferIndex = BufferIndex + nLen;
00422 nTokenIndex = nTokenIndex + nLen;
00423 }
00424
00425
00426 void SmParser::Replace( USHORT nPos, USHORT nLen, const String &rText )
00427 {
00428 DBG_ASSERT( nPos + nLen <= BufferString.Len(), "argument mismatch" );
00429
00430 BufferString.Replace( nPos, nLen, rText );
00431 INT16 nChg = rText.Len() - nLen;
00432 BufferIndex = BufferIndex + nChg;
00433 nTokenIndex = nTokenIndex + nChg;
00434 }
00435
00436
00437
00438 const sal_Int32 coStartFlags =
00439 KParseTokens::ANY_LETTER_OR_NUMBER |
00440 KParseTokens::IGNORE_LEADING_WS;
00441
00442
00443 const sal_Int32 coContFlags =
00444 ( coStartFlags | KParseTokens::ASC_DOT ) & ~KParseTokens::IGNORE_LEADING_WS
00445 | KParseTokens::TWO_DOUBLE_QUOTES_BREAK_STRING;
00446
00447
00448 const sal_Int32 coNumStartFlags =
00449 KParseTokens::ASC_DIGIT |
00450 KParseTokens::ASC_DOT |
00451 KParseTokens::IGNORE_LEADING_WS;
00452
00453 const sal_Int32 coNumContFlags =
00454 ( coNumStartFlags | KParseTokens::ASC_DOT ) & ~KParseTokens::IGNORE_LEADING_WS;
00455
00456 void SmParser::NextToken()
00457 {
00458 static const String aEmptyStr;
00459
00460 xub_StrLen nBufLen = BufferString.Len();
00461 ParseResult aRes;
00462 xub_StrLen nRealStart;
00463 BOOL bCont;
00464 BOOL bNumStart = FALSE;
00465 CharClass aCC(SM_MOD1()->GetSysLocale().GetCharClass().getLocale());
00466 do
00467 {
00468
00469 while (UnicodeType::SPACE_SEPARATOR ==
00470 aCC.getType( BufferString, BufferIndex ))
00471 ++BufferIndex;
00472
00473 sal_Int32 nStartFlags = coStartFlags;
00474 sal_Int32 nContFlags = coContFlags;
00475 sal_Unicode cFirstChar = BufferString.GetChar( BufferIndex );
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 aRes = aCC.parseAnyToken( BufferString, BufferIndex,
00486 nStartFlags, aEmptyStr,
00487 nContFlags, aEmptyStr );
00488
00489
00490
00491
00492 if ((aRes.TokenType & KParseType::IDENTNAME) && IsDigit( cFirstChar ))
00493 {
00495 static lang::Locale aDotLoc( SvxCreateLocale( LANGUAGE_ENGLISH_US ) );
00496
00497 ParseResult aTmpRes;
00498 lang::Locale aOldLoc( aCC.getLocale() );
00499 aCC.setLocale( aDotLoc );
00500 aTmpRes = aCC.parsePredefinedToken(
00501 KParseType::ASC_NUMBER,
00502 BufferString, BufferIndex,
00503 KParseTokens::ASC_DIGIT, aEmptyStr,
00504 KParseTokens::ASC_DIGIT | KParseTokens::ASC_DOT, aEmptyStr );
00505 aCC.setLocale( aOldLoc );
00506 if (aTmpRes.TokenType & KParseType::ASC_NUMBER)
00507 aRes.TokenType = aTmpRes.TokenType;
00508 }
00509
00510 nRealStart = BufferIndex + sal::static_int_cast< xub_StrLen >(aRes.LeadingWhiteSpace);
00511 BufferIndex = nRealStart;
00512
00513 bCont = FALSE;
00514 if ( aRes.TokenType == 0 &&
00515 nRealStart < nBufLen &&
00516 '\n' == BufferString.GetChar( nRealStart ) )
00517 {
00518
00519 ++Row;
00520 BufferIndex = ColOff = nRealStart + 1;
00521 bCont = TRUE;
00522 }
00523 else if (aRes.TokenType & KParseType::ONE_SINGLE_CHAR)
00524 {
00525 String aName( BufferString.Copy( nRealStart, 2 ));
00526 if ( aName.EqualsAscii( "%%" ))
00527 {
00528
00529 BufferIndex = nRealStart + 2;
00530 while (BufferIndex < nBufLen &&
00531 '\n' != BufferString.GetChar( BufferIndex ))
00532 ++BufferIndex;
00533 bCont = TRUE;
00534 }
00535 }
00536
00537 } while (bCont);
00538
00539
00540 nTokenIndex = BufferIndex;
00541
00542 CurToken.nRow = Row;
00543 CurToken.nCol = nRealStart - ColOff + 1;
00544
00545 BOOL bHandled = TRUE;
00546 if (nRealStart >= nBufLen)
00547 {
00548 CurToken.eType = TEND;
00549 CurToken.cMathChar = '\0';
00550 CurToken.nGroup = 0;
00551 CurToken.nLevel = 0;
00552 CurToken.aText.Erase();
00553 }
00554 else if ((aRes.TokenType & (KParseType::ASC_NUMBER | KParseType::UNI_NUMBER))
00555 || (bNumStart && (aRes.TokenType & KParseType::IDENTNAME)))
00556 {
00557 INT32 n = aRes.EndPos - nRealStart;
00558 DBG_ASSERT( n >= 0, "length < 0" );
00559 CurToken.eType = TNUMBER;
00560 CurToken.cMathChar = '\0';
00561 CurToken.nGroup = 0;
00562 CurToken.nLevel = 5;
00563 CurToken.aText = BufferString.Copy( nRealStart, sal::static_int_cast< xub_StrLen >(n) );
00564
00565 #if OSL_DEBUG_LEVEL > 1
00566 if (!IsDelimiter( BufferString, static_cast< xub_StrLen >(aRes.EndPos) ))
00567 {
00568 DBG_WARNING( "identifier really finished? (compatibility!)" );
00569 }
00570 #endif
00571 }
00572 else if (aRes.TokenType & KParseType::DOUBLE_QUOTE_STRING)
00573 {
00574 CurToken.eType = TTEXT;
00575 CurToken.cMathChar = '\0';
00576 CurToken.nGroup = 0;
00577 CurToken.nLevel = 5;
00578 CurToken.aText = aRes.DequotedNameOrString;
00579 CurToken.nRow = Row;
00580 CurToken.nCol = nRealStart - ColOff + 2;
00581 }
00582 else if (aRes.TokenType & KParseType::IDENTNAME)
00583 {
00584 INT32 n = aRes.EndPos - nRealStart;
00585 DBG_ASSERT( n >= 0, "length < 0" );
00586 String aName( BufferString.Copy( nRealStart, sal::static_int_cast< xub_StrLen >(n) ) );
00587 const SmTokenTableEntry *pEntry = GetTokenTableEntry( aName );
00588
00589 if (pEntry)
00590 {
00591 CurToken.eType = pEntry->eType;
00592 CurToken.cMathChar = pEntry->cMathChar;
00593 CurToken.nGroup = pEntry->nGroup;
00594 CurToken.nLevel = pEntry->nLevel;
00595 CurToken.aText.AssignAscii( pEntry->pIdent );
00596 }
00597 else
00598 {
00599 CurToken.eType = TIDENT;
00600 CurToken.cMathChar = '\0';
00601 CurToken.nGroup = 0;
00602 CurToken.nLevel = 5;
00603 CurToken.aText = aName;
00604
00605 #if OSL_DEBUG_LEVEL > 1
00606 if (!IsDelimiter( BufferString, static_cast< xub_StrLen >(aRes.EndPos) ))
00607 {
00608 DBG_WARNING( "identifier really finished? (compatibility!)" );
00609 }
00610 #endif
00611 }
00612 }
00613 else if (aRes.TokenType == 0 && '_' == BufferString.GetChar( nRealStart ))
00614 {
00615 CurToken.eType = TRSUB;
00616 CurToken.cMathChar = '\0';
00617 CurToken.nGroup = TGPOWER;
00618 CurToken.nLevel = 0;
00619 CurToken.aText.AssignAscii( "_" );
00620
00621 aRes.EndPos = nRealStart + 1;
00622 }
00623 else if (aRes.TokenType & KParseType::BOOLEAN)
00624 {
00625 sal_Int32 &rnEndPos = aRes.EndPos;
00626 String aName( BufferString.Copy( nRealStart,
00627 sal::static_int_cast< xub_StrLen >(rnEndPos - nRealStart) ));
00628 if (2 >= aName.Len())
00629 {
00630 sal_Unicode ch = aName.GetChar( 0 );
00631 switch (ch)
00632 {
00633 case '<':
00634 {
00635 if (BufferString.Copy( nRealStart, 2 ).
00636 EqualsAscii( "<<" ))
00637 {
00638 CurToken.eType = TLL;
00639 CurToken.cMathChar = MS_LL;
00640 CurToken.nGroup = TGRELATION;
00641 CurToken.nLevel = 0;
00642 CurToken.aText.AssignAscii( "<<" );
00643
00644 rnEndPos = nRealStart + 2;
00645 }
00646 else if (BufferString.Copy( nRealStart, 2 ).
00647 EqualsAscii( "<=" ))
00648 {
00649 CurToken.eType = TLE;
00650 CurToken.cMathChar = MS_LE;
00651 CurToken.nGroup = TGRELATION;
00652 CurToken.nLevel = 0;
00653 CurToken.aText.AssignAscii( "<=" );
00654
00655 rnEndPos = nRealStart + 2;
00656 }
00657 else if (BufferString.Copy( nRealStart, 2 ).
00658 EqualsAscii( "<>" ))
00659 {
00660 CurToken.eType = TNEQ;
00661 CurToken.cMathChar = MS_NEQ;
00662 CurToken.nGroup = TGRELATION;
00663 CurToken.nLevel = 0;
00664 CurToken.aText.AssignAscii( "<>" );
00665
00666 rnEndPos = nRealStart + 2;
00667 }
00668 else if (BufferString.Copy( nRealStart, 3 ).
00669 EqualsAscii( "<?>" ))
00670 {
00671 CurToken.eType = TPLACE;
00672 CurToken.cMathChar = MS_PLACE;
00673 CurToken.nGroup = 0;
00674 CurToken.nLevel = 5;
00675 CurToken.aText.AssignAscii( "<?>" );
00676
00677 rnEndPos = nRealStart + 3;
00678 }
00679 else
00680 {
00681 CurToken.eType = TLT;
00682 CurToken.cMathChar = MS_LT;
00683 CurToken.nGroup = TGRELATION;
00684 CurToken.nLevel = 0;
00685 CurToken.aText.AssignAscii( "<" );
00686 }
00687 }
00688 break;
00689 case '>':
00690 {
00691 if (BufferString.Copy( nRealStart, 2 ).
00692 EqualsAscii( ">=" ))
00693 {
00694 CurToken.eType = TGE;
00695 CurToken.cMathChar = MS_GE;
00696 CurToken.nGroup = TGRELATION;
00697 CurToken.nLevel = 0;
00698 CurToken.aText.AssignAscii( ">=" );
00699
00700 rnEndPos = nRealStart + 2;
00701 }
00702 else if (BufferString.Copy( nRealStart, 2 ).
00703 EqualsAscii( ">>" ))
00704 {
00705 CurToken.eType = TGG;
00706 CurToken.cMathChar = MS_GG;
00707 CurToken.nGroup = TGRELATION;
00708 CurToken.nLevel = 0;
00709 CurToken.aText.AssignAscii( ">>" );
00710
00711 rnEndPos = nRealStart + 2;
00712 }
00713 else
00714 {
00715 CurToken.eType = TGT;
00716 CurToken.cMathChar = MS_GT;
00717 CurToken.nGroup = TGRELATION;
00718 CurToken.nLevel = 0;
00719 CurToken.aText.AssignAscii( ">" );
00720 }
00721 }
00722 break;
00723 default:
00724 bHandled = FALSE;
00725 }
00726 }
00727 }
00728 else if (aRes.TokenType & KParseType::ONE_SINGLE_CHAR)
00729 {
00730 sal_Int32 &rnEndPos = aRes.EndPos;
00731 String aName( BufferString.Copy( nRealStart,
00732 sal::static_int_cast< xub_StrLen >(rnEndPos - nRealStart) ) );
00733
00734 if (1 == aName.Len())
00735 {
00736 sal_Unicode ch = aName.GetChar( 0 );
00737 switch (ch)
00738 {
00739 case '%':
00740 {
00742
00743 DBG_ASSERT( rnEndPos >= nBufLen ||
00744 '%' != BufferString.GetChar( sal::static_int_cast< xub_StrLen >(rnEndPos) ),
00745 "unexpected comment start" );
00746
00747
00748 ParseResult aTmpRes = aCC.parseAnyToken(
00749 BufferString, rnEndPos,
00750 KParseTokens::ANY_LETTER,
00751 aEmptyStr,
00752 coContFlags,
00753 aEmptyStr );
00754
00755 xub_StrLen nTmpStart = sal::static_int_cast< xub_StrLen >(rnEndPos +
00756 aTmpRes.LeadingWhiteSpace);
00757
00758
00759
00760
00761 CurToken.eType = TTEXT;
00762 CurToken.cMathChar = '\0';
00763 CurToken.nGroup = 0;
00764 CurToken.nLevel = 5;
00765 CurToken.aText = String();
00766 CurToken.nRow = sal::static_int_cast< xub_StrLen >(Row);
00767 CurToken.nCol = nTmpStart - ColOff + 1;
00768
00769 if (aTmpRes.TokenType & KParseType::IDENTNAME)
00770 {
00771
00772 xub_StrLen n = sal::static_int_cast< xub_StrLen >(aTmpRes.EndPos - nTmpStart);
00773 CurToken.eType = TSPECIAL;
00774 CurToken.aText = BufferString.Copy( sal::static_int_cast< xub_StrLen >(nTmpStart), n );
00775
00776 DBG_ASSERT( aTmpRes.EndPos > rnEndPos,
00777 "empty identifier" );
00778 if (aTmpRes.EndPos > rnEndPos)
00779 rnEndPos = aTmpRes.EndPos;
00780 else
00781 ++rnEndPos;
00782 }
00783
00784
00785
00786
00787 }
00788 break;
00789 case '[':
00790 {
00791 CurToken.eType = TLBRACKET;
00792 CurToken.cMathChar = MS_LBRACKET;
00793 CurToken.nGroup = TGLBRACES;
00794 CurToken.nLevel = 5;
00795 CurToken.aText.AssignAscii( "[" );
00796 }
00797 break;
00798 case '\\':
00799 {
00800 CurToken.eType = TESCAPE;
00801 CurToken.cMathChar = '\0';
00802 CurToken.nGroup = 0;
00803 CurToken.nLevel = 5;
00804 CurToken.aText.AssignAscii( "\\" );
00805 }
00806 break;
00807 case ']':
00808 {
00809 CurToken.eType = TRBRACKET;
00810 CurToken.cMathChar = MS_RBRACKET;
00811 CurToken.nGroup = TGRBRACES;
00812 CurToken.nLevel = 0;
00813 CurToken.aText.AssignAscii( "]" );
00814 }
00815 break;
00816 case '^':
00817 {
00818 CurToken.eType = TRSUP;
00819 CurToken.cMathChar = '\0';
00820 CurToken.nGroup = TGPOWER;
00821 CurToken.nLevel = 0;
00822 CurToken.aText.AssignAscii( "^" );
00823 }
00824 break;
00825 case '`':
00826 {
00827 CurToken.eType = TSBLANK;
00828 CurToken.cMathChar = '\0';
00829 CurToken.nGroup = TGBLANK;
00830 CurToken.nLevel = 5;
00831 CurToken.aText.AssignAscii( "`" );
00832 }
00833 break;
00834 case '{':
00835 {
00836 CurToken.eType = TLGROUP;
00837 CurToken.cMathChar = MS_LBRACE;
00838 CurToken.nGroup = 0;
00839 CurToken.nLevel = 5;
00840 CurToken.aText.AssignAscii( "{" );
00841 }
00842 break;
00843 case '|':
00844 {
00845 CurToken.eType = TOR;
00846 CurToken.cMathChar = MS_OR;
00847 CurToken.nGroup = TGSUM;
00848 CurToken.nLevel = 0;
00849 CurToken.aText.AssignAscii( "|" );
00850 }
00851 break;
00852 case '}':
00853 {
00854 CurToken.eType = TRGROUP;
00855 CurToken.cMathChar = MS_RBRACE;
00856 CurToken.nGroup = 0;
00857 CurToken.nLevel = 0;
00858 CurToken.aText.AssignAscii( "}" );
00859 }
00860 break;
00861 case '~':
00862 {
00863 CurToken.eType = TBLANK;
00864 CurToken.cMathChar = '\0';
00865 CurToken.nGroup = TGBLANK;
00866 CurToken.nLevel = 5;
00867 CurToken.aText.AssignAscii( "~" );
00868 }
00869 break;
00870 case '#':
00871 {
00872 if (BufferString.Copy( nRealStart, 2 ).
00873 EqualsAscii( "##" ))
00874 {
00875 CurToken.eType = TDPOUND;
00876 CurToken.cMathChar = '\0';
00877 CurToken.nGroup = 0;
00878 CurToken.nLevel = 0;
00879 CurToken.aText.AssignAscii( "##" );
00880
00881 rnEndPos = nRealStart + 2;
00882 }
00883 else
00884 {
00885 CurToken.eType = TPOUND;
00886 CurToken.cMathChar = '\0';
00887 CurToken.nGroup = 0;
00888 CurToken.nLevel = 0;
00889 CurToken.aText.AssignAscii( "#" );
00890 }
00891 }
00892 break;
00893 case '&':
00894 {
00895 CurToken.eType = TAND;
00896 CurToken.cMathChar = MS_AND;
00897 CurToken.nGroup = TGPRODUCT;
00898 CurToken.nLevel = 0;
00899 CurToken.aText.AssignAscii( "&" );
00900 }
00901 break;
00902 case '(':
00903 {
00904 CurToken.eType = TLPARENT;
00905 CurToken.cMathChar = MS_LPARENT;
00906 CurToken.nGroup = TGLBRACES;
00907 CurToken.nLevel = 5;
00908 CurToken.aText.AssignAscii( "(" );
00909 }
00910 break;
00911 case ')':
00912 {
00913 CurToken.eType = TRPARENT;
00914 CurToken.cMathChar = MS_RPARENT;
00915 CurToken.nGroup = TGRBRACES;
00916 CurToken.nLevel = 0;
00917 CurToken.aText.AssignAscii( ")" );
00918 }
00919 break;
00920 case '*':
00921 {
00922 CurToken.eType = TMULTIPLY;
00923 CurToken.cMathChar = MS_MULTIPLY;
00924 CurToken.nGroup = TGPRODUCT;
00925 CurToken.nLevel = 0;
00926 CurToken.aText.AssignAscii( "*" );
00927 }
00928 break;
00929 case '+':
00930 {
00931 if (BufferString.Copy( nRealStart, 2 ).
00932 EqualsAscii( "+-" ))
00933 {
00934 CurToken.eType = TPLUSMINUS;
00935 CurToken.cMathChar = MS_PLUSMINUS;
00936 CurToken.nGroup = TGUNOPER | TGSUM;
00937 CurToken.nLevel = 5;
00938 CurToken.aText.AssignAscii( "+-" );
00939
00940 rnEndPos = nRealStart + 2;
00941 }
00942 else
00943 {
00944 CurToken.eType = TPLUS;
00945 CurToken.cMathChar = MS_PLUS;
00946 CurToken.nGroup = TGUNOPER | TGSUM;
00947 CurToken.nLevel = 5;
00948 CurToken.aText.AssignAscii( "+" );
00949 }
00950 }
00951 break;
00952 case '-':
00953 {
00954 if (BufferString.Copy( nRealStart, 2 ).
00955 EqualsAscii( "-+" ))
00956 {
00957 CurToken.eType = TMINUSPLUS;
00958 CurToken.cMathChar = MS_MINUSPLUS;
00959 CurToken.nGroup = TGUNOPER | TGSUM;
00960 CurToken.nLevel = 5;
00961 CurToken.aText.AssignAscii( "-+" );
00962
00963 rnEndPos = nRealStart + 2;
00964 }
00965 else
00966 {
00967 CurToken.eType = TMINUS;
00968 CurToken.cMathChar = MS_MINUS;
00969 CurToken.nGroup = TGUNOPER | TGSUM;
00970 CurToken.nLevel = 5;
00971 CurToken.aText.AssignAscii( "-" );
00972 }
00973 }
00974 break;
00975 case '.':
00976 {
00977
00978
00979
00980 CurToken.eType = TNUMBER;
00981 CurToken.cMathChar = '\0';
00982 CurToken.nGroup = 0;
00983 CurToken.nLevel = 5;
00984
00985 xub_StrLen nTxtStart = BufferIndex;
00986 sal_Unicode cChar;
00987 do
00988 {
00989 cChar = BufferString.GetChar( ++BufferIndex );
00990 }
00991 while ( cChar == '.' || IsDigit( cChar ) );
00992
00993 CurToken.aText = BufferString.Copy( sal::static_int_cast< xub_StrLen >(nTxtStart),
00994 sal::static_int_cast< xub_StrLen >(BufferIndex - nTxtStart) );
00995 aRes.EndPos = BufferIndex;
00996 }
00997 break;
00998 case '/':
00999 {
01000 CurToken.eType = TDIVIDEBY;
01001 CurToken.cMathChar = MS_SLASH;
01002 CurToken.nGroup = TGPRODUCT;
01003 CurToken.nLevel = 0;
01004 CurToken.aText.AssignAscii( "/" );
01005 }
01006 break;
01007 case '=':
01008 {
01009 CurToken.eType = TASSIGN;
01010 CurToken.cMathChar = MS_ASSIGN;
01011 CurToken.nGroup = TGRELATION;
01012 CurToken.nLevel = 0;
01013 CurToken.aText.AssignAscii( "=" );
01014 }
01015 break;
01016 default:
01017 bHandled = FALSE;
01018 }
01019 }
01020 }
01021 else
01022 bHandled = FALSE;
01023
01024 if (!bHandled)
01025 {
01026 CurToken.eType = TCHARACTER;
01027 CurToken.cMathChar = '\0';
01028 CurToken.nGroup = 0;
01029 CurToken.nLevel = 5;
01030 CurToken.aText = BufferString.Copy( nRealStart, 1 );
01031
01032 aRes.EndPos = nRealStart + 1;
01033 }
01034
01035 if (TEND != CurToken.eType)
01036 BufferIndex = sal::static_int_cast< xub_StrLen >(aRes.EndPos);
01037 }
01038
01039
01041
01042
01043
01044
01045 void SmParser::Table()
01046 {
01047 SmNodeArray LineArray;
01048
01049 Line();
01050 while (CurToken.eType == TNEWLINE)
01051 {
01052 NextToken();
01053 Line();
01054 }
01055
01056 if (CurToken.eType != TEND)
01057 Error(PE_UNEXPECTED_CHAR);
01058
01059 ULONG n = NodeStack.Count();
01060
01061 LineArray.SetSize(n);
01062
01063 for (ULONG i = 0; i < n; i++)
01064 LineArray.Put(n - (i + 1), NodeStack.Pop());
01065
01066 SmStructureNode *pSNode = new SmTableNode(CurToken);
01067 pSNode->SetSubNodes(LineArray);
01068 NodeStack.Push(pSNode);
01069 }
01070
01071
01072 void SmParser::Align()
01073
01074 {
01075 SmStructureNode *pSNode = 0;
01076 BOOL bNeedGroupClose = FALSE;
01077
01078 if (TokenInGroup(TGALIGN))
01079 {
01080 if (CONVERT_40_TO_50 == GetConversion())
01081
01082
01083 { Insert('{', GetTokenIndex());
01084 bNeedGroupClose = TRUE;
01085
01086
01087
01088
01089 while (TokenInGroup(TGALIGN))
01090 { if (TokenInGroup(TGDISCARDED) || pSNode)
01091 { BufferIndex = GetTokenIndex();
01092 BufferString.Erase(BufferIndex, CurToken.aText.Len());
01093 }
01094 else
01095 pSNode = new SmAlignNode(CurToken);
01096
01097 NextToken();
01098 }
01099 }
01100 else
01101 {
01102 pSNode = new SmAlignNode(CurToken);
01103
01104 NextToken();
01105
01106
01107 if (CONVERT_40_TO_50 != GetConversion() && TokenInGroup(TGALIGN))
01108 { Error(PE_DOUBLE_ALIGN);
01109 return;
01110 }
01111 }
01112 }
01113
01114 Expression();
01115
01116 if (bNeedGroupClose)
01117 Insert('}', GetTokenIndex());
01118
01119 if (pSNode)
01120 { pSNode->SetSubNodes(NodeStack.Pop(), 0);
01121 NodeStack.Push(pSNode);
01122 }
01123 }
01124
01125
01126 void SmParser::Line()
01127 {
01128 USHORT n = 0;
01129 SmNodeArray ExpressionArray;
01130
01131 ExpressionArray.SetSize(n);
01132
01133
01134
01135
01136 if (CurToken.eType != TEND && CurToken.eType != TNEWLINE)
01137 { Align();
01138 ExpressionArray.SetSize(++n);
01139 ExpressionArray.Put(n - 1, NodeStack.Pop());
01140 }
01141
01142 while (CurToken.eType != TEND && CurToken.eType != TNEWLINE)
01143 { if (CONVERT_40_TO_50 != GetConversion())
01144 Expression();
01145 else
01146 Align();
01147 ExpressionArray.SetSize(++n);
01148 ExpressionArray.Put(n - 1, NodeStack.Pop());
01149 }
01150
01151 SmStructureNode *pSNode = new SmLineNode(CurToken);
01152 pSNode->SetSubNodes(ExpressionArray);
01153 NodeStack.Push(pSNode);
01154 }
01155
01156
01157 void SmParser::Expression()
01158 {
01159 USHORT n = 0;
01160 SmNodeArray RelationArray;
01161
01162 RelationArray.SetSize(n);
01163
01164 Relation();
01165 RelationArray.SetSize(++n);
01166 RelationArray.Put(n - 1, NodeStack.Pop());
01167
01168 while (CurToken.nLevel >= 4)
01169 { Relation();
01170 RelationArray.SetSize(++n);
01171 RelationArray.Put(n - 1, NodeStack.Pop());
01172 }
01173
01174 SmStructureNode *pSNode = new SmExpressionNode(CurToken);
01175 pSNode->SetSubNodes(RelationArray);
01176 NodeStack.Push(pSNode);
01177 }
01178
01179
01180 void SmParser::Relation()
01181 {
01182 Sum();
01183 while (TokenInGroup(TGRELATION))
01184 {
01185 SmStructureNode *pSNode = new SmBinHorNode(CurToken);
01186 SmNode *pFirst = NodeStack.Pop();
01187
01188 OpSubSup();
01189 SmNode *pSecond = NodeStack.Pop();
01190
01191 Sum();
01192
01193 pSNode->SetSubNodes(pFirst, pSecond, NodeStack.Pop());
01194 NodeStack.Push(pSNode);
01195 }
01196 }
01197
01198
01199 void SmParser::Sum()
01200 {
01201 Product();
01202 while (TokenInGroup(TGSUM))
01203 {
01204 SmStructureNode *pSNode = new SmBinHorNode(CurToken);
01205 SmNode *pFirst = NodeStack.Pop();
01206
01207 OpSubSup();
01208 SmNode *pSecond = NodeStack.Pop();
01209
01210 Product();
01211
01212 pSNode->SetSubNodes(pFirst, pSecond, NodeStack.Pop());
01213 NodeStack.Push(pSNode);
01214 }
01215 }
01216
01217
01218 void SmParser::Product()
01219 {
01220 Power();
01221
01222 while (TokenInGroup(TGPRODUCT))
01223 { SmStructureNode *pSNode;
01224 SmNode *pFirst = NodeStack.Pop(),
01225 *pOper;
01226 BOOL bSwitchArgs = FALSE;
01227
01228 SmTokenType eType = CurToken.eType;
01229 switch (eType)
01230 {
01231 case TOVER:
01232 pSNode = new SmBinVerNode(CurToken);
01233 pOper = new SmRectangleNode(CurToken);
01234 NextToken();
01235 break;
01236
01237 case TBOPER:
01238 pSNode = new SmBinHorNode(CurToken);
01239
01240 NextToken();
01241
01242 GlyphSpecial();
01243 pOper = NodeStack.Pop();
01244 break;
01245
01246 case TOVERBRACE :
01247 case TUNDERBRACE :
01248 pSNode = new SmVerticalBraceNode(CurToken);
01249 pOper = new SmMathSymbolNode(CurToken);
01250
01251 NextToken();
01252 break;
01253
01254 case TWIDEBACKSLASH:
01255 case TWIDESLASH:
01256 {
01257 SmBinDiagonalNode *pSTmp = new SmBinDiagonalNode(CurToken);
01258 pSTmp->SetAscending(eType == TWIDESLASH);
01259 pSNode = pSTmp;
01260
01261 pOper = new SmPolyLineNode(CurToken);
01262 NextToken();
01263
01264 bSwitchArgs =TRUE;
01265 break;
01266 }
01267
01268 default:
01269 pSNode = new SmBinHorNode(CurToken);
01270
01271 OpSubSup();
01272 pOper = NodeStack.Pop();
01273 }
01274
01275 Power();
01276
01277 if (bSwitchArgs)
01279 pSNode->SetSubNodes(pFirst, NodeStack.Pop(), pOper);
01280 else
01281 pSNode->SetSubNodes(pFirst, pOper, NodeStack.Pop());
01282 NodeStack.Push(pSNode);
01283 }
01284 }
01285
01286
01287 void SmParser::SubSup(ULONG nActiveGroup)
01288 {
01289 DBG_ASSERT(nActiveGroup == TGPOWER || nActiveGroup == TGLIMIT,
01290 "Sm: falsche Tokengruppe");
01291
01292 if (!TokenInGroup(nActiveGroup))
01293
01294 return;
01295
01296 SmSubSupNode *pNode = new SmSubSupNode(CurToken);
01301
01302 pNode->SetUseLimits(nActiveGroup == TGLIMIT);
01303
01304
01305 SmNodeArray aSubNodes;
01306 aSubNodes.SetSize(1 + SUBSUP_NUM_ENTRIES);
01307 aSubNodes.Put(0, NodeStack.Pop());
01308 for (USHORT i = 1; i < aSubNodes.GetSize(); i++)
01309 aSubNodes.Put(i, NULL);
01310
01311
01312 int nIndex = 0;
01313 while (TokenInGroup(nActiveGroup))
01314 { SmTokenType eType (CurToken.eType);
01315
01316
01317 NextToken();
01318
01319
01320 if (eType == TFROM || eType == TTO)
01321 {
01322
01323 Relation();
01324 }
01325 else
01326 Term();
01327
01328 switch (eType)
01329 { case TRSUB : nIndex = (int) RSUB; break;
01330 case TRSUP : nIndex = (int) RSUP; break;
01331 case TFROM :
01332 case TCSUB : nIndex = (int) CSUB; break;
01333 case TTO :
01334 case TCSUP : nIndex = (int) CSUP; break;
01335 case TLSUB : nIndex = (int) LSUB; break;
01336 case TLSUP : nIndex = (int) LSUP; break;
01337 default :
01338 DBG_ASSERT(FALSE, "Sm: unbekannter Fall");
01339 }
01340 nIndex++;
01341 DBG_ASSERT(1 <= nIndex && nIndex <= 1 + SUBSUP_NUM_ENTRIES,
01342 "SmParser::Power() : sub-/supscript index falsch")
01343
01344
01345 if (aSubNodes.Get(nIndex) != NULL)
01346 Error(PE_DOUBLE_SUBSUPSCRIPT);
01347 aSubNodes.Put(nIndex, NodeStack.Pop());
01348 }
01349
01350 pNode->SetSubNodes(aSubNodes);
01351 NodeStack.Push(pNode);
01352 }
01353
01354
01355 void SmParser::OpSubSup()
01356 {
01357
01358 NodeStack.Push(new SmMathSymbolNode(CurToken));
01359
01360 NextToken();
01361
01362 if (TokenInGroup(TGPOWER))
01363 SubSup(TGPOWER);
01364 }
01365
01366
01367 void SmParser::Power()
01368 {
01369
01370 Term();
01371
01372 SubSup(TGPOWER);
01373 }
01374
01375
01376 void SmParser::Blank()
01377 {
01378 DBG_ASSERT(TokenInGroup(TGBLANK), "Sm : falsches Token");
01379 SmBlankNode *pBlankNode = new SmBlankNode(CurToken);
01380
01381 while (TokenInGroup(TGBLANK))
01382 {
01383 pBlankNode->IncreaseBy(CurToken);
01384 NextToken();
01385 }
01386
01387
01388 if (CurToken.eType == TNEWLINE || CurToken.eType == TEND
01389 && SM_MOD1()->GetConfig()->IsIgnoreSpacesRight())
01390 pBlankNode->Clear();
01391
01392 NodeStack.Push(pBlankNode);
01393 }
01394
01395
01396 void SmParser::Term()
01397 {
01398 switch (CurToken.eType)
01399 { case TESCAPE :
01400 Escape();
01401 break;
01402
01403 case TLGROUP :
01404 NextToken();
01405
01406
01407 if (CurToken.eType == TRGROUP)
01408 { SmStructureNode *pSNode = new SmExpressionNode(CurToken);
01409 pSNode->SetSubNodes(NULL, NULL);
01410 NodeStack.Push(pSNode);
01411
01412 NextToken();
01413 }
01414 else
01415 { Align();
01416 if (CurToken.eType != TRGROUP)
01417 Error(PE_RGROUP_EXPECTED);
01418 else
01419 { NextToken();
01420 }
01421 }
01422 break;
01423
01424 case TLEFT :
01425 Brace();
01426 break;
01427
01428 case TBLANK :
01429 case TSBLANK :
01430 Blank();
01431 break;
01432
01433 case TTEXT :
01434 NodeStack.Push(new SmTextNode(CurToken, FNT_TEXT));
01435 NextToken();
01436 break;
01437 case TIDENT :
01438 case TCHARACTER :
01439 NodeStack.Push(new SmTextNode(CurToken, FNT_VARIABLE));
01440 NextToken();
01441 break;
01442 case TNUMBER :
01443 NodeStack.Push(new SmTextNode(CurToken, FNT_NUMBER));
01444 NextToken();
01445 break;
01446
01447 case TLEFTARROW :
01448 case TRIGHTARROW :
01449 case TUPARROW :
01450 case TDOWNARROW :
01451 case TSETN :
01452 case TSETZ :
01453 case TSETQ :
01454 case TSETR :
01455 case TSETC :
01456 case THBAR :
01457 case TLAMBDABAR :
01458 case TCIRC :
01459 case TDRARROW :
01460 case TDLARROW :
01461 case TDLRARROW :
01462 case TBACKEPSILON :
01463 case TALEPH :
01464 case TIM :
01465 case TRE :
01466 case TWP :
01467 case TEMPTYSET :
01468 case TINFINITY :
01469 case TEXISTS :
01470 case TFORALL :
01471 case TPARTIAL :
01472 case TNABLA :
01473 case TTOWARD :
01474 case TDOTSAXIS :
01475 case TDOTSDIAG :
01476 case TDOTSDOWN :
01477 case TDOTSLOW :
01478 case TDOTSUP :
01479 case TDOTSVERT :
01480 NodeStack.Push(new SmMathSymbolNode(CurToken));
01481 NextToken();
01482 break;
01483
01484 case TPLACE:
01485 NodeStack.Push(new SmPlaceNode(CurToken));
01486 NextToken();
01487 break;
01488
01489 case TSPECIAL:
01490 Special();
01491 break;
01492
01493 case TBINOM:
01494 Binom();
01495 break;
01496
01497 case TSTACK:
01498 Stack();
01499 break;
01500
01501 case TMATRIX:
01502 Matrix();
01503 break;
01504
01505 default:
01506 if (TokenInGroup(TGLBRACES))
01507 { Brace();
01508 }
01509 else if (TokenInGroup(TGOPER))
01510 { Operator();
01511 }
01512 else if (TokenInGroup(TGUNOPER))
01513 { UnOper();
01514 }
01515 else if ( TokenInGroup(TGATTRIBUT)
01516 || TokenInGroup(TGFONTATTR))
01517 { SmStructureNodeArray aArray;
01518
01519 BOOL bIsAttr;
01520 USHORT n = 0;
01521 while (TRUE == (bIsAttr = TokenInGroup(TGATTRIBUT))
01522 || TokenInGroup(TGFONTATTR))
01523 { aArray.SetSize(n + 1);
01524
01525 if (bIsAttr)
01526 Attribut();
01527 else
01528 FontAttribut();
01529
01530
01531 DBG_ASSERT(!NodeStack.Top()->IsVisible(), "Sm : Ooops...");
01532
01533 aArray.Put(n, (SmStructureNode *) NodeStack.Pop());
01534 n++;
01535 }
01536
01537 Power();
01538
01539 SmNode *pFirstNode = NodeStack.Pop();
01540 while (n > 0)
01541 { aArray.Get(n - 1)->SetSubNodes(0, pFirstNode);
01542 pFirstNode = aArray.Get(n - 1);
01543 n--;
01544 }
01545 NodeStack.Push(pFirstNode);
01546 }
01547 else if (TokenInGroup(TGFUNCTION))
01548 { if (CONVERT_40_TO_50 != GetConversion())
01549 { Function();
01550 }
01551 else
01552 {
01553
01554 Insert('{', GetTokenIndex());
01555
01556
01557
01558
01559 Function();
01560
01561 SmNode *pFunc = NodeStack.Pop();
01562
01563 if (CurToken.eType == TLPARENT)
01564 { Term();
01565 }
01566 else
01567 { Align();
01568 }
01569
01570
01571 Insert('}', GetTokenIndex());
01572
01573 SmStructureNode *pSNode = new SmExpressionNode(pFunc->GetToken());
01574 pSNode->SetSubNodes(pFunc, NodeStack.Pop());
01575 NodeStack.Push(pSNode);
01576 }
01577 }
01578 else
01579 Error(PE_UNEXPECTED_CHAR);
01580 }
01581 }
01582
01583
01584 void SmParser::Escape()
01585 {
01586 NextToken();
01587
01588 sal_Unicode cChar;
01589 switch (CurToken.eType)
01590 { case TLPARENT : cChar = MS_LPARENT; break;
01591 case TRPARENT : cChar = MS_RPARENT; break;
01592 case TLBRACKET : cChar = MS_LBRACKET; break;
01593 case TRBRACKET : cChar = MS_RBRACKET; break;
01594 case TLDBRACKET : cChar = MS_LDBRACKET; break;
01595 case TRDBRACKET : cChar = MS_RDBRACKET; break;
01596 case TLBRACE :
01597 case TLGROUP : cChar = MS_LBRACE; break;
01598 case TRBRACE :
01599 case TRGROUP : cChar = MS_RBRACE; break;
01600 case TLANGLE : cChar = MS_LANGLE; break;
01601 case TRANGLE : cChar = MS_RANGLE; break;
01602 case TLCEIL : cChar = MS_LCEIL; break;
01603 case TRCEIL : cChar = MS_RCEIL; break;
01604 case TLFLOOR : cChar = MS_LFLOOR; break;
01605 case TRFLOOR : cChar = MS_RFLOOR; break;
01606 case TLLINE :
01607 case TRLINE : cChar = MS_LINE; break;
01608 case TLDLINE :
01609 case TRDLINE : cChar = MS_DLINE; break;
01610 default:
01611 Error(PE_UNEXPECTED_TOKEN);
01612 }
01613
01614 SmNode *pNode = new SmMathSymbolNode(CurToken);
01615 NodeStack.Push(pNode);
01616
01617 NextToken();
01618 }
01619
01620
01621 void SmParser::Operator()
01622 {
01623 if (TokenInGroup(TGOPER))
01624 { SmStructureNode *pSNode = new SmOperNode(CurToken);
01625
01626
01627 Oper();
01628
01629 if (TokenInGroup(TGLIMIT) || TokenInGroup(TGPOWER))
01630 SubSup(CurToken.nGroup);
01631 SmNode *pOperator = NodeStack.Pop();
01632
01633
01634 Power();
01635
01636 pSNode->SetSubNodes(pOperator, NodeStack.Pop());
01637 NodeStack.Push(pSNode);
01638 }
01639 }
01640
01641
01642 void SmParser::Oper()
01643 {
01644 SmTokenType eType (CurToken.eType);
01645 SmNode *pNode = NULL;
01646
01647 switch (eType)
01648 {
01649 case TSUM :
01650 case TPROD :
01651 case TCOPROD :
01652 case TINT :
01653 case TIINT :
01654 case TIIINT :
01655 case TLINT :
01656 case TLLINT :
01657 case TLLLINT :
01658 pNode = new SmMathSymbolNode(CurToken);
01659 break;
01660
01661 case TLIM :
01662 case TLIMSUP :
01663 case TLIMINF :
01664 {
01665 const sal_Char* pLim = 0;
01666 switch (eType)
01667 {
01668 case TLIM : pLim = "lim"; break;
01669 case TLIMSUP : pLim = "lim sup"; break;
01670 case TLIMINF : pLim = "lim inf"; break;
01671 default:
01672 break;
01673 }
01674 if( pLim )
01675 CurToken.aText.AssignAscii( pLim );
01676 pNode = new SmTextNode(CurToken, FNT_TEXT);
01677 }
01678 break;
01679
01680 case TOVERBRACE :
01681 case TUNDERBRACE :
01682 pNode = new SmMathSymbolNode(CurToken);
01683 break;
01684
01685 case TOPER :
01686 NextToken();
01687
01688 DBG_ASSERT(CurToken.eType == TSPECIAL, "Sm: falsches Token");
01689 pNode = new SmGlyphSpecialNode(CurToken);
01690 break;
01691
01692 default :
01693 DBG_ASSERT(0, "Sm: unbekannter Fall");
01694 }
01695 NodeStack.Push(pNode);
01696
01697 NextToken();
01698 }
01699
01700
01701 void SmParser::UnOper()
01702 {
01703 DBG_ASSERT(TokenInGroup(TGUNOPER), "Sm: falsches Token");
01704
01705 SmToken aNodeToken = CurToken;
01706 SmTokenType eType = CurToken.eType;
01707 BOOL bIsPostfix = eType == TFACT;
01708
01709 SmStructureNode *pSNode;
01710 SmNode *pOper = 0,
01711 *pExtra = 0,
01712 *pArg;
01713
01714 switch (eType)
01715 {
01716 case TABS :
01717 case TSQRT :
01718 NextToken();
01719 break;
01720
01721 case TNROOT :
01722 NextToken();
01723 Power();
01724 pExtra = NodeStack.Pop();
01725 break;
01726
01727 case TUOPER :
01728 NextToken();
01729 GlyphSpecial();
01730 pOper = NodeStack.Pop();
01731 break;
01732
01733 case TPLUS :
01734 case TMINUS :
01735 case TPLUSMINUS :
01736 case TMINUSPLUS :
01737 case TNEG :
01738 case TFACT :
01739 OpSubSup();
01740 pOper = NodeStack.Pop();
01741 break;
01742
01743 default :
01744 Error(PE_UNOPER_EXPECTED);
01745 }
01746
01747
01748 Power();
01749 pArg = NodeStack.Pop();
01750
01751 if (eType == TABS)
01752 { pSNode = new SmBraceNode(aNodeToken);
01753 pSNode->SetScaleMode(SCALE_HEIGHT);
01754
01755
01756
01757
01758 aNodeToken.eType = TABS;
01759
01760 aNodeToken.cMathChar = MS_LINE;
01761 SmNode* pLeft = new SmMathSymbolNode(aNodeToken);
01762
01763 aNodeToken.cMathChar = MS_LINE;
01764 SmNode* pRight = new SmMathSymbolNode(aNodeToken);
01765
01766 pSNode->SetSubNodes(pLeft, pArg, pRight);
01767 }
01768 else if (eType == TSQRT || eType == TNROOT)
01769 { pSNode = new SmRootNode(aNodeToken);
01770 pOper = new SmRootSymbolNode(aNodeToken);
01771 pSNode->SetSubNodes(pExtra, pOper, pArg);
01772 }
01773 else
01774 { pSNode = new SmUnHorNode(aNodeToken);
01775
01776 if (bIsPostfix)
01777 pSNode->SetSubNodes(pArg, pOper);
01778 else
01779
01780 pSNode->SetSubNodes(pOper, pArg);
01781 }
01782
01783 NodeStack.Push(pSNode);
01784 }
01785
01786
01787 void SmParser::Attribut()
01788 {
01789 DBG_ASSERT(TokenInGroup(TGATTRIBUT), "Sm: falsche Tokengruppe");
01790
01791 SmStructureNode *pSNode = new SmAttributNode(CurToken);
01792 SmNode *pAttr;
01793 SmScaleMode eScaleMode = SCALE_NONE;
01794
01795
01796 switch (CurToken.eType)
01797 { case TUNDERLINE :
01798 case TOVERLINE :
01799 case TOVERSTRIKE :
01800 pAttr = new SmRectangleNode(CurToken);
01801 eScaleMode = SCALE_WIDTH;
01802 break;
01803
01804 case TWIDEVEC :
01805 case TWIDEHAT :
01806 case TWIDETILDE :
01807 pAttr = new SmMathSymbolNode(CurToken);
01808 eScaleMode = SCALE_WIDTH;
01809 break;
01810
01811 default :
01812 pAttr = new SmMathSymbolNode(CurToken);
01813 }
01814
01815 NextToken();
01816
01817 pSNode->SetSubNodes(pAttr, 0);
01818 pSNode->SetScaleMode(eScaleMode);
01819 NodeStack.Push(pSNode);
01820 }
01821
01822
01823 void SmParser::FontAttribut()
01824 {
01825 DBG_ASSERT(TokenInGroup(TGFONTATTR), "Sm: falsche Tokengruppe");
01826
01827 switch (CurToken.eType)
01828 {
01829 case TITALIC :
01830 case TNITALIC :
01831 case TBOLD :
01832 case TNBOLD :
01833 case TPHANTOM :
01834 NodeStack.Push(new SmFontNode(CurToken));
01835 NextToken();
01836 break;
01837
01838 case TSIZE :
01839 FontSize();
01840 break;
01841
01842 case TFONT :
01843 Font();
01844 break;
01845
01846 case TCOLOR :
01847 Color();
01848 break;
01849
01850 default :
01851 DBG_ASSERT(0, "Sm: unbekannter Fall");
01852 }
01853 }
01854
01855
01856 void SmParser::Color()
01857 {
01858 DBG_ASSERT(CurToken.eType == TCOLOR, "Sm : Ooops...");
01859
01860
01861 SmToken aToken;
01862 do
01863 { NextToken();
01864
01865 if (TokenInGroup(TGCOLOR))
01866 { aToken = CurToken;
01867 NextToken();
01868 }
01869 else
01870 Error(PE_COLOR_EXPECTED);
01871 } while (CurToken.eType == TCOLOR);
01872
01873 NodeStack.Push(new SmFontNode(aToken));
01874 }
01875
01876
01877 void SmParser::Font()
01878 {
01879 DBG_ASSERT(CurToken.eType == TFONT, "Sm : Ooops...");
01880
01881
01882 SmToken aToken;
01883 do
01884 { NextToken();
01885
01886 if (TokenInGroup(TGFONT))
01887 { aToken = CurToken;
01888 NextToken();
01889 }
01890 else
01891 Error(PE_FONT_EXPECTED);
01892 } while (CurToken.eType == TFONT);
01893
01894 NodeStack.Push(new SmFontNode(aToken));
01895 }
01896
01897
01898
01899
01900 BOOL lcl_IsNumber(const UniString& rText)
01901 {
01902 BOOL bPoint = FALSE;
01903 const sal_Unicode* pBuffer = rText.GetBuffer();
01904 for(xub_StrLen nPos = 0; nPos < rText.Len(); nPos++, pBuffer++)
01905 {
01906 const sal_Unicode cChar = *pBuffer;
01907 if(cChar == '.')
01908 {
01909 if(bPoint)
01910 return FALSE;
01911 else
01912 bPoint = TRUE;
01913 }
01914 else if ( !IsDigit( cChar ) )
01915 return FALSE;
01916 }
01917 return TRUE;
01918 }
01919
01920 void SmParser::FontSize()
01921 {
01922 DBG_ASSERT(CurToken.eType == TSIZE, "Sm : Ooops...");
01923
01924 USHORT Type;
01925 SmFontNode *pFontNode = new SmFontNode(CurToken);
01926
01927 NextToken();
01928
01929 switch (CurToken.eType)
01930 {
01931 case TNUMBER: Type = FNTSIZ_ABSOLUT; break;
01932 case TPLUS: Type = FNTSIZ_PLUS; break;
01933 case TMINUS: Type = FNTSIZ_MINUS; break;
01934 case TMULTIPLY: Type = FNTSIZ_MULTIPLY; break;
01935 case TDIVIDEBY: Type = FNTSIZ_DIVIDE; break;
01936
01937 default:
01938 delete pFontNode;
01939 Error(PE_SIZE_EXPECTED);
01940 return;
01941 }
01942
01943 if (Type != FNTSIZ_ABSOLUT)
01944 {
01945 NextToken();
01946 if (CurToken.eType != TNUMBER)
01947 {
01948 delete pFontNode;
01949 Error(PE_SIZE_EXPECTED);
01950 return;
01951 }
01952 }
01953
01954
01955 Fraction aValue( 1L );
01956 if (lcl_IsNumber( CurToken.aText ))
01957 {
01958 double fTmp;
01959 if ((fTmp = CurToken.aText.ToDouble()) != 0.0)
01960 {
01961 aValue = fTmp;
01962
01968 if (aValue.GetDenominator() > 1000)
01969 {
01970 long nNum = aValue.GetNumerator();
01971 long nDenom = aValue.GetDenominator();
01972 while (nDenom > 1000)
01973 {
01974 nNum /= 10;
01975 nDenom /= 10;
01976 }
01977 aValue = Fraction( nNum, nDenom );
01978 }
01979 }
01980 }
01981
01982 NextToken();
01983
01984 pFontNode->SetSizeParameter(aValue, Type);
01985 NodeStack.Push(pFontNode);
01986 }
01987
01988
01989 void SmParser::Brace()
01990 {
01991 DBG_ASSERT(CurToken.eType == TLEFT || TokenInGroup(TGLBRACES),
01992 "Sm: kein Klammer Ausdruck");
01993
01994 SmStructureNode *pSNode = new SmBraceNode(CurToken);
01995 SmNode *pBody = 0,
01996 *pLeft = 0,
01997 *pRight = 0;
01998 SmScaleMode eScaleMode = SCALE_NONE;
01999 SmParseError eError = PE_NONE;
02000
02001 if (CurToken.eType == TLEFT)
02002 { NextToken();
02003
02004 eScaleMode = SCALE_HEIGHT;
02005
02006
02007 if (TokenInGroup(TGLBRACES) || TokenInGroup(TGRBRACES))
02008 {
02009 pLeft = new SmMathSymbolNode(CurToken);
02010
02011 NextToken();
02012 Bracebody(TRUE);
02013 pBody = NodeStack.Pop();
02014
02015 if (CurToken.eType == TRIGHT)
02016 { NextToken();
02017
02018
02019 if (TokenInGroup(TGLBRACES) || TokenInGroup(TGRBRACES))
02020 {
02021 pRight = new SmMathSymbolNode(CurToken);
02022 NextToken();
02023 }
02024 else
02025 eError = PE_RBRACE_EXPECTED;
02026 }
02027 else
02028 eError = PE_RIGHT_EXPECTED;
02029 }
02030 else
02031 eError = PE_LBRACE_EXPECTED;
02032 }
02033 else
02034 {
02035 if (TokenInGroup(TGLBRACES))
02036 {
02037 pLeft = new SmMathSymbolNode(CurToken);
02038
02039 NextToken();
02040 Bracebody(FALSE);
02041 pBody = NodeStack.Pop();
02042
02043 SmTokenType eExpectedType = TUNKNOWN;
02044 switch (pLeft->GetToken().eType)
02045 { case TLPARENT : eExpectedType = TRPARENT; break;
02046 case TLBRACKET : eExpectedType = TRBRACKET; break;
02047 case TLBRACE : eExpectedType = TRBRACE; break;
02048 case TLDBRACKET : eExpectedType = TRDBRACKET; break;
02049 case TLLINE : eExpectedType = TRLINE; break;
02050 case TLDLINE : eExpectedType = TRDLINE; break;
02051 case TLANGLE : eExpectedType = TRANGLE; break;
02052 case TLFLOOR : eExpectedType = TRFLOOR; break;
02053 case TLCEIL : eExpectedType = TRCEIL; break;
02054 default :
02055 DBG_ASSERT(0, "Sm: unbekannter Fall");
02056 }
02057
02058 if (CurToken.eType == eExpectedType)
02059 {
02060 pRight = new SmMathSymbolNode(CurToken);
02061 NextToken();
02062 }
02063 else
02064 eError = PE_PARENT_MISMATCH;
02065 }
02066 else
02067 eError = PE_LBRACE_EXPECTED;
02068 }
02069
02070 if (eError == PE_NONE)
02071 { DBG_ASSERT(pLeft, "Sm: NULL pointer");
02072 DBG_ASSERT(pRight, "Sm: NULL pointer");
02073 pSNode->SetSubNodes(pLeft, pBody, pRight);
02074 pSNode->SetScaleMode(eScaleMode);
02075 NodeStack.Push(pSNode);
02076 }
02077 else
02078 { delete pSNode;
02079 delete pBody;
02080 delete pLeft;
02081 delete pRight;
02082
02083 Error(eError);
02084 }
02085 }
02086
02087
02088 void SmParser::Bracebody(BOOL bIsLeftRight)
02089 {
02090 SmStructureNode *pBody = new SmBracebodyNode(CurToken);
02091 SmNodeArray aNodes;
02092 USHORT nNum = 0;
02093
02094
02095 if (bIsLeftRight)
02096 {
02097 do
02098 {
02099 if (CurToken.eType == TMLINE)
02100 {
02101 NodeStack.Push(new SmMathSymbolNode(CurToken));
02102 NextToken();
02103 nNum++;
02104 }
02105 else if (CurToken.eType != TRIGHT)
02106 { Align();
02107 nNum++;
02108
02109 if (CurToken.eType != TMLINE && CurToken.eType != TRIGHT)
02110 Error(PE_RIGHT_EXPECTED);
02111 }
02112 } while (CurToken.eType != TEND && CurToken.eType != TRIGHT);
02113 }
02114 else
02115 {
02116 do
02117 {
02118 if (CurToken.eType == TMLINE)
02119 {
02120 NodeStack.Push(new SmMathSymbolNode(CurToken));
02121 NextToken();
02122 nNum++;
02123 }
02124 else if (!TokenInGroup(TGRBRACES))
02125 { Align();
02126 nNum++;
02127
02128 if (CurToken.eType != TMLINE && !TokenInGroup(TGRBRACES))
02129 Error(PE_RBRACE_EXPECTED);
02130 }
02131 } while (CurToken.eType != TEND && !TokenInGroup(TGRBRACES));
02132 }
02133
02134
02135 aNodes.SetSize(nNum);
02136 for (USHORT i = 0; i < nNum; i++)
02137 aNodes.Put(nNum - 1 - i, NodeStack.Pop());
02138
02139 pBody->SetSubNodes(aNodes);
02140 pBody->SetScaleMode(bIsLeftRight ? SCALE_HEIGHT : SCALE_NONE);
02141 NodeStack.Push(pBody);
02142 }
02143
02144
02145 void SmParser::Function()
02146 {
02147 switch (CurToken.eType)
02148 {
02149 case TFUNC:
02150 NextToken();
02151
02152
02153 case TSIN :
02154 case TCOS :
02155 case TTAN :
02156 case TCOT :
02157 case TASIN :
02158 case TACOS :
02159 case TATAN :
02160 case TACOT :
02161 case TSINH :
02162 case TCOSH :
02163 case TTANH :
02164 case TCOTH :
02165 case TASINH :
02166 case TACOSH :
02167 case TATANH :
02168 case TACOTH :
02169 case TLN :
02170 case TLOG :
02171 case TEXP :
02172 NodeStack.Push(new SmTextNode(CurToken, FNT_FUNCTION));
02173 NextToken();
02174 break;
02175
02176 default:
02177 Error(PE_FUNC_EXPECTED);
02178 }
02179 }
02180
02181
02182 void SmParser::Binom()
02183 {
02184 SmNodeArray ExpressionArray;
02185 SmStructureNode *pSNode = new SmTableNode(CurToken);
02186
02187 NextToken();
02188
02189 Sum();
02190 Sum();
02191
02192 ExpressionArray.SetSize(2);
02193
02194 for (int i = 0; i < 2; i++)
02195 ExpressionArray.Put(2 - (i + 1), NodeStack.Pop());
02196
02197 pSNode->SetSubNodes(ExpressionArray);
02198 NodeStack.Push(pSNode);
02199 }
02200
02201
02202 void SmParser::Stack()
02203 {
02204 SmNodeArray ExpressionArray;
02205 NextToken();
02206 if (CurToken.eType == TLGROUP)
02207 {
02208 USHORT n = 0;
02209
02210 do
02211 {
02212 NextToken();
02213 Align();
02214 n++;
02215 }
02216 while (CurToken.eType == TPOUND);
02217
02218 ExpressionArray.SetSize(n);
02219
02220 for (USHORT i = 0; i < n; i++)
02221 ExpressionArray.Put(n - (i + 1), NodeStack.Pop());
02222
02223 if (CurToken.eType != TRGROUP)
02224 Error(PE_RGROUP_EXPECTED);
02225
02226 NextToken();
02227
02228 SmStructureNode *pSNode = new SmTableNode(CurToken);
02229 pSNode->SetSubNodes(ExpressionArray);
02230 NodeStack.Push(pSNode);
02231 }
02232 else
02233 Error(PE_LGROUP_EXPECTED);
02234 }
02235
02236
02237 void SmParser::Matrix()
02238 {
02239 SmNodeArray ExpressionArray;
02240
02241 NextToken();
02242 if (CurToken.eType == TLGROUP)
02243 {
02244 USHORT c = 0;
02245
02246 do
02247 {
02248 NextToken();
02249 Align();
02250 c++;
02251 }
02252 while (CurToken.eType == TPOUND);
02253
02254 USHORT r = 1;
02255
02256 while (CurToken.eType == TDPOUND)
02257 {
02258 NextToken();
02259 for (USHORT i = 0; i < c; i++)
02260 {
02261 Align();
02262 if (i < (c - 1))
02263 {
02264 if (CurToken.eType == TPOUND)
02265 {
02266 NextToken();
02267 }
02268 else
02269 Error(PE_POUND_EXPECTED);
02270 }
02271 }
02272
02273 r++;
02274 }
02275
02276 long nRC = r * c;
02277
02278 ExpressionArray.SetSize(nRC);
02279
02280 for (USHORT i = 0; i < (nRC); i++)
02281 ExpressionArray.Put((nRC) - (i + 1), NodeStack.Pop());
02282
02283 if (CurToken.eType != TRGROUP)
02284 Error(PE_RGROUP_EXPECTED);
02285
02286 NextToken();
02287
02288 SmMatrixNode *pMNode = new SmMatrixNode(CurToken);
02289 pMNode->SetSubNodes(ExpressionArray);
02290 pMNode->SetRowCol(r, c);
02291 NodeStack.Push(pMNode);
02292 }
02293 else
02294 Error(PE_LGROUP_EXPECTED);
02295 }
02296
02297
02298 void SmParser::Special()
02299 {
02300 BOOL bReplace = FALSE;
02301 String &rName = CurToken.aText;
02302 String aNewName;
02303
02304 if (CONVERT_NONE == GetConversion())
02305 {
02306
02307
02308
02309 if (IsImportSymbolNames())
02310 {
02311 const SmLocalizedSymbolData &rLSD = SM_MOD1()->GetLocSymbolData();
02312 aNewName = rLSD.GetUiSymbolName( rName );
02313 bReplace = TRUE;
02314 }
02315 else if (IsExportSymbolNames())
02316 {
02317 const SmLocalizedSymbolData &rLSD = SM_MOD1()->GetLocSymbolData();
02318 aNewName = rLSD.GetExportSymbolName( rName );
02319 bReplace = TRUE;
02320 }
02321 }
02322 else
02323 {
02324 LanguageType nLanguage = GetLanguage();
02325 SmLocalizedSymbolData &rData = SM_MOD1()->GetLocSymbolData();
02326 const ResStringArray *pFrom = 0;
02327 const ResStringArray *pTo = 0;
02328 if (CONVERT_50_TO_60 == GetConversion())
02329 {
02330 pFrom = rData.Get50NamesArray( nLanguage );
02331 pTo = rData.Get60NamesArray( nLanguage );
02332 }
02333 else if (CONVERT_60_TO_50 == GetConversion())
02334 {
02335 pFrom = rData.Get60NamesArray( nLanguage );
02336 pTo = rData.Get50NamesArray( nLanguage );
02337 }
02338 if (pFrom && pTo)
02339 {
02340 DBG_ASSERT( pFrom->Count() == pTo->Count(),
02341 "array length mismatch" );
02342 USHORT nCount = sal::static_int_cast< USHORT >(pFrom->Count());
02343 for (USHORT i = 0; i < nCount; ++i)
02344 {
02345 if (pFrom->GetString(i) == rName)
02346 {
02347 aNewName = pTo->GetString(i);
02348 bReplace = TRUE;
02349 }
02350 }
02351 }
02352
02353
02354
02355 }
02356
02357 if (bReplace && aNewName.Len() && rName != aNewName)
02358 {
02359 Replace( GetTokenIndex() + 1, rName.Len(), aNewName );
02360 rName = aNewName;
02361 }
02362
02363 NodeStack.Push(new SmSpecialNode(CurToken));
02364 NextToken();
02365 }
02366
02367
02368 void SmParser::GlyphSpecial()
02369 {
02370 NodeStack.Push(new SmGlyphSpecialNode(CurToken));
02371 NextToken();
02372 }
02373
02374
02375 void SmParser::Error(SmParseError eError)
02376 {
02377 SmStructureNode *pSNode = new SmExpressionNode(CurToken);
02378 SmErrorNode *pErr = new SmErrorNode(eError, CurToken);
02379 pSNode->SetSubNodes(pErr, 0);
02380
02384 NodeStack.Push(pSNode);
02385
02386 AddError(eError, pSNode);
02387
02388 NextToken();
02389 }
02390
02391
02392
02393
02394
02395 SmParser::SmParser()
02396 {
02397 eConversion = CONVERT_NONE;
02398 bImportSymNames = bExportSymNames = FALSE;
02399 nLang = Application::GetSettings().GetUILanguage();
02400 }
02401
02402
02403 SmNode *SmParser::Parse(const String &rBuffer)
02404 {
02405 BufferString = rBuffer;
02406 BufferString.ConvertLineEnd( LINEEND_LF );
02407 BufferIndex =
02408 nTokenIndex = 0;
02409 Row = 1;
02410 ColOff = 0;
02411 CurError = -1;
02412
02413 for (USHORT i = 0; i < ErrDescList.Count(); i++)
02414 delete ErrDescList.Remove(i);
02415
02416 ErrDescList.Clear();
02417
02418 NodeStack.Clear();
02419
02420 SetLanguage( Application::GetSettings().GetUILanguage() );
02421 NextToken();
02422 Table();
02423
02424 return NodeStack.Pop();
02425 }
02426
02427
02428 USHORT SmParser::AddError(SmParseError Type, SmNode *pNode)
02429 {
02430 SmErrorDesc *pErrDesc = new SmErrorDesc;
02431
02432 pErrDesc->Type = Type;
02433 pErrDesc->pNode = pNode;
02434 pErrDesc->Text = String(SmResId(RID_ERR_IDENT));
02435
02436 USHORT nRID;
02437 switch (Type)
02438 {
02439 case PE_UNEXPECTED_CHAR: nRID = RID_ERR_UNEXPECTEDCHARACTER; break;
02440 case PE_LGROUP_EXPECTED: nRID = RID_ERR_LGROUPEXPECTED; break;
02441 case PE_RGROUP_EXPECTED: nRID = RID_ERR_RGROUPEXPECTED; break;
02442 case PE_LBRACE_EXPECTED: nRID = RID_ERR_LBRACEEXPECTED; break;
02443 case PE_RBRACE_EXPECTED: nRID = RID_ERR_RBRACEEXPECTED; break;
02444 case PE_FUNC_EXPECTED: nRID = RID_ERR_FUNCEXPECTED; break;
02445 case PE_UNOPER_EXPECTED: nRID = RID_ERR_UNOPEREXPECTED; break;
02446 case PE_BINOPER_EXPECTED: nRID = RID_ERR_BINOPEREXPECTED; break;
02447 case PE_SYMBOL_EXPECTED: nRID = RID_ERR_SYMBOLEXPECTED; break;
02448 case PE_IDENTIFIER_EXPECTED: nRID = RID_ERR_IDENTEXPECTED; break;
02449 case PE_POUND_EXPECTED: nRID = RID_ERR_POUNDEXPECTED; break;
02450 case PE_COLOR_EXPECTED: nRID = RID_ERR_COLOREXPECTED; break;
02451 case PE_RIGHT_EXPECTED: nRID = RID_ERR_RIGHTEXPECTED; break;
02452
02453 default:
02454 nRID = RID_ERR_UNKOWN;
02455 }
02456 pErrDesc->Text += SmResId(nRID);
02457
02458 ErrDescList.Insert(pErrDesc);
02459
02460 return (USHORT) ErrDescList.GetPos(pErrDesc);
02461 }
02462
02463
02464 const SmErrorDesc *SmParser::NextError()
02465 {
02466 if (ErrDescList.Count())
02467 if (CurError > 0) return ErrDescList.Seek(--CurError);
02468 else
02469 {
02470 CurError = 0;
02471 return ErrDescList.Seek(CurError);
02472 }
02473 else return 0;
02474 }
02475
02476
02477 const SmErrorDesc *SmParser::PrevError()
02478 {
02479 if (ErrDescList.Count())
02480 if (CurError < (int) (ErrDescList.Count() - 1)) return ErrDescList.Seek(++CurError);
02481 else
02482 {
02483 CurError = (int) (ErrDescList.Count() - 1);
02484 return ErrDescList.Seek(CurError);
02485 }
02486 else return 0;
02487 }
02488
02489
02490 const SmErrorDesc *SmParser::GetError(USHORT i)
02491 {
02492 return ( i < ErrDescList.Count())
02493 ? ErrDescList.Seek(i)
02494 : ErrDescList.Seek(CurError);
02495 }
02496
02497