summaryrefslogtreecommitdiff
path: root/binfilter/bf_starmath/source/starmath_parse.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_starmath/source/starmath_parse.cxx')
-rw-r--r--binfilter/bf_starmath/source/starmath_parse.cxx2376
1 files changed, 2376 insertions, 0 deletions
diff --git a/binfilter/bf_starmath/source/starmath_parse.cxx b/binfilter/bf_starmath/source/starmath_parse.cxx
new file mode 100644
index 000000000000..6f2bcd447255
--- /dev/null
+++ b/binfilter/bf_starmath/source/starmath_parse.cxx
@@ -0,0 +1,2376 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifdef _MSC_VER
+#pragma hdrstop
+#endif
+
+#include <stdio.h>
+
+#define SMDLL 1
+
+#include <com/sun/star/i18n/UnicodeType.hpp>
+
+#include <bf_svtools/syslocale.hxx>
+#include <sal/macros.h>
+
+#include "starmath.hrc"
+#include "config.hxx"
+
+#include "node.hxx"
+namespace binfilter {
+
+using namespace ::com::sun::star::i18n;
+
+///////////////////////////////////////////////////////////////////////////
+
+
+/*N*/ static const sal_Unicode aDelimiterTable[] =
+/*N*/ {
+/*N*/ ' ', '\t', '\n', '\r', '+', '-', '*', '/', '=', '#',
+/*N*/ '%', '\\', '"', '~', '`', '>', '<', '&', '|', '(',
+/*N*/ ')', '{', '}', '[', ']', '^', '_',
+/*N*/ '\0' // end of list symbol
+/*N*/ };
+
+
+
+///////////////////////////////////////////////////////////////////////////
+
+/*N*/ SmToken::SmToken() :
+/*N*/ eType (TUNKNOWN),
+/*N*/ cMathChar ('\0')
+/*N*/ {
+/*N*/ nRow = nCol = nGroup = nLevel = 0;
+/*N*/ }
+
+///////////////////////////////////////////////////////////////////////////
+
+/*?*/ struct SmTokenTableEntry
+/*?*/ {
+/*?*/ const sal_Char* pIdent;
+/*?*/ SmTokenType eType;
+/*?*/ sal_Unicode cMathChar;
+/*?*/ ULONG nGroup;
+/*?*/ USHORT nLevel;
+/*?*/ };
+
+/*?*/ static const SmTokenTableEntry aTokenTable[] =
+/*?*/ {
+/*?*/ // { "#", TPOUND, '\0', 0, 0 },
+/*?*/ // { "##", TDPOUND, '\0', 0, 0 },
+/*?*/ // { "&", TAND, MS_AND, TGPRODUCT, 0 },
+/*?*/ // { "(", TLPARENT, MS_LPARENT, TGLBRACES, 5 }, //! 5 to continue expression
+/*?*/ // { ")", TRPARENT, MS_RPARENT, TGRBRACES, 0 }, //! 0 to terminate expression
+/*?*/ // { "*", TMULTIPLY, MS_MULTIPLY, TGPRODUCT, 0 },
+/*?*/ // { "+", TPLUS, MS_PLUS, TGUNOPER | TGSUM, 5 },
+/*?*/ // { "+-", TPLUSMINUS, MS_PLUSMINUS, TGUNOPER | TGSUM, 5 },
+/*?*/ // { "-", TMINUS, MS_MINUS, TGUNOPER | TGSUM, 5 },
+/*?*/ // { "-+", TMINUSPLUS, MS_MINUSPLUS, TGUNOPER | TGSUM, 5 },
+/*?*/ // { ".", TPOINT, '\0', 0, 0 },
+/*?*/ // { "/", TDIVIDEBY, MS_SLASH, TGPRODUCT, 0 },
+/*?*/ // { "<", TLT, MS_LT, TGRELATION, 0 },
+/*?*/ // { "<<", TLL, MS_LL, TGRELATION, 0 },
+/*?*/ // { "<=", TLE, MS_LE, TGRELATION, 0 },
+/*?*/ // { "<>", TNEQ, MS_NEQ, TGRELATION, 0},
+/*?*/ // { "<?>", TPLACE, MS_PLACE, 0, 5 },
+/*?*/ // { "=", TASSIGN, MS_ASSIGN, TGRELATION, 0},
+/*?*/ // { ">", TGT, MS_GT, TGRELATION, 0 },
+/*?*/ // { ">=", TGE, MS_GE, TGRELATION, 0 },
+/*?*/ // { ">>", TGG, MS_GG, TGRELATION, 0 },
+/*?*/ { "Im" , TIM, MS_IM, TGSTANDALONE, 5 },
+/*?*/ { "MZ23", TDEBUG, '\0', TGATTRIBUT, 0 },
+/*?*/ { "Re" , TRE, MS_RE, TGSTANDALONE, 5 },
+/*?*/ { "abs", TABS, '\0', TGUNOPER, 13 },
+/*?*/ { "arcosh", TACOSH, '\0', TGFUNCTION, 5 },
+/*?*/ { "arcoth", TACOTH, '\0', TGFUNCTION, 5 },
+/*?*/ { "acute", TACUTE, MS_ACUTE, TGATTRIBUT, 5 },
+/*?*/ { "aleph" , TALEPH, MS_ALEPH, TGSTANDALONE, 5 },
+/*?*/ { "alignb", TALIGNC, '\0', TGALIGN | TGDISCARDED, 0},
+/*?*/ { "alignc", TALIGNC, '\0', TGALIGN, 0},
+/*?*/ { "alignl", TALIGNL, '\0', TGALIGN, 0},
+/*?*/ { "alignm", TALIGNC, '\0', TGALIGN | TGDISCARDED, 0},
+/*?*/ { "alignr", TALIGNR, '\0', TGALIGN, 0},
+/*?*/ { "alignt", TALIGNC, '\0', TGALIGN | TGDISCARDED, 0},
+/*?*/ { "and", TAND, MS_AND, TGPRODUCT, 0},
+/*?*/ { "approx", TAPPROX, MS_APPROX, TGRELATION, 0},
+/*?*/ { "arccos", TACOS, '\0', TGFUNCTION, 5},
+/*?*/ { "arccot", TACOT, '\0', TGFUNCTION, 5},
+/*?*/ { "arcsin", TASIN, '\0', TGFUNCTION, 5},
+/*?*/ { "arctan", TATAN, '\0', TGFUNCTION, 5},
+/*?*/ { "arsinh", TASINH, '\0', TGFUNCTION, 5},
+/*?*/ { "artanh", TATANH, '\0', TGFUNCTION, 5},
+/*?*/ { "backepsilon" , TBACKEPSILON, MS_BACKEPSILON, TGSTANDALONE, 5},
+/*?*/ { "bar", TBAR, MS_BAR, TGATTRIBUT, 5},
+/*?*/ { "binom", TBINOM, '\0', 0, 5 },
+/*?*/ { "black", TBLACK, '\0', TGCOLOR, 0},
+/*?*/ { "blue", TBLUE, '\0', TGCOLOR, 0},
+/*?*/ { "bold", TBOLD, '\0', TGFONTATTR, 5},
+/*?*/ { "boper", TBOPER, '\0', TGPRODUCT, 0},
+/*?*/ { "breve", TBREVE, MS_BREVE, TGATTRIBUT, 5},
+/*?*/ { "bslash", TBACKSLASH, MS_BACKSLASH, TGPRODUCT, 0 },
+/*?*/ { "cdot", TCDOT, MS_CDOT, TGPRODUCT, 0},
+/*?*/ { "check", TCHECK, MS_CHECK, TGATTRIBUT, 5},
+/*?*/ { "circ" , TCIRC, MS_CIRC, TGSTANDALONE, 5},
+/*?*/ { "circle", TCIRCLE, MS_CIRCLE, TGATTRIBUT, 5},
+/*?*/ { "color", TCOLOR, '\0', TGFONTATTR, 5},
+/*?*/ { "coprod", TCOPROD, MS_COPROD, TGOPER, 5},
+/*?*/ { "cos", TCOS, '\0', TGFUNCTION, 5},
+/*?*/ { "cosh", TCOSH, '\0', TGFUNCTION, 5},
+/*?*/ { "cot", TCOT, '\0', TGFUNCTION, 5},
+/*?*/ { "coth", TCOTH, '\0', TGFUNCTION, 5},
+/*?*/ { "csub", TCSUB, '\0', TGPOWER, 0},
+/*?*/ { "csup", TCSUP, '\0', TGPOWER, 0},
+/*?*/ { "cyan", TCYAN, '\0', TGCOLOR, 0},
+/*?*/ { "dddot", TDDDOT, MS_DDDOT, TGATTRIBUT, 5},
+/*?*/ { "ddot", TDDOT, MS_DDOT, TGATTRIBUT, 5},
+/*?*/ { "def", TDEF, MS_DEF, TGRELATION, 0},
+/*?*/ { "div", TDIV, MS_DIV, TGPRODUCT, 0},
+/*?*/ { "divides", TDIVIDES, MS_LINE, TGRELATION, 0},
+/*?*/ { "dlarrow" , TDLARROW, MS_DLARROW, TGSTANDALONE, 5},
+/*?*/ { "dlrarrow" , TDLRARROW, MS_DLRARROW, TGSTANDALONE, 5},
+/*?*/ { "dot", TDOT, MS_DOT, TGATTRIBUT, 5},
+/*?*/ { "dotsaxis", TDOTSAXIS, MS_DOTSAXIS, TGSTANDALONE, 5}, // 5 to continue expression
+/*?*/ { "dotsdiag", TDOTSDIAG, MS_DOTSUP, TGSTANDALONE, 5}, //
+/*?*/ { "dotsdown", TDOTSDOWN, MS_DOTSDOWN, TGSTANDALONE, 5}, //
+/*?*/ { "dotslow", TDOTSLOW, MS_DOTSLOW, TGSTANDALONE, 5}, //
+/*?*/ { "dotsup", TDOTSUP, MS_DOTSUP, TGSTANDALONE, 5}, //
+/*?*/ { "dotsvert", TDOTSVERT, MS_DOTSVERT, TGSTANDALONE, 5}, //
+/*?*/ { "downarrow" , TDOWNARROW, MS_DOWNARROW, TGSTANDALONE, 5},
+/*?*/ { "drarrow" , TDRARROW, MS_DRARROW, TGSTANDALONE, 5},
+/*?*/ { "emptyset" , TEMPTYSET, MS_EMPTYSET, TGSTANDALONE, 5},
+/*?*/ { "equiv", TEQUIV, MS_EQUIV, TGRELATION, 0},
+/*?*/ { "exists", TEXISTS, MS_EXISTS, TGSTANDALONE, 5},
+/*?*/ { "exp", TEXP, '\0', TGFUNCTION, 5},
+/*?*/ { "fact", TFACT, MS_FACT, TGUNOPER, 5},
+/*?*/ { "fixed", TFIXED, '\0', TGFONT, 0},
+/*?*/ { "font", TFONT, '\0', TGFONTATTR, 5},
+/*?*/ { "forall", TFORALL, MS_FORALL, TGSTANDALONE, 5},
+/*?*/ { "from", TFROM, '\0', TGLIMIT, 0},
+/*?*/ { "func", TFUNC, '\0', TGFUNCTION, 5},
+/*?*/ { "ge", TGE, MS_GE, TGRELATION, 0},
+/*?*/ { "geslant", TGESLANT, MS_GESLANT, TGRELATION, 0 },
+/*?*/ { "gg", TGG, MS_GG, TGRELATION, 0},
+/*?*/ { "grave", TGRAVE, MS_GRAVE, TGATTRIBUT, 5},
+/*?*/ { "green", TGREEN, '\0', TGCOLOR, 0},
+/*?*/ { "gt", TGT, MS_GT, TGRELATION, 0},
+/*?*/ { "hat", THAT, MS_HAT, TGATTRIBUT, 5},
+/*?*/ { "hbar" , THBAR, MS_HBAR, TGSTANDALONE, 5},
+/*?*/ { "iiint", TIIINT, MS_IIINT, TGOPER, 5},
+/*?*/ { "iint", TIINT, MS_IINT, TGOPER, 5},
+/*?*/ { "in", TIN, MS_IN, TGRELATION, 0},
+/*?*/ { "infinity" , TINFINITY, MS_INFINITY, TGSTANDALONE, 5},
+/*?*/ { "infty" , TINFINITY, MS_INFINITY, TGSTANDALONE, 5},
+/*?*/ { "int", TINT, MS_INT, TGOPER, 5},
+/*?*/ { "intersection", TINTERSECT, MS_INTERSECT, TGPRODUCT, 0},
+/*?*/ { "ital", TITALIC, '\0', TGFONTATTR, 5},
+/*?*/ { "italic", TITALIC, '\0', TGFONTATTR, 5},
+/*?*/ { "lambdabar" , TLAMBDABAR, MS_LAMBDABAR, TGSTANDALONE, 5},
+/*?*/ { "langle", TLANGLE, MS_LANGLE, TGLBRACES, 5},
+/*?*/ { "lbrace", TLBRACE, MS_LBRACE, TGLBRACES, 5},
+/*?*/ { "lceil", TLCEIL, MS_LCEIL, TGLBRACES, 5},
+/*?*/ { "ldbracket", TLDBRACKET, MS_LDBRACKET, TGLBRACES, 5},
+/*?*/ { "ldline", TLDLINE, MS_DLINE, TGLBRACES, 5},
+/*?*/ { "le", TLE, MS_LE, TGRELATION, 0},
+/*?*/ { "left", TLEFT, '\0', 0, 5},
+/*?*/ { "leftarrow" , TLEFTARROW, MS_LEFTARROW, TGSTANDALONE, 5},
+/*?*/ { "leslant", TLESLANT, MS_LESLANT, TGRELATION, 0 },
+/*?*/ { "lfloor", TLFLOOR, MS_LFLOOR, TGLBRACES, 5},
+/*?*/ { "lim", TLIM, '\0', TGOPER, 5},
+/*?*/ { "liminf", TLIMINF, '\0', TGOPER, 5},
+/*?*/ { "limsup", TLIMSUP, '\0', TGOPER, 5},
+/*?*/ { "lint", TLINT, MS_LINT, TGOPER, 5},
+/*?*/ { "ll", TLL, MS_LL, TGRELATION, 0},
+/*?*/ { "lline", TLLINE, MS_LINE, TGLBRACES, 5},
+/*?*/ { "llint", TLLINT, MS_LLINT, TGOPER, 5},
+/*?*/ { "lllint", TLLLINT, MS_LLLINT, TGOPER, 5},
+/*?*/ { "ln", TLN, '\0', TGFUNCTION, 5},
+/*?*/ { "log", TLOG, '\0', TGFUNCTION, 5},
+/*?*/ { "lsub", TLSUB, '\0', TGPOWER, 0},
+/*?*/ { "lsup", TLSUP, '\0', TGPOWER, 0},
+/*?*/ { "lt", TLT, MS_LT, TGRELATION, 0},
+/*?*/ { "magenta", TMAGENTA, '\0', TGCOLOR, 0},
+/*?*/ { "matrix", TMATRIX, '\0', 0, 5},
+/*?*/ { "minusplus", TMINUSPLUS, MS_MINUSPLUS, TGUNOPER | TGSUM, 5},
+/*?*/ { "mline", TMLINE, MS_LINE, 0, 0}, //! nicht in TGRBRACES, Level 0
+/*?*/ { "nabla", TNABLA, MS_NABLA, TGSTANDALONE, 5},
+/*?*/ { "nbold", TNBOLD, '\0', TGFONTATTR, 5},
+/*?*/ { "ndivides", TNDIVIDES, MS_NDIVIDES, TGRELATION, 0},
+/*?*/ { "neg", TNEG, MS_NEG, TGUNOPER, 5 },
+/*?*/ { "neq", TNEQ, MS_NEQ, TGRELATION, 0},
+/*?*/ { "newline", TNEWLINE, '\0', 0, 0},
+/*?*/ { "ni", TNI, MS_NI, TGRELATION, 0},
+/*?*/ { "nitalic", TNITALIC, '\0', TGFONTATTR, 5},
+/*?*/ { "none", TNONE, '\0', TGLBRACES | TGRBRACES, 0},
+/*?*/ { "notin", TNOTIN, MS_NOTIN, TGRELATION, 0},
+/*?*/ { "nsubset", TNSUBSET, MS_NSUBSET, TGRELATION, 0 },
+/*?*/ { "nsupset", TNSUPSET, MS_NSUPSET, TGRELATION, 0 },
+/*?*/ { "nsubseteq", TNSUBSETEQ, MS_NSUBSETEQ, TGRELATION, 0 },
+/*?*/ { "nsupseteq", TNSUPSETEQ, MS_NSUPSETEQ, TGRELATION, 0 },
+/*?*/ { "nroot", TNROOT, MS_SQRT, TGUNOPER, 5},
+/*?*/ { "odivide", TODIVIDE, MS_ODIVIDE, TGPRODUCT, 0},
+/*?*/ { "odot", TODOT, MS_ODOT, TGPRODUCT, 0},
+/*?*/ { "ominus", TOMINUS, MS_OMINUS, TGSUM, 0},
+/*?*/ { "oper", TOPER, '\0', TGOPER, 5},
+/*?*/ { "oplus", TOPLUS, MS_OPLUS, TGSUM, 0},
+/*?*/ { "or", TOR, MS_OR, TGSUM, 0},
+/*?*/ { "ortho", TORTHO, MS_ORTHO, TGRELATION, 0},
+/*?*/ { "otimes", TOTIMES, MS_OTIMES, TGPRODUCT, 0},
+/*?*/ { "over", TOVER, '\0', TGPRODUCT, 0},
+/*?*/ { "overbrace", TOVERBRACE, MS_OVERBRACE, TGPRODUCT, 5},
+/*?*/ { "overline", TOVERLINE, '\0', TGATTRIBUT, 5},
+/*?*/ { "overstrike", TOVERSTRIKE, '\0', TGATTRIBUT, 5},
+/*?*/ { "owns", TNI, MS_NI, TGRELATION, 0},
+/*?*/ { "parallel", TPARALLEL, MS_DLINE, TGRELATION, 0},
+/*?*/ { "partial", TPARTIAL, MS_PARTIAL, TGSTANDALONE, 5 },
+/*?*/ { "phantom", TPHANTOM, '\0', TGFONTATTR, 5},
+/*?*/ { "plusminus", TPLUSMINUS, MS_PLUSMINUS, TGUNOPER | TGSUM, 5},
+/*?*/ { "prod", TPROD, MS_PROD, TGOPER, 5},
+/*?*/ { "prop", TPROP, MS_PROP, TGRELATION, 0},
+/*?*/ { "rangle", TRANGLE, MS_RANGLE, TGRBRACES, 0}, //! 0 to terminate expression
+/*?*/ { "rbrace", TRBRACE, MS_RBRACE, TGRBRACES, 0}, //
+/*?*/ { "rceil", TRCEIL, MS_RCEIL, TGRBRACES, 0}, //
+/*?*/ { "rdbracket", TRDBRACKET, MS_RDBRACKET, TGRBRACES, 0}, //
+/*?*/ { "rdline", TRDLINE, MS_DLINE, TGRBRACES, 0}, //
+/*?*/ { "red", TRED, '\0', TGCOLOR, 0},
+/*?*/ { "rfloor", TRFLOOR, MS_RFLOOR, TGRBRACES, 0}, //! 0 to terminate expression
+/*?*/ { "right", TRIGHT, '\0', 0, 0},
+/*?*/ { "rightarrow" , TRIGHTARROW, MS_RIGHTARROW, TGSTANDALONE, 5},
+/*?*/ { "rline", TRLINE, MS_LINE, TGRBRACES, 0}, //! 0 to terminate expression
+/*?*/ { "rsub", TRSUB, '\0', TGPOWER, 0},
+/*?*/ { "rsup", TRSUP, '\0', TGPOWER, 0},
+/*?*/ { "sans", TSANS, '\0', TGFONT, 0},
+/*?*/ { "serif", TSERIF, '\0', TGFONT, 0},
+/*?*/ { "setC" , TSETC, MS_SETC, TGSTANDALONE, 5},
+/*?*/ { "setN" , TSETN, MS_SETN, TGSTANDALONE, 5},
+/*?*/ { "setQ" , TSETQ, MS_SETQ, TGSTANDALONE, 5},
+/*?*/ { "setR" , TSETR, MS_SETR, TGSTANDALONE, 5},
+/*?*/ { "setZ" , TSETZ, MS_SETZ, TGSTANDALONE, 5},
+/*?*/ { "setminus", TBACKSLASH, MS_BACKSLASH, TGPRODUCT, 0 },
+/*?*/ { "sim", TSIM, MS_SIM, TGRELATION, 0},
+/*?*/ { "simeq", TSIMEQ, MS_SIMEQ, TGRELATION, 0},
+/*?*/ { "sin", TSIN, '\0', TGFUNCTION, 5},
+/*?*/ { "sinh", TSINH, '\0', TGFUNCTION, 5},
+/*?*/ { "size", TSIZE, '\0', TGFONTATTR, 5},
+/*?*/ { "slash", TSLASH, MS_SLASH, TGPRODUCT, 0 },
+/*?*/ { "sqrt", TSQRT, MS_SQRT, TGUNOPER, 5},
+/*?*/ { "stack", TSTACK, '\0', 0, 5},
+/*?*/ { "sub", TRSUB, '\0', TGPOWER, 0},
+/*?*/ { "subset", TSUBSET, MS_SUBSET, TGRELATION, 0},
+/*?*/ { "subseteq", TSUBSETEQ, MS_SUBSETEQ, TGRELATION, 0},
+/*?*/ { "sum", TSUM, MS_SUM, TGOPER, 5},
+/*?*/ { "sup", TRSUP, '\0', TGPOWER, 0},
+/*?*/ { "supset", TSUPSET, MS_SUPSET, TGRELATION, 0},
+/*?*/ { "supseteq", TSUPSETEQ, MS_SUPSETEQ, TGRELATION, 0},
+/*?*/ { "tan", TTAN, '\0', TGFUNCTION, 5},
+/*?*/ { "tanh", TTANH, '\0', TGFUNCTION, 5},
+/*?*/ { "tilde", TTILDE, MS_TILDE, TGATTRIBUT, 5},
+/*?*/ { "times", TTIMES, MS_TIMES, TGPRODUCT, 0},
+/*?*/ { "to", TTO, '\0', TGLIMIT, 0},
+/*?*/ { "toward", TTOWARD, MS_RIGHTARROW, TGRELATION, 0},
+/*?*/ { "transl", TTRANSL, MS_TRANSL, TGRELATION, 0},
+/*?*/ { "transr", TTRANSR, MS_TRANSR, TGRELATION, 0},
+/*?*/ { "underbrace", TUNDERBRACE, MS_UNDERBRACE, TGPRODUCT, 5},
+/*?*/ { "underline", TUNDERLINE, '\0', TGATTRIBUT, 5},
+/*?*/ { "union", TUNION, MS_UNION, TGSUM, 0},
+/*?*/ { "uoper", TUOPER, '\0', TGUNOPER, 5},
+/*?*/ { "uparrow" , TUPARROW, MS_UPARROW, TGSTANDALONE, 5},
+/*?*/ { "vec", TVEC, MS_VEC, TGATTRIBUT, 5},
+/*?*/ { "white", TWHITE, '\0', TGCOLOR, 0},
+/*?*/ { "widebslash", TWIDEBACKSLASH, MS_BACKSLASH, TGPRODUCT, 0 },
+/*?*/ { "widehat", TWIDEHAT, MS_HAT, TGATTRIBUT, 5},
+/*?*/ { "widetilde", TWIDETILDE, MS_TILDE, TGATTRIBUT, 5},
+/*?*/ { "wideslash", TWIDESLASH, MS_SLASH, TGPRODUCT, 0 },
+/*?*/ { "widevec", TWIDEVEC, MS_VEC, TGATTRIBUT, 5},
+/*?*/ { "wp" , TWP, MS_WP, TGSTANDALONE, 5},
+/*?*/ { "yellow", TYELLOW, '\0', TGCOLOR, 0},
+/*?*/ // { "[", TLBRACKET, MS_LBRACKET, TGLBRACES, 5}, //! 5 to continue expression
+/*?*/ // { "\\", TESCAPE, '\0', 0, 5},
+/*?*/ // { "]", TRBRACKET, MS_RBRACKET, TGRBRACES, 0}, //! 0 to terminate expression
+/*?*/ // { "^", TRSUP, '\0', TGPOWER, 0},
+/*?*/ // { "_", TRSUB, '\0', TGPOWER, 0},
+/*?*/ // { "`", TSBLANK, '\0', TGBLANK, 5},
+/*?*/ // { "{", TLGROUP, MS_LBRACE, 0, 5}, //! 5 to continue expression
+/*?*/ // { "|", TOR, MS_OR, TGSUM, 0},
+/*?*/ // { "}", TRGROUP, MS_RBRACE, 0, 0}, //! 0 to terminate expression
+/*?*/ // { "~", TBLANK, '\0', TGBLANK, 5},
+/*?*/ { "", TEND, '\0', 0, 0}
+/*?*/ };
+
+
+/*N*/ static const SmTokenTableEntry * GetTokenTableEntry( const String &rName )
+/*N*/ {
+/*N*/ const SmTokenTableEntry * pRes = 0;
+/*N*/ if (rName.Len())
+/*N*/ {
+/*N*/ INT32 nEntries = SAL_N_ELEMENTS( aTokenTable );
+/*N*/ for (INT32 i = 0; i < nEntries; ++i)
+/*N*/ {
+/*N*/ if (rName.EqualsIgnoreCaseAscii( aTokenTable[i].pIdent ))
+/*N*/ {
+/*N*/ pRes = &aTokenTable[i];
+/*N*/ break;
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ }
+/*N*/
+/*N*/ return pRes;
+/*N*/ }
+
+
+///////////////////////////////////////////////////////////////////////////
+
+#if OSL_DEBUG_LEVEL > 1
+
+/*N*/ BOOL SmParser::IsDelimiter( const String &rTxt, xub_StrLen nPos )
+/*N*/ // returns 'TRUE' iff cChar is '\0' or a delimeter
+/*N*/ {
+/*N*/ DBG_ASSERT( nPos <= rTxt.Len(), "index out of range" );
+/*N*/
+/*N*/ sal_Unicode cChar = rTxt.GetChar( nPos );
+/*N*/ if(!cChar)
+/*N*/ return TRUE;
+/*N*/
+/*N*/ // check if 'cChar' is in the delimeter table
+/*N*/ const sal_Unicode *pDelim = &aDelimiterTable[0];
+/*N*/ for ( ; *pDelim != 0; pDelim++)
+/*N*/ if (*pDelim == cChar)
+/*N*/ break;
+/*N*/
+/*N*/ BOOL bIsDelim = *pDelim != 0;
+/*N*/
+/*N*/ INT16 nTypJp = SM_MOD1()->GetSysLocale().GetCharClass().getType( rTxt, nPos );
+/*N*/ bIsDelim |= nTypJp == ::com::sun::star::i18n::UnicodeType::SPACE_SEPARATOR ||
+/*N*/ nTypJp == ::com::sun::star::i18n::UnicodeType::CONTROL;
+/*N*/
+/*N*/ return bIsDelim;
+/*N*/ }
+
+#endif
+
+
+/*N*/ void SmParser::Insert(const String &rText, USHORT nPos)
+/*N*/ {
+/*N*/ BufferString.Insert(rText, nPos);
+/*N*/
+/*N*/ xub_StrLen nLen = rText.Len();
+/*N*/ BufferIndex += nLen;
+/*N*/ nTokenIndex += nLen;
+/*N*/ }
+
+
+/*N*/ void SmParser::Replace( USHORT nPos, USHORT nLen, const String &rText )
+/*N*/ {
+/*N*/ DBG_ASSERT( nPos + nLen <= BufferString.Len(), "argument mismatch" );
+/*N*/
+/*N*/ BufferString.Replace( nPos, nLen, rText );
+/*N*/ INT16 nChg = rText.Len() - nLen;
+/*N*/ BufferIndex += nChg;
+/*N*/ nTokenIndex += nChg;
+/*N*/ }
+
+
+// First character may be any alphabetic
+/*?*/ const sal_Int32 coStartFlags =
+/*?*/ KParseTokens::ANY_LETTER_OR_NUMBER |
+/*?*/ KParseTokens::IGNORE_LEADING_WS;
+
+// Continuing characters may be any alphanumeric or dot.
+/*?*/ const sal_Int32 coContFlags =
+/*?*/ ( coStartFlags | KParseTokens::ASC_DOT ) & ~KParseTokens::IGNORE_LEADING_WS
+/*?*/ | KParseTokens::TWO_DOUBLE_QUOTES_BREAK_STRING;
+
+// First character for numbers, may be any numeric or dot
+const sal_Int32 coNumStartFlags =
+ KParseTokens::ASC_DIGIT |
+ KParseTokens::ASC_DOT |
+ KParseTokens::IGNORE_LEADING_WS;
+// Continuing characters for numbers, may be any numeric or dot.
+const sal_Int32 coNumContFlags =
+ ( coNumStartFlags | KParseTokens::ASC_DOT ) & ~KParseTokens::IGNORE_LEADING_WS;
+
+/*N*/ void SmParser::NextToken()
+/*N*/ {
+/*N*/ static const String aEmptyStr;
+/*N*/
+/*N*/ xub_StrLen nBufLen = BufferString.Len();
+/*N*/ ParseResult aRes;
+/*N*/ xub_StrLen nRealStart;
+/*N*/ BOOL bCont;
+/*N*/ BOOL bNumStart;
+/*N*/ const CharClass& rCC = SM_MOD1()->GetSysLocale().GetCharClass();
+/*N*/ do
+/*N*/ {
+/*N*/ // skip white spaces
+/*N*/ while (UnicodeType::SPACE_SEPARATOR ==
+/*N*/ rCC.getType( BufferString, BufferIndex ))
+/*N*/ ++BufferIndex;
+/*N*/
+/*N*/ sal_Int32 nStartFlags = coStartFlags;
+/*N*/ sal_Int32 nContFlags = coContFlags;
+/*N*/ sal_Unicode cFirstChar = BufferString.GetChar( BufferIndex );
+/*N*/ bNumStart = cFirstChar == '.' || ('0' <= cFirstChar && cFirstChar <= '9');
+/*N*/ if (bNumStart)
+/*N*/ {
+/*N*/ nStartFlags = coNumStartFlags;
+/*N*/ nContFlags = coNumContFlags;
+/*N*/ }
+/*N*/
+/*N*/ aRes = rCC.parseAnyToken( BufferString, BufferIndex,
+/*N*/ nStartFlags, aEmptyStr,
+/*N*/ nContFlags, aEmptyStr );
+/*N*/
+/*N*/ nRealStart = BufferIndex + (xub_StrLen) aRes.LeadingWhiteSpace;
+/*N*/ BufferIndex = nRealStart;
+/*N*/
+/*N*/ bCont = FALSE;
+/*N*/ if ( aRes.TokenType == 0 &&
+/*N*/ nRealStart < nBufLen &&
+/*N*/ '\n' == BufferString.GetChar( nRealStart ) )
+/*N*/ {
+/*N*/ // keep data needed for tokens row and col entry up to date
+/*N*/ ++Row;
+/*N*/ BufferIndex = ColOff = nRealStart + 1;
+/*N*/ bCont = TRUE;
+/*N*/ }
+/*N*/ else if (aRes.TokenType & KParseType::ONE_SINGLE_CHAR)
+/*N*/ {
+/*N*/ String aName( BufferString.Copy( nRealStart, 2 ));
+/*N*/ if ( aName.EqualsAscii( "%%" ))
+/*N*/ {
+/*N*/ //SkipComment
+/*N*/ BufferIndex = nRealStart + 2;
+/*N*/ while (BufferIndex < nBufLen &&
+/*N*/ '\n' != BufferString.GetChar( BufferIndex ))
+/*N*/ ++BufferIndex;
+/*N*/ bCont = TRUE;
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ } while (bCont);
+/*N*/
+/*N*/ // set index of current token
+/*N*/ nTokenIndex = BufferIndex;
+/*N*/
+/*N*/ CurToken.nRow = Row;
+/*N*/ CurToken.nCol = nRealStart - ColOff + 1;
+/*N*/
+/*N*/ BOOL bHandled = TRUE;
+/*N*/ if (nRealStart >= nBufLen)
+/*N*/ {
+/*N*/ CurToken.eType = TEND;
+/*N*/ CurToken.cMathChar = '\0';
+/*N*/ CurToken.nGroup = 0;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.Erase();
+/*N*/ }
+/*N*/ else if ((aRes.TokenType & (KParseType::ASC_NUMBER | KParseType::UNI_NUMBER))
+/*N*/ || (bNumStart && (aRes.TokenType & KParseType::IDENTNAME)))
+/*N*/ {
+/*N*/ INT32 n = aRes.EndPos - nRealStart;
+/*N*/ DBG_ASSERT( n >= 0, "length < 0" );
+/*N*/ CurToken.eType = TNUMBER;
+/*N*/ CurToken.cMathChar = '\0';
+/*N*/ CurToken.nGroup = 0;
+/*N*/ CurToken.nLevel = 5;
+/*N*/ CurToken.aText = BufferString.Copy( nRealStart, (xub_StrLen) n );
+/*N*/
+/*N*/ #if OSL_DEBUG_LEVEL > 1
+/*N*/ if (!IsDelimiter( BufferString, aRes.EndPos ))
+/*N*/ DBG_WARNING( "identifier really finished? (compatibility!)" );
+/*N*/ #endif
+/*N*/ }
+/*N*/ else if (aRes.TokenType & KParseType::DOUBLE_QUOTE_STRING)
+/*N*/ {
+/*N*/ CurToken.eType = TTEXT;
+/*N*/ CurToken.cMathChar = '\0';
+/*N*/ CurToken.nGroup = 0;
+/*N*/ CurToken.nLevel = 5;
+/*N*/ CurToken.aText = aRes.DequotedNameOrString;
+/*N*/ CurToken.nRow = Row;
+/*N*/ CurToken.nCol = nRealStart - ColOff + 2;
+/*N*/ }
+/*N*/ else if (aRes.TokenType & KParseType::IDENTNAME)
+/*N*/ {
+/*N*/ INT32 n = aRes.EndPos - nRealStart;
+/*N*/ DBG_ASSERT( n >= 0, "length < 0" );
+/*N*/ String aName( BufferString.Copy( nRealStart, (xub_StrLen) n ) );
+/*N*/ const SmTokenTableEntry *pEntry = GetTokenTableEntry( aName );
+/*N*/
+/*N*/ if (pEntry)
+/*N*/ {
+/*N*/ CurToken.eType = pEntry->eType;
+/*N*/ CurToken.cMathChar = pEntry->cMathChar;
+/*N*/ CurToken.nGroup = pEntry->nGroup;
+/*N*/ CurToken.nLevel = pEntry->nLevel;
+/*N*/ CurToken.aText.AssignAscii( pEntry->pIdent );
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ CurToken.eType = TIDENT;
+/*N*/ CurToken.cMathChar = '\0';
+/*N*/ CurToken.nGroup = 0;
+/*N*/ CurToken.nLevel = 5;
+/*N*/ CurToken.aText = aName;
+/*N*/
+/*N*/ #if OSL_DEBUG_LEVEL > 1
+/*N*/ if (!IsDelimiter( BufferString, aRes.EndPos ))
+/*N*/ DBG_WARNING( "identifier really finished? (compatibility!)" );
+/*N*/ #endif
+/*N*/ }
+/*N*/ }
+/*N*/ else if (aRes.TokenType == 0 && '_' == BufferString.GetChar( nRealStart ))
+/*N*/ {
+/*N*/ CurToken.eType = TRSUB;
+/*N*/ CurToken.cMathChar = '\0';
+/*N*/ CurToken.nGroup = TGPOWER;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( "_" );
+/*N*/
+/*N*/ aRes.EndPos = nRealStart + 1;
+/*N*/ }
+/*N*/ else if (aRes.TokenType & KParseType::BOOLEAN)
+/*N*/ {
+/*N*/ sal_Int32 &rnEndPos = aRes.EndPos;
+/*N*/ String aName( BufferString.Copy( nRealStart, rnEndPos - nRealStart ) );
+/*N*/ if (2 >= aName.Len())
+/*N*/ {
+/*N*/ sal_Unicode ch = aName.GetChar( 0 );
+/*N*/ switch (ch)
+/*N*/ {
+/*N*/ case '<':
+/*N*/ {
+/*N*/ if (BufferString.Copy( nRealStart, 2 ).
+/*N*/ EqualsAscii( "<<" ))
+/*N*/ {
+/*N*/ CurToken.eType = TLL;
+/*N*/ CurToken.cMathChar = MS_LL;
+/*N*/ CurToken.nGroup = TGRELATION;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( "<<" );
+/*N*/
+/*N*/ rnEndPos = nRealStart + 2;
+/*N*/ }
+/*N*/ else if (BufferString.Copy( nRealStart, 2 ).
+/*N*/ EqualsAscii( "<=" ))
+/*N*/ {
+/*N*/ CurToken.eType = TLE;
+/*N*/ CurToken.cMathChar = MS_LE;
+/*N*/ CurToken.nGroup = TGRELATION;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( "<=" );
+/*N*/
+/*N*/ rnEndPos = nRealStart + 2;
+/*N*/ }
+/*N*/ else if (BufferString.Copy( nRealStart, 2 ).
+/*N*/ EqualsAscii( "<>" ))
+/*N*/ {
+/*N*/ CurToken.eType = TNEQ;
+/*N*/ CurToken.cMathChar = MS_NEQ;
+/*N*/ CurToken.nGroup = TGRELATION;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( "<>" );
+/*N*/
+/*N*/ rnEndPos = nRealStart + 2;
+/*N*/ }
+/*N*/ else if (BufferString.Copy( nRealStart, 3 ).
+/*N*/ EqualsAscii( "<?>" ))
+/*N*/ {
+/*N*/ CurToken.eType = TPLACE;
+/*N*/ CurToken.cMathChar = MS_PLACE;
+/*N*/ CurToken.nGroup = 0;
+/*N*/ CurToken.nLevel = 5;
+/*N*/ CurToken.aText.AssignAscii( "<?>" );
+/*N*/
+/*N*/ rnEndPos = nRealStart + 3;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ CurToken.eType = TLT;
+/*N*/ CurToken.cMathChar = MS_LT;
+/*N*/ CurToken.nGroup = TGRELATION;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( "<" );
+/*N*/ }
+/*N*/ }
+/*N*/ break;
+/*N*/ case '>':
+/*N*/ {
+/*N*/ if (BufferString.Copy( nRealStart, 2 ).
+/*N*/ EqualsAscii( ">=" ))
+/*N*/ {
+/*N*/ CurToken.eType = TGE;
+/*N*/ CurToken.cMathChar = MS_GE;
+/*N*/ CurToken.nGroup = TGRELATION;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( ">=" );
+/*N*/
+/*N*/ rnEndPos = nRealStart + 2;
+/*N*/ }
+/*N*/ else if (BufferString.Copy( nRealStart, 2 ).
+/*N*/ EqualsAscii( ">>" ))
+/*N*/ {
+/*N*/ CurToken.eType = TGG;
+/*N*/ CurToken.cMathChar = MS_GG;
+/*N*/ CurToken.nGroup = TGRELATION;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( ">>" );
+/*N*/
+/*N*/ rnEndPos = nRealStart + 2;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ CurToken.eType = TGT;
+/*N*/ CurToken.cMathChar = MS_GT;
+/*N*/ CurToken.nGroup = TGRELATION;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( ">" );
+/*N*/ }
+/*N*/ }
+/*N*/ break;
+/*N*/ default:
+/*N*/ bHandled = FALSE;
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ else if (aRes.TokenType & KParseType::ONE_SINGLE_CHAR)
+/*N*/ {
+/*N*/ sal_Int32 &rnEndPos = aRes.EndPos;
+/*N*/ String aName( BufferString.Copy( nRealStart, rnEndPos - nRealStart ) );
+/*N*/
+/*N*/ if (1 == aName.Len())
+/*N*/ {
+/*N*/ sal_Unicode ch = aName.GetChar( 0 );
+/*N*/ switch (ch)
+/*N*/ {
+/*N*/ case '%':
+/*N*/ {
+/*N*/ //! modifies aRes.EndPos
+/*N*/
+/*N*/ DBG_ASSERT( rnEndPos >= nBufLen ||
+/*N*/ '%' != BufferString.GetChar( rnEndPos ),
+/*N*/ "unexpected comment start" );
+/*N*/
+/*N*/ // get identifier of user-defined character
+/*N*/ ParseResult aTmpRes = rCC.parseAnyToken(
+/*N*/ BufferString, rnEndPos,
+/*N*/ KParseTokens::ANY_LETTER,
+/*N*/ aEmptyStr,
+/*N*/ coContFlags,
+/*N*/ aEmptyStr );
+/*N*/
+/*N*/ xub_StrLen nTmpStart = rnEndPos +
+/*N*/ (xub_StrLen) aTmpRes.LeadingWhiteSpace;
+/*N*/
+/*N*/ // default setting fo the case that no identifier
+/*N*/ // i.e. a valid symbol-name is following the '%'
+/*N*/ // character
+/*N*/ CurToken.eType = TTEXT;
+/*N*/ CurToken.cMathChar = '\0';
+/*N*/ CurToken.nGroup = 0;
+/*N*/ CurToken.nLevel = 5;
+/*N*/ CurToken.aText = String();
+/*N*/ CurToken.nRow = Row;
+/*N*/ CurToken.nCol = nTmpStart - ColOff + 1;
+/*N*/
+/*N*/ if (aTmpRes.TokenType & KParseType::IDENTNAME)
+/*N*/ {
+/*N*/
+/*N*/ INT32 n = aTmpRes.EndPos - nTmpStart;
+/*N*/ CurToken.eType = TSPECIAL;
+/*N*/ CurToken.aText = BufferString.Copy( nTmpStart, n );
+/*N*/
+/*N*/ DBG_ASSERT( aTmpRes.EndPos > rnEndPos,
+/*N*/ "empty identifier" );
+/*N*/ if (aTmpRes.EndPos > rnEndPos)
+/*N*/ rnEndPos = aTmpRes.EndPos;
+/*N*/ else
+/*N*/ ++rnEndPos;
+/*N*/ }
+/*N*/
+/*N*/ // if no symbol-name was found we start-over with
+/*N*/ // finding the next token right afer the '%' sign.
+/*N*/ // I.e. we leave rnEndPos unmodified.
+/*N*/ }
+/*N*/ break;
+/*N*/ case '[':
+/*N*/ {
+/*N*/ CurToken.eType = TLBRACKET;
+/*N*/ CurToken.cMathChar = MS_LBRACKET;
+/*N*/ CurToken.nGroup = TGLBRACES;
+/*N*/ CurToken.nLevel = 5;
+/*N*/ CurToken.aText.AssignAscii( "[" );
+/*N*/ }
+/*N*/ break;
+/*N*/ case '\\':
+/*N*/ {
+/*N*/ CurToken.eType = TESCAPE;
+/*N*/ CurToken.cMathChar = '\0';
+/*N*/ CurToken.nGroup = 0;
+/*N*/ CurToken.nLevel = 5;
+/*N*/ CurToken.aText.AssignAscii( "\\" );
+/*N*/ }
+/*N*/ break;
+/*N*/ case ']':
+/*N*/ {
+/*N*/ CurToken.eType = TRBRACKET;
+/*N*/ CurToken.cMathChar = MS_RBRACKET;
+/*N*/ CurToken.nGroup = TGRBRACES;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( "]" );
+/*N*/ }
+/*N*/ break;
+/*N*/ case '^':
+/*N*/ {
+/*N*/ CurToken.eType = TRSUP;
+/*N*/ CurToken.cMathChar = '\0';
+/*N*/ CurToken.nGroup = TGPOWER;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( "^" );
+/*N*/ }
+/*N*/ break;
+/*N*/ case '`':
+/*N*/ {
+/*N*/ CurToken.eType = TSBLANK;
+/*N*/ CurToken.cMathChar = '\0';
+/*N*/ CurToken.nGroup = TGBLANK;
+/*N*/ CurToken.nLevel = 5;
+/*N*/ CurToken.aText.AssignAscii( "`" );
+/*N*/ }
+/*N*/ break;
+/*N*/ case '{':
+/*N*/ {
+/*N*/ CurToken.eType = TLGROUP;
+/*N*/ CurToken.cMathChar = MS_LBRACE;
+/*N*/ CurToken.nGroup = 0;
+/*N*/ CurToken.nLevel = 5;
+/*N*/ CurToken.aText.AssignAscii( "{" );
+/*N*/ }
+/*N*/ break;
+/*N*/ case '|':
+/*N*/ {
+/*N*/ CurToken.eType = TOR;
+/*N*/ CurToken.cMathChar = MS_OR;
+/*N*/ CurToken.nGroup = TGSUM;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( "|" );
+/*N*/ }
+/*N*/ break;
+/*N*/ case '}':
+/*N*/ {
+/*N*/ CurToken.eType = TRGROUP;
+/*N*/ CurToken.cMathChar = MS_RBRACE;
+/*N*/ CurToken.nGroup = 0;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( "}" );
+/*N*/ }
+/*N*/ break;
+/*N*/ case '~':
+/*N*/ {
+/*N*/ CurToken.eType = TBLANK;
+/*N*/ CurToken.cMathChar = '\0';
+/*N*/ CurToken.nGroup = TGBLANK;
+/*N*/ CurToken.nLevel = 5;
+/*N*/ CurToken.aText.AssignAscii( "~" );
+/*N*/ }
+/*N*/ break;
+/*N*/ case '#':
+/*N*/ {
+/*N*/ if (BufferString.Copy( nRealStart, 2 ).
+/*N*/ EqualsAscii( "##" ))
+/*N*/ {
+/*N*/ CurToken.eType = TDPOUND;
+/*N*/ CurToken.cMathChar = '\0';
+/*N*/ CurToken.nGroup = 0;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( "##" );
+/*N*/
+/*N*/ rnEndPos = nRealStart + 2;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ CurToken.eType = TPOUND;
+/*N*/ CurToken.cMathChar = '\0';
+/*N*/ CurToken.nGroup = 0;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( "#" );
+/*N*/ }
+/*N*/ }
+/*N*/ break;
+/*N*/ case '&':
+/*N*/ {
+/*N*/ CurToken.eType = TAND;
+/*N*/ CurToken.cMathChar = MS_AND;
+/*N*/ CurToken.nGroup = TGPRODUCT;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( "&" );
+/*N*/ }
+/*N*/ break;
+/*N*/ case '(':
+/*N*/ {
+/*N*/ CurToken.eType = TLPARENT;
+/*N*/ CurToken.cMathChar = MS_LPARENT;
+/*N*/ CurToken.nGroup = TGLBRACES;
+/*N*/ CurToken.nLevel = 5; //! 0 to continue expression
+/*N*/ CurToken.aText.AssignAscii( "(" );
+/*N*/ }
+/*N*/ break;
+/*N*/ case ')':
+/*N*/ {
+/*N*/ CurToken.eType = TRPARENT;
+/*N*/ CurToken.cMathChar = MS_RPARENT;
+/*N*/ CurToken.nGroup = TGRBRACES;
+/*N*/ CurToken.nLevel = 0; //! 0 to terminate expression
+/*N*/ CurToken.aText.AssignAscii( ")" );
+/*N*/ }
+/*N*/ break;
+/*N*/ case '*':
+/*N*/ {
+/*N*/ CurToken.eType = TMULTIPLY;
+/*N*/ CurToken.cMathChar = MS_MULTIPLY;
+/*N*/ CurToken.nGroup = TGPRODUCT;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( "*" );
+/*N*/ }
+/*N*/ break;
+/*N*/ case '+':
+/*N*/ {
+/*N*/ if (BufferString.Copy( nRealStart, 2 ).
+/*N*/ EqualsAscii( "+-" ))
+/*N*/ {
+/*N*/ CurToken.eType = TPLUSMINUS;
+/*N*/ CurToken.cMathChar = MS_PLUSMINUS;
+/*N*/ CurToken.nGroup = TGUNOPER | TGSUM;
+/*N*/ CurToken.nLevel = 5;
+/*N*/ CurToken.aText.AssignAscii( "+-" );
+/*N*/
+/*N*/ rnEndPos = nRealStart + 2;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ CurToken.eType = TPLUS;
+/*N*/ CurToken.cMathChar = MS_PLUS;
+/*N*/ CurToken.nGroup = TGUNOPER | TGSUM;
+/*N*/ CurToken.nLevel = 5;
+/*N*/ CurToken.aText.AssignAscii( "+" );
+/*N*/ }
+/*N*/ }
+/*N*/ break;
+/*N*/ case '-':
+/*N*/ {
+/*N*/ if (BufferString.Copy( nRealStart, 2 ).
+/*N*/ EqualsAscii( "-+" ))
+/*N*/ {
+/*N*/ CurToken.eType = TMINUSPLUS;
+/*N*/ CurToken.cMathChar = MS_MINUSPLUS;
+/*N*/ CurToken.nGroup = TGUNOPER | TGSUM;
+/*N*/ CurToken.nLevel = 5;
+/*N*/ CurToken.aText.AssignAscii( "-+" );
+/*N*/
+/*N*/ rnEndPos = nRealStart + 2;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ CurToken.eType = TMINUS;
+/*N*/ CurToken.cMathChar = MS_MINUS;
+/*N*/ CurToken.nGroup = TGUNOPER | TGSUM;
+/*N*/ CurToken.nLevel = 5;
+/*N*/ CurToken.aText.AssignAscii( "-" );
+/*N*/ }
+/*N*/ }
+/*N*/ break;
+/*N*/ case '.':
+/*N*/ {
+/*N*/ // for compatibility with SO5.2
+/*N*/ // texts like .34 ...56 ... h ...78..90
+/*N*/ // will be treated as numbers
+/*N*/ CurToken.eType = TNUMBER;
+/*N*/ CurToken.cMathChar = '\0';
+/*N*/ CurToken.nGroup = 0;
+/*N*/ CurToken.nLevel = 5;
+/*N*/
+/*N*/ xub_StrLen nTxtStart = BufferIndex;
+/*N*/ sal_Unicode cChar;
+/*N*/ do
+/*N*/ {
+/*N*/ cChar = BufferString.GetChar( ++BufferIndex );
+/*N*/ }
+/*N*/ while ( cChar == '.' || ('0' <= cChar && cChar <= '9') );
+/*N*/
+/*N*/ CurToken.aText = BufferString.Copy( nTxtStart, BufferIndex - nTxtStart );
+/*N*/ aRes.EndPos = BufferIndex;
+/*N*/ }
+/*N*/ break;
+/*N*/ case '/':
+/*N*/ {
+/*N*/ CurToken.eType = TDIVIDEBY;
+/*N*/ CurToken.cMathChar = MS_SLASH;
+/*N*/ CurToken.nGroup = TGPRODUCT;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( "/" );
+/*N*/ }
+/*N*/ break;
+/*N*/ case '=':
+/*N*/ {
+/*N*/ CurToken.eType = TASSIGN;
+/*N*/ CurToken.cMathChar = MS_ASSIGN;
+/*N*/ CurToken.nGroup = TGRELATION;
+/*N*/ CurToken.nLevel = 0;
+/*N*/ CurToken.aText.AssignAscii( "=" );
+/*N*/ }
+/*N*/ break;
+/*N*/ default:
+/*N*/ bHandled = FALSE;
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ bHandled = FALSE;
+/*N*/
+/*N*/ if (!bHandled)
+/*N*/ {
+/*N*/ CurToken.eType = TCHARACTER;
+/*N*/ CurToken.cMathChar = '\0';
+/*N*/ CurToken.nGroup = 0;
+/*N*/ CurToken.nLevel = 5;
+/*N*/ CurToken.aText = BufferString.Copy( nRealStart, 1 );
+/*N*/
+/*N*/ aRes.EndPos = nRealStart + 1;
+/*N*/ }
+/*N*/
+/*N*/ if (TEND != CurToken.eType)
+/*N*/ BufferIndex = (xub_StrLen)aRes.EndPos;
+/*N*/ }
+/*N*/
+/*N*/
+////////////////////////////////////////
+// grammar
+//
+
+
+/*N*/ void SmParser::Table()
+/*N*/ {
+/*N*/ SmNodeArray LineArray;
+/*N*/
+/*N*/ Line();
+/*N*/ while (CurToken.eType == TNEWLINE)
+/*N*/ {
+/*N*/ NextToken();
+/*N*/ Line();
+/*N*/ }
+/*N*/
+/*N*/ if (CurToken.eType != TEND)
+/*?*/ Error(PE_UNEXPECTED_CHAR);
+/*N*/
+/*N*/ ULONG n = NodeStack.Count();
+/*N*/
+/*N*/ LineArray.SetSize(n);
+/*N*/
+/*N*/ for (ULONG i = 0; i < n; i++)
+/*N*/ LineArray.Put(n - (i + 1), NodeStack.Pop());
+/*N*/
+/*N*/ SmStructureNode *pSNode = new SmTableNode(CurToken);
+/*N*/ pSNode->SetSubNodes(LineArray);
+/*N*/ NodeStack.Push(pSNode);
+/*N*/ }
+
+
+/*N*/ void SmParser::Align()
+/*N*/ // parse alignment info (if any), then go on with rest of expression
+/*N*/ {
+/*N*/ SmStructureNode *pSNode = 0;
+/*N*/ BOOL bNeedGroupClose = FALSE;
+/*N*/
+/*N*/ if (TokenInGroup(TGALIGN))
+/*N*/ {
+/*?*/ if (CONVERT_40_TO_50 == GetConversion())
+/*?*/ // encapsulate expression to be aligned in group braces
+/*?*/ // (here group-open brace)
+/*?*/ { Insert('{', GetTokenIndex());
+/*?*/ bNeedGroupClose = TRUE;
+/*?*/
+/*?*/ // get first valid align statement in sequence
+/*?*/ // (the dominant one in 4.0) and erase all others (especially old
+/*?*/ // discarded tokens) from command string.
+/*?*/ while (TokenInGroup(TGALIGN))
+/*?*/ { if (TokenInGroup(TGDISCARDED) || pSNode)
+/*?*/ { BufferIndex = GetTokenIndex();
+/*?*/ BufferString.Erase(BufferIndex, CurToken.aText.Len());
+/*?*/ }
+/*?*/ else
+/*?*/ pSNode = new SmAlignNode(CurToken);
+/*?*/
+/*?*/ NextToken();
+/*?*/ }
+/*?*/ }
+/*?*/ else
+/*?*/ {
+/*?*/ pSNode = new SmAlignNode(CurToken);
+/*?*/
+/*?*/ NextToken();
+/*?*/
+/*?*/ // allow for just one align statement in 5.0
+/*?*/ if (CONVERT_40_TO_50 != GetConversion() && TokenInGroup(TGALIGN))
+/*?*/ { Error(PE_DOUBLE_ALIGN);
+/*?*/ return;
+/*?*/ }
+/*?*/ }
+/*?*/ }
+/*N*/
+/*N*/ Expression();
+/*N*/
+/*N*/ if (bNeedGroupClose)
+/*?*/ Insert('}', GetTokenIndex());
+/*N*/
+/*N*/ if (pSNode)
+/*?*/ { pSNode->SetSubNodes(NodeStack.Pop(), 0);
+/*?*/ NodeStack.Push(pSNode);
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ void SmParser::Line()
+/*N*/ {
+/*N*/ USHORT n = 0;
+/*N*/ SmNodeArray ExpressionArray;
+/*N*/
+/*N*/ ExpressionArray.SetSize(n);
+/*N*/
+/*N*/ // start with single expression that may have an alignment statement
+/*N*/ // (and go on with expressions that must not have alignment
+/*N*/ // statements in 'while' loop below. See also 'Expression()'.)
+/*N*/ if (CurToken.eType != TEND && CurToken.eType != TNEWLINE)
+/*N*/ { Align();
+/*N*/ ExpressionArray.SetSize(++n);
+/*N*/ ExpressionArray.Put(n - 1, NodeStack.Pop());
+/*N*/ }
+/*N*/
+/*N*/ while (CurToken.eType != TEND && CurToken.eType != TNEWLINE)
+/*N*/ { if (CONVERT_40_TO_50 != GetConversion())
+/*N*/ Expression();
+/*N*/ else
+/*?*/ Align();
+/*N*/ ExpressionArray.SetSize(++n);
+/*N*/ ExpressionArray.Put(n - 1, NodeStack.Pop());
+/*N*/ }
+/*N*/
+/*N*/ SmStructureNode *pSNode = new SmLineNode(CurToken);
+/*N*/ pSNode->SetSubNodes(ExpressionArray);
+/*N*/ NodeStack.Push(pSNode);
+/*N*/ }
+
+
+/*N*/ void SmParser::Expression()
+/*N*/ {
+/*N*/ USHORT n = 0;
+/*N*/ SmNodeArray RelationArray;
+/*N*/
+/*N*/ RelationArray.SetSize(n);
+/*N*/
+/*N*/ Relation();
+/*N*/ RelationArray.SetSize(++n);
+/*N*/ RelationArray.Put(n - 1, NodeStack.Pop());
+/*N*/
+/*N*/ while (CurToken.nLevel >= 4)
+/*N*/ { Relation();
+/*N*/ RelationArray.SetSize(++n);
+/*N*/ RelationArray.Put(n - 1, NodeStack.Pop());
+/*N*/ }
+/*N*/
+/*N*/ SmStructureNode *pSNode = new SmExpressionNode(CurToken);
+/*N*/ pSNode->SetSubNodes(RelationArray);
+/*N*/ NodeStack.Push(pSNode);
+/*N*/ }
+
+
+/*N*/ void SmParser::Relation()
+/*N*/ {
+/*N*/ Sum();
+/*N*/ while (TokenInGroup(TGRELATION))
+/*N*/ {
+/*N*/ SmStructureNode *pSNode = new SmBinHorNode(CurToken);
+/*N*/ SmNode *pFirst = NodeStack.Pop();
+/*N*/
+/*N*/ OpSubSup();
+/*N*/ SmNode *pSecond = NodeStack.Pop();
+/*N*/
+/*N*/ Sum();
+/*N*/
+/*N*/ pSNode->SetSubNodes(pFirst, pSecond, NodeStack.Pop());
+/*N*/ NodeStack.Push(pSNode);
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ void SmParser::Sum()
+/*N*/ {
+/*N*/ Product();
+/*N*/ while (TokenInGroup(TGSUM))
+/*N*/ {
+/*N*/ SmStructureNode *pSNode = new SmBinHorNode(CurToken);
+/*N*/ SmNode *pFirst = NodeStack.Pop();
+/*N*/
+/*N*/ OpSubSup();
+/*N*/ SmNode *pSecond = NodeStack.Pop();
+/*N*/
+/*N*/ Product();
+/*N*/
+/*N*/ pSNode->SetSubNodes(pFirst, pSecond, NodeStack.Pop());
+/*N*/ NodeStack.Push(pSNode);
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ void SmParser::Product()
+/*N*/ {
+/*N*/ Power();
+/*N*/
+/*N*/ while (TokenInGroup(TGPRODUCT))
+/*N*/ { SmStructureNode *pSNode;
+/*N*/ SmNode *pFirst = NodeStack.Pop(),
+/*N*/ *pOper;
+/*N*/ BOOL bSwitchArgs = FALSE;
+/*N*/
+/*N*/ SmTokenType eType = CurToken.eType;
+/*N*/ switch (eType)
+/*N*/ {
+/*N*/ case TOVER:
+/*N*/ pSNode = new SmBinVerNode(CurToken);
+/*N*/ pOper = new SmRectangleNode(CurToken);
+/*N*/ NextToken();
+/*N*/ break;
+/*N*/
+/*N*/ case TBOPER:
+/*?*/ pSNode = new SmBinHorNode(CurToken);
+/*?*/
+/*?*/ NextToken();
+/*?*/
+/*?*/ GlyphSpecial();
+/*?*/ pOper = NodeStack.Pop();
+/*?*/ break;
+/*N*/
+/*N*/ case TOVERBRACE :
+/*N*/ case TUNDERBRACE :
+/*?*/ pSNode = new SmVerticalBraceNode(CurToken);
+/*?*/ pOper = new SmMathSymbolNode(CurToken);
+/*?*/ NextToken();
+/*?*/ break;
+/*?*/
+/*?*/ case TWIDEBACKSLASH:
+/*?*/ case TWIDESLASH:
+/*?*/ {
+/*?*/ SmBinDiagonalNode *pSTmp = new SmBinDiagonalNode(CurToken);
+/*?*/ pSTmp->SetAscending(eType == TWIDESLASH);
+/*?*/ pSNode = pSTmp;
+/*?*/
+/*?*/ pOper = new SmPolyLineNode(CurToken);
+/*?*/ NextToken();
+/*?*/
+/*?*/ bSwitchArgs =TRUE;
+/*?*/ break;
+/*?*/ }
+/*?*/
+/*N*/ default:
+/*N*/ pSNode = new SmBinHorNode(CurToken);
+/*N*/
+/*N*/ OpSubSup();
+/*N*/ pOper = NodeStack.Pop();
+/*N*/ }
+/*N*/
+/*N*/ Power();
+/*N*/
+/*N*/ if (bSwitchArgs)
+/*N*/ //! vgl siehe SmBinDiagonalNode::Arrange
+/*?*/ pSNode->SetSubNodes(pFirst, NodeStack.Pop(), pOper);
+/*N*/ else
+/*N*/ pSNode->SetSubNodes(pFirst, pOper, NodeStack.Pop());
+/*N*/ NodeStack.Push(pSNode);
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ void SmParser::SubSup(ULONG nActiveGroup)
+/*N*/ {
+/*N*/ DBG_ASSERT(nActiveGroup == TGPOWER || nActiveGroup == TGLIMIT,
+/*N*/ "Sm: falsche Tokengruppe");
+/*N*/
+/*N*/ if (!TokenInGroup(nActiveGroup))
+/*N*/ // already finish
+/*N*/ return;
+/*N*/
+/*N*/ SmSubSupNode *pNode = new SmSubSupNode(CurToken);
+/*N*/ //! Of course 'CurToken' ist just the first sub-/supscript token.
+/*N*/ //! It should be of no further interest. The positions of the
+/*N*/ //! sub-/supscripts will be identified by the corresponding subnodes
+/*N*/ //! index in the 'aSubNodes' array (enum value from 'SmSubSup').
+/*N*/
+/*N*/ pNode->SetUseLimits(nActiveGroup == TGLIMIT);
+/*N*/
+/*N*/ // initialize subnodes array
+/*N*/ SmNodeArray aSubNodes;
+/*N*/ aSubNodes.SetSize(1 + SUBSUP_NUM_ENTRIES);
+/*N*/ aSubNodes.Put(0, NodeStack.Pop());
+/*N*/ for (USHORT i = 1; i < aSubNodes.GetSize(); i++)
+/*N*/ aSubNodes.Put(i, NULL);
+/*N*/
+/*N*/ // process all sub-/supscripts
+/*N*/ int nIndex = 0;
+/*N*/ while (TokenInGroup(nActiveGroup))
+/*N*/ { SmTokenType eType (CurToken.eType);
+/*N*/
+/*N*/ // skip sub-/supscript token
+/*N*/ NextToken();
+/*N*/
+/*N*/ // get sub-/supscript node on top of stack
+/*N*/ if (eType == TFROM || eType == TTO)
+/*N*/ {
+/*N*/ // parse limits in old 4.0 and 5.0 style
+/*N*/ Relation();
+/*N*/ }
+/*N*/ else
+/*N*/ Term();
+/*N*/
+/*N*/ switch (eType)
+/*N*/ { case TRSUB : nIndex = (int) RSUB; break;
+/*N*/ case TRSUP : nIndex = (int) RSUP; break;
+/*N*/ case TFROM :
+/*N*/ case TCSUB : nIndex = (int) CSUB; break;
+/*N*/ case TTO :
+/*N*/ case TCSUP : nIndex = (int) CSUP; break;
+/*N*/ case TLSUB : nIndex = (int) LSUB; break;
+/*N*/ case TLSUP : nIndex = (int) LSUP; break;
+/*N*/ default :
+/*N*/ DBG_ASSERT(FALSE, "Sm: unbekannter Fall");
+/*N*/ }
+/*N*/ nIndex++;
+/*N*/ DBG_ASSERT(1 <= nIndex && nIndex <= 1 + SUBSUP_NUM_ENTRIES,
+/*N*/ "SmParser::Power() : sub-/supscript index falsch");
+/*N*/
+/*N*/ // set sub-/supscript if not already done
+/*N*/ if (aSubNodes.Get(nIndex) != NULL)
+/*?*/ Error(PE_DOUBLE_SUBSUPSCRIPT);
+/*N*/ aSubNodes.Put(nIndex, NodeStack.Pop());
+/*N*/ }
+/*N*/
+/*N*/ pNode->SetSubNodes(aSubNodes);
+/*N*/ NodeStack.Push(pNode);
+/*N*/ }
+
+
+/*N*/ void SmParser::OpSubSup()
+/*N*/ {
+/*N*/ // push operator symbol
+/*N*/ NodeStack.Push(new SmMathSymbolNode(CurToken));
+/*N*/ // skip operator token
+/*N*/ NextToken();
+/*N*/ // get sub- supscripts if any
+/*N*/ if (TokenInGroup(TGPOWER))
+/*?*/ SubSup(TGPOWER);
+/*N*/ }
+
+
+/*N*/ void SmParser::Power()
+/*N*/ {
+/*N*/ // get body for sub- supscripts on top of stack
+/*N*/ Term();
+/*N*/
+/*N*/ SubSup(TGPOWER);
+/*N*/ }
+
+
+/*N*/ void SmParser::Blank()
+/*N*/ {
+/*N*/ DBG_ASSERT(TokenInGroup(TGBLANK), "Sm : falsches Token");
+/*N*/ SmBlankNode *pBlankNode = new SmBlankNode(CurToken);
+/*N*/
+/*N*/ while (TokenInGroup(TGBLANK))
+/*N*/ {
+/*N*/ pBlankNode->IncreaseBy(CurToken);
+/*N*/ NextToken();
+/*N*/ }
+/*N*/
+/*N*/ // Blanks am Zeilenende ignorieren wenn die entsprechende Option gesetzt ist
+/*N*/ if (CurToken.eType == TNEWLINE || CurToken.eType == TEND
+/*N*/ && SM_MOD1()->GetConfig()->IsIgnoreSpacesRight())
+/*?*/ pBlankNode->Clear();
+/*N*/
+/*N*/ NodeStack.Push(pBlankNode);
+/*N*/ }
+
+
+/*N*/ void SmParser::Term()
+/*N*/ {
+/*N*/ switch (CurToken.eType)
+/*N*/ { case TESCAPE :
+/*N*/ Escape();
+/*N*/ break;
+/*N*/
+/*N*/ case TLGROUP :
+/*N*/ NextToken();
+/*N*/
+/*N*/ // allow for empty group
+/*N*/ if (CurToken.eType == TRGROUP)
+/*N*/ { SmStructureNode *pSNode = new SmExpressionNode(CurToken);
+/*N*/ pSNode->SetSubNodes(NULL, NULL);
+/*N*/ NodeStack.Push(pSNode);
+/*N*/
+/*N*/ NextToken();
+/*N*/ }
+/*N*/ else // go as usual
+/*N*/ { Align();
+/*N*/ if (CurToken.eType != TRGROUP)
+/*N*/ Error(PE_RGROUP_EXPECTED);
+/*N*/ else
+/*N*/ { NextToken();
+/*N*/ }
+/*N*/ }
+/*N*/ break;
+/*N*/
+/*N*/ case TLEFT :
+/*N*/ Brace();
+/*N*/ break;
+/*N*/
+/*N*/ case TBLANK :
+/*N*/ case TSBLANK :
+/*N*/ Blank();
+/*N*/ break;
+/*N*/
+/*N*/ case TTEXT :
+/*N*/ NodeStack.Push(new SmTextNode(CurToken, FNT_TEXT));
+/*N*/ NextToken();
+/*N*/ break;
+/*N*/ case TIDENT :
+/*N*/ case TCHARACTER :
+/*N*/ NodeStack.Push(new SmTextNode(CurToken, FNT_VARIABLE));
+/*N*/ NextToken();
+/*N*/ break;
+/*N*/ case TNUMBER :
+/*N*/ NodeStack.Push(new SmTextNode(CurToken, FNT_NUMBER));
+/*N*/ NextToken();
+/*N*/ break;
+/*N*/
+/*N*/ case TLEFTARROW :
+/*N*/ case TRIGHTARROW :
+/*N*/ case TUPARROW :
+/*N*/ case TDOWNARROW :
+/*N*/ case TSETN :
+/*N*/ case TSETZ :
+/*N*/ case TSETQ :
+/*N*/ case TSETR :
+/*N*/ case TSETC :
+/*N*/ case THBAR :
+/*N*/ case TLAMBDABAR :
+/*N*/ case TCIRC :
+/*N*/ case TDRARROW :
+/*N*/ case TDLARROW :
+/*N*/ case TDLRARROW :
+/*N*/ case TBACKEPSILON :
+/*N*/ case TALEPH :
+/*N*/ case TIM :
+/*N*/ case TRE :
+/*N*/ case TWP :
+/*N*/ case TEMPTYSET :
+/*N*/ case TINFINITY :
+/*N*/ case TEXISTS :
+/*N*/ case TFORALL :
+/*N*/ case TPARTIAL :
+/*N*/ case TNABLA :
+/*N*/ case TTOWARD :
+/*N*/ case TDOTSAXIS :
+/*N*/ case TDOTSDIAG :
+/*N*/ case TDOTSDOWN :
+/*N*/ case TDOTSLOW :
+/*N*/ case TDOTSUP :
+/*N*/ case TDOTSVERT :
+/*N*/ NodeStack.Push(new SmMathSymbolNode(CurToken));
+/*N*/ NextToken();
+/*N*/ break;
+/*N*/
+/*N*/ case TPLACE:
+/*N*/ NodeStack.Push(new SmPlaceNode(CurToken));
+/*N*/ NextToken();
+/*N*/ break;
+/*N*/
+/*N*/ case TSPECIAL:
+/*N*/ Special();
+/*N*/ break;
+/*N*/
+/*N*/ case TBINOM:
+/*N*/ Binom(); // matrixfett.smf
+/*N*/ break;
+/*N*/
+/*N*/ case TSTACK:
+/*N*/ Stack(); // matrixfett.smf
+/*?*/ break;
+/*N*/
+/*N*/ case TMATRIX:
+/*N*/ Matrix();
+/*N*/ break;
+/*N*/
+/*N*/ default:
+/*N*/ if (TokenInGroup(TGLBRACES))
+/*N*/ { Brace();
+/*N*/ }
+/*N*/ else if (TokenInGroup(TGOPER))
+/*N*/ { Operator();
+/*N*/ }
+/*N*/ else if (TokenInGroup(TGUNOPER))
+/*N*/ { UnOper();
+/*N*/ }
+/*N*/ else if ( TokenInGroup(TGATTRIBUT)
+/*N*/ || TokenInGroup(TGFONTATTR))
+/*N*/ { SmStructureNodeArray aArray;
+/*N*/
+/*N*/ BOOL bIsAttr;
+/*N*/ USHORT n = 0;
+/*N*/ while ((bIsAttr = TokenInGroup(TGATTRIBUT))
+/*N*/ || TokenInGroup(TGFONTATTR))
+/*N*/ { aArray.SetSize(n + 1);
+/*N*/
+/*N*/ if (bIsAttr)
+/*N*/ Attribut();
+/*N*/ else
+/*N*/ FontAttribut();
+/*N*/
+/*N*/ // check if casting in following line is ok
+/*N*/ DBG_ASSERT(!NodeStack.Top()->IsVisible(), "Sm : Ooops...");
+/*N*/
+/*N*/ aArray.Put(n, (SmStructureNode *) NodeStack.Pop());
+/*N*/ n++;
+/*N*/ }
+/*N*/
+/*N*/ Power();
+/*N*/
+/*N*/ SmNode *pFirstNode = NodeStack.Pop();
+/*N*/ while (n > 0)
+/*N*/ { aArray.Get(n - 1)->SetSubNodes(0, pFirstNode);
+/*N*/ pFirstNode = aArray.Get(n - 1);
+/*N*/ n--;
+/*N*/ }
+/*N*/ NodeStack.Push(pFirstNode);
+/*N*/ }
+/*N*/ else if (TokenInGroup(TGFUNCTION))
+/*N*/ { if (CONVERT_40_TO_50 != GetConversion())
+/*N*/ { Function();
+/*N*/ }
+/*N*/ else // encapsulate old 4.0 style parsing in braces
+/*N*/ {
+/*N*/ // insert opening brace
+/*N*/ Insert('{', GetTokenIndex());
+/*N*/
+/*N*/ //
+/*N*/ // parse in 4.0 style
+/*N*/ //
+/*N*/ Function();
+/*N*/
+/*N*/ SmNode *pFunc = NodeStack.Pop();
+/*N*/
+/*N*/ if (CurToken.eType == TLPARENT)
+/*?*/ { Term();
+/*N*/ }
+/*N*/ else
+/*N*/ { Align();
+/*N*/ }
+/*N*/
+/*N*/ // insert closing brace
+/*N*/ Insert('}', GetTokenIndex());
+/*N*/
+/*N*/ SmStructureNode *pSNode = new SmExpressionNode(pFunc->GetToken());
+/*N*/ pSNode->SetSubNodes(pFunc, NodeStack.Pop());
+/*N*/ NodeStack.Push(pSNode);
+/*N*/ }
+/*N*/ }
+/*N*/ else
+/*N*/ Error(PE_UNEXPECTED_CHAR);
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ void SmParser::Escape()
+/*N*/ {
+/*N*/ NextToken();
+/*N*/
+/*N*/ sal_Unicode cChar;
+/*N*/ switch (CurToken.eType)
+/*N*/ { case TLPARENT : cChar = MS_LPARENT; break;
+/*N*/ case TRPARENT : cChar = MS_RPARENT; break;
+/*N*/ case TLBRACKET : cChar = MS_LBRACKET; break;
+/*N*/ case TRBRACKET : cChar = MS_RBRACKET; break;
+/*N*/ case TLDBRACKET : cChar = MS_LDBRACKET; break;
+/*N*/ case TRDBRACKET : cChar = MS_RDBRACKET; break;
+/*N*/ case TLBRACE :
+/*N*/ case TLGROUP : cChar = MS_LBRACE; break;
+/*N*/ case TRBRACE :
+/*N*/ case TRGROUP : cChar = MS_RBRACE; break;
+/*N*/ case TLANGLE : cChar = MS_LANGLE; break;
+/*N*/ case TRANGLE : cChar = MS_RANGLE; break;
+/*N*/ case TLCEIL : cChar = MS_LCEIL; break;
+/*N*/ case TRCEIL : cChar = MS_RCEIL; break;
+/*N*/ case TLFLOOR : cChar = MS_LFLOOR; break;
+/*N*/ case TRFLOOR : cChar = MS_RFLOOR; break;
+/*N*/ case TLLINE :
+/*N*/ case TRLINE : cChar = MS_LINE; break;
+/*N*/ case TLDLINE :
+/*N*/ case TRDLINE : cChar = MS_DLINE; break;
+/*N*/ default:
+/*N*/ Error(PE_UNEXPECTED_TOKEN);
+/*N*/ }
+/*N*/
+/*N*/ SmNode *pNode = new SmMathSymbolNode(CurToken);
+/*N*/ NodeStack.Push(pNode);
+/*N*/
+/*N*/ NextToken();
+/*N*/ }
+
+
+/*N*/ void SmParser::Operator()
+/*N*/ {
+/*N*/ if (TokenInGroup(TGOPER))
+/*N*/ { SmStructureNode *pSNode = new SmOperNode(CurToken);
+/*N*/
+/*N*/ // put operator on top of stack
+/*N*/ Oper();
+/*N*/
+/*N*/ if (TokenInGroup(TGLIMIT) || TokenInGroup(TGPOWER))
+/*N*/ SubSup(CurToken.nGroup);
+/*N*/ SmNode *pOperator = NodeStack.Pop();
+/*N*/
+/*N*/ // get argument
+/*N*/ Power();
+/*N*/
+/*N*/ pSNode->SetSubNodes(pOperator, NodeStack.Pop());
+/*N*/ NodeStack.Push(pSNode);
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ void SmParser::Oper()
+/*N*/ {
+/*N*/ SmTokenType eType (CurToken.eType);
+/*N*/ SmNode *pNode = NULL;
+/*N*/
+/*N*/ switch (eType)
+/*N*/ {
+/*N*/ case TSUM :
+/*N*/ case TPROD :
+/*N*/ case TCOPROD :
+/*N*/ case TINT :
+/*N*/ case TIINT :
+/*N*/ case TIIINT :
+/*N*/ case TLINT :
+/*N*/ case TLLINT :
+/*N*/ case TLLLINT :
+/*N*/ pNode = new SmMathSymbolNode(CurToken);
+/*N*/ break;
+/*N*/
+/*N*/ case TLIM :
+/*N*/ case TLIMSUP :
+/*N*/ case TLIMINF :
+/*N*/ {
+/*N*/ const sal_Char* pLim = 0;
+/*N*/ switch (eType)
+/*N*/ {
+/*N*/ case TLIM : pLim = "lim"; break;
+/*N*/ case TLIMSUP : pLim = "lim sup"; break;
+/*N*/ case TLIMINF : pLim = "lim inf"; break;
+/*N*/ }
+/*N*/ if( pLim )
+/*N*/ CurToken.aText.AssignAscii( pLim );
+/*N*/ pNode = new SmTextNode(CurToken, FNT_TEXT);
+/*N*/ }
+/*N*/ break;
+/*N*/
+/*N*/ case TOVERBRACE :
+/*N*/ case TUNDERBRACE :
+/*N*/ pNode = new SmMathSymbolNode(CurToken);
+/*N*/ break;
+/*N*/
+/*N*/ case TOPER :
+/*?*/ NextToken();
+/*N*/
+/*?*/ DBG_ASSERT(CurToken.eType == TSPECIAL, "Sm: falsches Token");
+/*?*/ pNode = new SmGlyphSpecialNode(CurToken);
+/*?*/ break;
+/*N*/
+/*N*/ default :
+/*N*/ DBG_ASSERT(0, "Sm: unbekannter Fall");
+/*N*/ }
+/*N*/ NodeStack.Push(pNode);
+/*N*/
+/*N*/ NextToken();
+/*N*/ }
+
+
+/*N*/ void SmParser::UnOper()
+/*N*/ {
+/*N*/ DBG_ASSERT(TokenInGroup(TGUNOPER), "Sm: falsches Token");
+/*N*/
+/*N*/ SmToken aNodeToken = CurToken;
+/*N*/ SmTokenType eType = CurToken.eType;
+/*N*/ BOOL bIsPostfix = eType == TFACT;
+/*N*/
+/*N*/ SmStructureNode *pSNode;
+/*N*/ SmNode *pOper,
+/*N*/ *pExtra = 0,
+/*N*/ *pArg;
+/*N*/
+/*N*/ switch (eType)
+/*N*/ {
+/*N*/ case TABS :
+/*N*/ case TSQRT :
+/*N*/ NextToken();
+/*N*/ break;
+/*N*/
+/*N*/ case TNROOT :
+/*N*/ NextToken();
+/*N*/ Power();
+/*N*/ pExtra = NodeStack.Pop();
+/*N*/ break;
+/*N*/
+/*N*/ case TUOPER :
+/*?*/ NextToken();
+/*?*/ GlyphSpecial();
+/*?*/ pOper = NodeStack.Pop();
+/*?*/ break;
+/*N*/
+/*N*/ case TPLUS :
+/*N*/ case TMINUS :
+/*N*/ case TPLUSMINUS :
+/*N*/ case TMINUSPLUS :
+/*N*/ case TNEG :
+/*N*/ case TFACT :
+/*N*/ OpSubSup();
+/*N*/ pOper = NodeStack.Pop();
+/*N*/ break;
+/*N*/
+/*N*/ default :
+/*N*/ Error(PE_UNOPER_EXPECTED);
+/*N*/ }
+/*N*/
+/*N*/ // get argument
+/*N*/ Power();
+/*N*/ pArg = NodeStack.Pop();
+/*N*/
+/*N*/ if (eType == TABS)
+/*N*/ { pSNode = new SmBraceNode(aNodeToken);
+/*N*/ pSNode->SetScaleMode(SCALE_HEIGHT);
+/*N*/
+/*N*/ // build nodes for left & right lines
+/*N*/ // (text, group, level of the used token are of no interrest here)
+/*N*/ // we'll use row & column of the keyword for abs
+/*N*/ aNodeToken.eType = TABS;
+/*N*/ //
+/*N*/ aNodeToken.cMathChar = MS_LINE;
+/*N*/ SmNode* pLeft = new SmMathSymbolNode(aNodeToken);
+/*N*/ //
+/*N*/ aNodeToken.cMathChar = MS_LINE;
+/*N*/ SmNode* pRight = new SmMathSymbolNode(aNodeToken);
+/*N*/
+/*N*/ pSNode->SetSubNodes(pLeft, pArg, pRight);
+/*N*/ }
+/*N*/ else if (eType == TSQRT || eType == TNROOT)
+/*N*/ { pSNode = new SmRootNode(aNodeToken);
+/*N*/ pOper = new SmRootSymbolNode(aNodeToken);
+/*N*/ pSNode->SetSubNodes(pExtra, pOper, pArg);
+/*N*/ }
+/*N*/ else
+/*N*/ { pSNode = new SmUnHorNode(aNodeToken);
+/*N*/
+/*N*/ if (bIsPostfix)
+/*N*/ pSNode->SetSubNodes(pArg, pOper);
+/*N*/ else
+/*N*/ // prefix operator
+/*N*/ pSNode->SetSubNodes(pOper, pArg);
+/*N*/ }
+/*N*/
+/*N*/ NodeStack.Push(pSNode);
+/*N*/ }
+
+
+/*N*/ void SmParser::Attribut()
+/*N*/ {
+/*N*/ DBG_ASSERT(TokenInGroup(TGATTRIBUT), "Sm: falsche Tokengruppe");
+/*N*/
+/*N*/ SmStructureNode *pSNode = new SmAttributNode(CurToken);
+/*N*/ SmNode *pAttr;
+/*N*/ SmScaleMode eScaleMode = SCALE_NONE;
+/*N*/
+/*N*/ // get appropriate node for the attribut itself
+/*N*/ switch (CurToken.eType)
+/*N*/ { case TUNDERLINE :
+/*N*/ case TOVERLINE :
+/*N*/ case TOVERSTRIKE :
+/*?*/ pAttr = new SmRectangleNode(CurToken);
+/*?*/ eScaleMode = SCALE_WIDTH;
+/*?*/ break;
+/*N*/
+/*N*/ case TWIDEVEC :
+/*N*/ case TWIDEHAT :
+/*N*/ case TWIDETILDE :
+/*N*/ pAttr = new SmMathSymbolNode(CurToken);
+/*N*/ eScaleMode = SCALE_WIDTH;
+/*?*/ break;
+/*N*/
+/*N*/ default :
+/*N*/ pAttr = new SmMathSymbolNode(CurToken);
+/*N*/ }
+/*N*/
+/*N*/ NextToken();
+/*N*/
+/*N*/ pSNode->SetSubNodes(pAttr, 0);
+/*N*/ pSNode->SetScaleMode(eScaleMode);
+/*N*/ NodeStack.Push(pSNode);
+/*N*/ }
+
+
+/*N*/ void SmParser::FontAttribut()
+/*N*/ {
+/*N*/ DBG_ASSERT(TokenInGroup(TGFONTATTR), "Sm: falsche Tokengruppe");
+/*N*/
+/*N*/ switch (CurToken.eType)
+/*N*/ {
+/*N*/ case TITALIC :
+/*N*/ case TNITALIC :
+/*N*/ case TBOLD :
+/*N*/ case TNBOLD :
+/*N*/ case TPHANTOM :
+/*N*/ NodeStack.Push(new SmFontNode(CurToken));
+/*N*/ NextToken();
+/*N*/ break;
+/*N*/
+/*N*/ case TSIZE :
+/*N*/ FontSize();
+/*N*/ break;
+/*N*/
+/*N*/ case TFONT :
+/*N*/ Font();
+/*N*/ break;
+/*N*/
+/*N*/ case TCOLOR :
+/*N*/ Color();
+/*N*/ break;
+/*N*/
+/*N*/ default :
+/*N*/ DBG_ASSERT(0, "Sm: unbekannter Fall");
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ void SmParser::Color()
+/*N*/ {
+/*N*/ DBG_ASSERT(CurToken.eType == TCOLOR, "Sm : Ooops...");
+/*N*/
+/*N*/ // last color rules, get that one
+/*N*/ SmToken aToken;
+/*N*/ do
+/*N*/ { NextToken();
+/*N*/
+/*N*/ if (TokenInGroup(TGCOLOR))
+/*N*/ { aToken = CurToken;
+/*N*/ NextToken();
+/*N*/ }
+/*N*/ else
+/*N*/ Error(PE_COLOR_EXPECTED);
+/*N*/ } while (CurToken.eType == TCOLOR);
+/*N*/
+/*N*/ NodeStack.Push(new SmFontNode(aToken));
+/*N*/ }
+
+
+/*N*/ void SmParser::Font()
+/*N*/ {
+/*N*/ DBG_ASSERT(CurToken.eType == TFONT, "Sm : Ooops...");
+/*N*/
+/*N*/ // last font rules, get that one
+/*N*/ SmToken aToken;
+/*N*/ do
+/*N*/ { NextToken();
+/*N*/
+/*N*/ if (TokenInGroup(TGFONT))
+/*N*/ { aToken = CurToken;
+/*N*/ NextToken();
+/*N*/ }
+/*N*/ else
+/*N*/ Error(PE_FONT_EXPECTED);
+/*N*/ } while (CurToken.eType == TFONT);
+/*N*/
+/*N*/ NodeStack.Push(new SmFontNode(aToken));
+/*N*/ }
+/*N*/ BOOL lcl_IsNumber(const UniString& rText)
+/*N*/ {
+/*N*/ BOOL bPoint = FALSE;
+/*N*/ const sal_Unicode* pBuffer = rText.GetBuffer();
+/*N*/ for(xub_StrLen nPos = 0; nPos < rText.Len(); nPos++, pBuffer++)
+/*N*/ {
+/*N*/ const sal_Unicode cChar = *pBuffer;
+/*N*/ if(cChar == '.')
+/*N*/ {
+/*N*/ if(bPoint)
+/*N*/ return FALSE;
+/*N*/ else
+/*N*/ bPoint = TRUE;
+/*N*/ }
+/*N*/ else if ( (cChar < 48) || (cChar > 57) )
+/*N*/ return FALSE;
+/*N*/ }
+/*N*/ return TRUE;
+/*N*/ }
+
+/*N*/ void SmParser::FontSize()
+/*N*/ {
+/*N*/ DBG_ASSERT(CurToken.eType == TSIZE, "Sm : Ooops...");
+/*N*/
+/*N*/ USHORT Type;
+/*N*/ SmFontNode *pFontNode = new SmFontNode(CurToken);
+/*N*/
+/*N*/ NextToken();
+/*N*/
+/*N*/ switch (CurToken.eType)
+/*N*/ {
+/*N*/ case TNUMBER: Type = FNTSIZ_ABSOLUT; break;
+/*N*/ case TPLUS: Type = FNTSIZ_PLUS; break;
+/*N*/ case TMINUS: Type = FNTSIZ_MINUS; break;
+/*N*/ case TMULTIPLY: Type = FNTSIZ_MULTIPLY; break;
+/*N*/ case TDIVIDEBY: Type = FNTSIZ_DIVIDE; break;
+/*N*/
+/*N*/ default:
+/*?*/ delete pFontNode;
+/*?*/ Error(PE_SIZE_EXPECTED);
+/*?*/ return;
+/*N*/ }
+/*N*/
+/*N*/ if (Type != FNTSIZ_ABSOLUT)
+/*N*/ {
+/*N*/ NextToken();
+/*N*/ if (CurToken.eType != TNUMBER)
+/*N*/ {
+/*?*/ delete pFontNode;
+/*?*/ Error(PE_SIZE_EXPECTED);
+/*?*/ return;
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ // get number argument
+/*N*/ double fTmp;
+/*N*/ Fraction aValue;
+/*N*/ if(lcl_IsNumber(CurToken.aText) &&
+/*N*/ sscanf(ByteString(CurToken.aText, RTL_TEXTENCODING_ASCII_US).GetBuffer(), "%lf", &fTmp) == 1)
+/*N*/ aValue = fTmp;
+/*N*/
+/*N*/ NextToken();
+/*N*/
+/*N*/ pFontNode->SetSizeParameter(aValue, Type);
+/*N*/ NodeStack.Push(pFontNode);
+/*N*/ }
+
+
+/*N*/ void SmParser::Brace()
+/*N*/ {
+/*N*/ DBG_ASSERT(CurToken.eType == TLEFT || TokenInGroup(TGLBRACES),
+/*N*/ "Sm: kein Klammer Ausdruck");
+/*N*/
+/*N*/ SmStructureNode *pSNode = new SmBraceNode(CurToken);
+/*N*/ SmNode *pBody = 0,
+/*N*/ *pLeft = 0,
+/*N*/ *pRight = 0;
+/*N*/ SmScaleMode eScaleMode = SCALE_NONE;
+/*N*/ SmParseError eError = PE_NONE;
+/*N*/
+/*N*/ if (CurToken.eType == TLEFT)
+/*N*/ { NextToken();
+/*N*/
+/*N*/ eScaleMode = SCALE_HEIGHT;
+/*N*/
+/*N*/ // check for left bracket
+/*N*/ if (TokenInGroup(TGLBRACES) || TokenInGroup(TGRBRACES))
+/*N*/ {
+/*N*/ pLeft = new SmMathSymbolNode(CurToken);
+/*N*/
+/*N*/ NextToken();
+/*N*/ Bracebody(TRUE);
+/*N*/ pBody = NodeStack.Pop();
+/*N*/
+/*N*/ if (CurToken.eType == TRIGHT)
+/*N*/ { NextToken();
+/*N*/
+/*N*/ // check for right bracket
+/*N*/ if (TokenInGroup(TGLBRACES) || TokenInGroup(TGRBRACES))
+/*N*/ {
+/*N*/ pRight = new SmMathSymbolNode(CurToken);
+/*N*/ NextToken();
+/*N*/ }
+/*N*/ else
+/*N*/ eError = PE_RBRACE_EXPECTED;
+/*N*/ }
+/*N*/ else
+/*N*/ eError = PE_RIGHT_EXPECTED;
+/*N*/ }
+/*N*/ else
+/*N*/ eError = PE_LBRACE_EXPECTED;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ if (TokenInGroup(TGLBRACES))
+/*N*/ {
+/*N*/ pLeft = new SmMathSymbolNode(CurToken);
+/*N*/
+/*N*/ NextToken();
+/*N*/ Bracebody(FALSE);
+/*N*/ pBody = NodeStack.Pop();
+/*N*/
+/*N*/ SmTokenType eExpectedType = TUNKNOWN;
+/*N*/ switch (pLeft->GetToken().eType)
+/*N*/ { case TLPARENT : eExpectedType = TRPARENT; break;
+/*N*/ case TLBRACKET : eExpectedType = TRBRACKET; break;
+/*N*/ case TLBRACE : eExpectedType = TRBRACE; break;
+/*N*/ case TLDBRACKET : eExpectedType = TRDBRACKET; break;
+/*N*/ case TLLINE : eExpectedType = TRLINE; break;
+/*N*/ case TLDLINE : eExpectedType = TRDLINE; break;
+/*N*/ case TLANGLE : eExpectedType = TRANGLE; break;
+/*N*/ case TLFLOOR : eExpectedType = TRFLOOR; break;
+/*N*/ case TLCEIL : eExpectedType = TRCEIL; break;
+/*N*/ default :
+/*N*/ DBG_ASSERT(0, "Sm: unbekannter Fall");
+/*N*/ }
+/*N*/
+/*N*/ if (CurToken.eType == eExpectedType)
+/*N*/ {
+/*N*/ pRight = new SmMathSymbolNode(CurToken);
+/*N*/ NextToken();
+/*N*/ }
+/*N*/ else
+/*N*/ eError = PE_PARENT_MISMATCH;
+/*N*/ }
+/*N*/ else
+/*N*/ eError = PE_LBRACE_EXPECTED;
+/*N*/ }
+/*N*/
+/*N*/ if (eError == PE_NONE)
+/*N*/ { DBG_ASSERT(pLeft, "Sm: NULL pointer");
+/*N*/ DBG_ASSERT(pRight, "Sm: NULL pointer");
+/*N*/ pSNode->SetSubNodes(pLeft, pBody, pRight);
+/*N*/ pSNode->SetScaleMode(eScaleMode);
+/*N*/ NodeStack.Push(pSNode);
+/*N*/ }
+/*N*/ else
+/*N*/ { delete pSNode;
+/*N*/ delete pBody;
+/*N*/ delete pLeft;
+/*N*/ delete pRight;
+/*N*/
+/*N*/ Error(eError);
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ void SmParser::Bracebody(BOOL bIsLeftRight)
+/*N*/ {
+/*N*/ SmStructureNode *pBody = new SmBracebodyNode(CurToken);
+/*N*/ SmNodeArray aNodes;
+/*N*/ USHORT nNum = 0;
+/*N*/
+/*N*/ // get body if any
+/*N*/ if (bIsLeftRight)
+/*N*/ {
+/*N*/ do
+/*N*/ {
+/*N*/ if (CurToken.eType == TMLINE)
+/*N*/ {
+/*N*/ NodeStack.Push(new SmMathSymbolNode(CurToken));
+/*N*/ NextToken();
+/*N*/ nNum++;
+/*N*/ }
+/*N*/ else if (CurToken.eType != TRIGHT)
+/*N*/ { Align();
+/*N*/ nNum++;
+/*N*/
+/*N*/ if (CurToken.eType != TMLINE && CurToken.eType != TRIGHT)
+/*N*/ Error(PE_RIGHT_EXPECTED);
+/*N*/ }
+/*N*/ } while (CurToken.eType != TEND && CurToken.eType != TRIGHT);
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ do
+/*N*/ {
+/*N*/ if (CurToken.eType == TMLINE)
+/*N*/ {
+/*N*/ NodeStack.Push(new SmMathSymbolNode(CurToken));
+/*N*/ NextToken();
+/*N*/ nNum++;
+/*N*/ }
+/*N*/ else if (!TokenInGroup(TGRBRACES))
+/*N*/ { Align();
+/*N*/ nNum++;
+/*N*/
+/*N*/ if (CurToken.eType != TMLINE && !TokenInGroup(TGRBRACES))
+/*N*/ Error(PE_RBRACE_EXPECTED);
+/*N*/ }
+/*N*/ } while (CurToken.eType != TEND && !TokenInGroup(TGRBRACES));
+/*N*/ }
+/*N*/
+/*N*/ // build argument vector in parsing order
+/*N*/ aNodes.SetSize(nNum);
+/*N*/ for (USHORT i = 0; i < nNum; i++)
+/*N*/ aNodes.Put(nNum - 1 - i, NodeStack.Pop());
+/*N*/
+/*N*/ pBody->SetSubNodes(aNodes);
+/*N*/ pBody->SetScaleMode(bIsLeftRight ? SCALE_HEIGHT : SCALE_NONE);
+/*N*/ NodeStack.Push(pBody);
+/*N*/ }
+
+
+/*N*/ void SmParser::Function()
+/*N*/ {
+/*N*/ switch (CurToken.eType)
+/*N*/ {
+/*N*/ case TFUNC:
+/*N*/ NextToken(); // skip "FUNC"-statement
+/*N*/ // fall through
+/*N*/
+/*N*/ case TSIN :
+/*N*/ case TCOS :
+/*N*/ case TTAN :
+/*N*/ case TCOT :
+/*N*/ case TASIN :
+/*N*/ case TACOS :
+/*N*/ case TATAN :
+/*N*/ case TACOT :
+/*N*/ case TSINH :
+/*N*/ case TCOSH :
+/*N*/ case TTANH :
+/*N*/ case TCOTH :
+/*N*/ case TASINH :
+/*N*/ case TACOSH :
+/*N*/ case TATANH :
+/*N*/ case TACOTH :
+/*N*/ case TLN :
+/*N*/ case TLOG :
+/*N*/ case TEXP :
+/*N*/ NodeStack.Push(new SmTextNode(CurToken, FNT_FUNCTION));
+/*N*/ NextToken();
+/*N*/ break;
+/*N*/
+/*N*/ default:
+/*N*/ Error(PE_FUNC_EXPECTED);
+/*N*/ }
+/*N*/ }
+
+
+/*N*/ void SmParser::Binom() // matrixfett.smf
+/*N*/ {
+/*N*/ SmNodeArray ExpressionArray;
+/*N*/ SmStructureNode *pSNode = new SmTableNode(CurToken);
+/*N*/
+/*N*/ NextToken();
+/*N*/
+/*N*/ Sum();
+/*N*/ Sum();
+/*N*/
+/*N*/ ExpressionArray.SetSize(2);
+/*N*/
+/*N*/ for (int i = 0; i < 2; i++)
+/*N*/ ExpressionArray.Put(2 - (i + 1), NodeStack.Pop());
+/*N*/
+/*N*/ pSNode->SetSubNodes(ExpressionArray);
+/*N*/ NodeStack.Push(pSNode);
+/*N*/ }
+
+
+/*N*/ void SmParser::Stack() // matrixfett.smf
+/*N*/ {
+/*N*/ SmNodeArray ExpressionArray;
+/*N*/ NextToken();
+/*N*/ if (CurToken.eType == TLGROUP)
+/*N*/ {
+/*N*/ USHORT n = 0;
+/*N*/
+/*N*/ do
+/*N*/ {
+/*N*/ NextToken();
+/*N*/ Align();
+/*N*/ n++;
+/*N*/ }
+/*N*/ while (CurToken.eType == TPOUND);
+/*N*/
+/*N*/ ExpressionArray.SetSize(n);
+/*N*/
+/*N*/ for (USHORT i = 0; i < n; i++)
+/*N*/ ExpressionArray.Put(n - (i + 1), NodeStack.Pop());
+/*N*/
+/*N*/ if (CurToken.eType != TRGROUP)
+/*N*/ Error(PE_RGROUP_EXPECTED);
+/*N*/
+/*N*/ NextToken();
+/*N*/
+/*N*/ SmStructureNode *pSNode = new SmTableNode(CurToken);
+/*N*/ pSNode->SetSubNodes(ExpressionArray);
+/*N*/ NodeStack.Push(pSNode);
+/*N*/ }
+/*N*/ else
+/*N*/ Error(PE_LGROUP_EXPECTED);
+/*N*/ }
+
+
+/*N*/ void SmParser::Matrix()
+/*N*/ {
+/*N*/ SmNodeArray ExpressionArray;
+/*N*/
+/*N*/ NextToken();
+/*N*/ if (CurToken.eType == TLGROUP)
+/*N*/ {
+/*N*/ USHORT c = 0;
+/*N*/
+/*N*/ do
+/*N*/ {
+/*N*/ NextToken();
+/*N*/ Align();
+/*N*/ c++;
+/*N*/ }
+/*N*/ while (CurToken.eType == TPOUND);
+/*N*/
+/*N*/ USHORT r = 1;
+/*N*/
+/*N*/ while (CurToken.eType == TDPOUND)
+/*N*/ {
+/*N*/ NextToken();
+/*N*/ for (USHORT i = 0; i < c; i++)
+/*N*/ {
+/*N*/ Align();
+/*N*/ if (i < (c - 1))
+/*N*/ {
+/*N*/ if (CurToken.eType == TPOUND)
+/*N*/ {
+/*N*/ NextToken();
+/*N*/ }
+/*N*/ else
+/*N*/ Error(PE_POUND_EXPECTED);
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ r++;
+/*N*/ }
+/*N*/
+/*N*/ long nRC = r * c;
+/*N*/
+/*N*/ ExpressionArray.SetSize(nRC);
+/*N*/
+/*N*/ for (USHORT i = 0; i < (nRC); i++)
+/*N*/ ExpressionArray.Put((nRC) - (i + 1), NodeStack.Pop());
+/*N*/
+/*N*/ if (CurToken.eType != TRGROUP)
+/*N*/ Error(PE_RGROUP_EXPECTED);
+/*N*/
+/*N*/ NextToken();
+/*N*/
+/*N*/ SmMatrixNode *pMNode = new SmMatrixNode(CurToken);
+/*N*/ pMNode->SetSubNodes(ExpressionArray);
+/*N*/ pMNode->SetRowCol(r, c);
+/*N*/ NodeStack.Push(pMNode);
+/*N*/ }
+/*N*/ else
+/*N*/ Error(PE_LGROUP_EXPECTED);
+/*N*/ }
+
+
+/*N*/ void SmParser::Special()
+/*M*/ {
+/*M*/ BOOL bReplace = FALSE;
+/*M*/ String &rName = CurToken.aText;
+/*M*/ String aNewName;
+/*M*/
+/*M*/ if (CONVERT_NONE == GetConversion())
+/*M*/ {
+/*M*/ // conversion of symbol names for 6.0 (XML) file format
+/*M*/ // (name change on import / export.
+/*M*/ // UI uses localized names XML file format does not.)
+/*M*/ if (IsImportSymbolNames())
+/*M*/ {
+/*M*/ const SmLocalizedSymbolData &rLSD = SM_MOD1()->GetLocSymbolData();
+/*M*/ aNewName = rLSD.GetUiSymbolName( rName );
+/*M*/ bReplace = TRUE;
+/*M*/ }
+/*M*/ else if (IsExportSymbolNames())
+/*M*/ {
+/*M*/ const SmLocalizedSymbolData &rLSD = SM_MOD1()->GetLocSymbolData();
+/*M*/ aNewName = rLSD.GetExportSymbolName( rName );
+/*M*/ bReplace = TRUE;
+/*M*/ }
+/*M*/ }
+/*M*/ else // 5.0 <-> 6.0 formula text (symbol name) conversion
+/*M*/ {
+/*M*/ LanguageType nLang = GetLanguage();
+/*M*/ SmLocalizedSymbolData &rData = SM_MOD1()->GetLocSymbolData();
+/*M*/ const ResStringArray *pFrom = 0;
+/*M*/ const ResStringArray *pTo = 0;
+/*M*/ if (CONVERT_50_TO_60 == GetConversion())
+/*M*/ {
+/*M*/ pFrom = rData.Get50NamesArray( nLang );
+/*M*/ pTo = rData.Get60NamesArray( nLang );
+/*M*/ }
+/*M*/ else if (CONVERT_60_TO_50 == GetConversion())
+/*M*/ {
+/*M*/ pFrom = rData.Get60NamesArray( nLang );
+/*M*/ pTo = rData.Get50NamesArray( nLang );
+/*M*/ }
+/*M*/ if (pFrom && pTo)
+/*M*/ {
+/*M*/ DBG_ASSERT( pFrom->Count() == pTo->Count(),
+/*M*/ "array length mismatch" );
+/*M*/ USHORT nCount = pFrom->Count();
+/*M*/ for (USHORT i = 0; i < nCount; ++i)
+/*M*/ {
+/*M*/ if (pFrom->GetString(i) == rName)
+/*M*/ {
+/*M*/ aNewName = pTo->GetString(i);
+/*M*/ bReplace = TRUE;
+/*M*/ }
+/*M*/ }
+/*M*/ }
+/*M*/ // else:
+/*M*/ // conversion arrays not found or (usually)
+/*M*/ // conversion not necessary
+/*M*/ }
+/*M*/
+/*M*/ if (bReplace && aNewName.Len() && rName != aNewName)
+/*M*/ {
+/*M*/ Replace( GetTokenIndex() + 1, rName.Len(), aNewName );
+/*M*/ rName = aNewName;
+/*M*/ }
+/*M*/
+/*M*/ NodeStack.Push(new SmSpecialNode(CurToken));
+/*M*/ NextToken();
+/*M*/ }
+
+
+/*?*/ void SmParser::GlyphSpecial()
+/*?*/ {
+/*?*/ NodeStack.Push(new SmGlyphSpecialNode(CurToken));
+/*?*/ NextToken();
+/*?*/ }
+
+
+/*N*/ void SmParser::Error(SmParseError eError)
+/*N*/ {
+/*N*/ SmStructureNode *pSNode = new SmExpressionNode(CurToken);
+/*N*/ SmErrorNode *pErr = new SmErrorNode(eError, CurToken);
+/*N*/ pSNode->SetSubNodes(pErr, 0);
+/*N*/
+/*N*/ //! put a structure node on the stack (instead of the error node itself)
+/*N*/ //! because sometimes such a node is expected in order to attach some
+/*N*/ //! subnodes
+/*N*/ NodeStack.Push(pSNode);
+/*N*/
+/*N*/ AddError(eError, pSNode);
+/*N*/
+/*N*/ NextToken();
+/*N*/ }
+
+
+// end gramar
+
+
+/*N*/ SmParser::SmParser()
+/*N*/ {
+/*N*/ eConversion = CONVERT_NONE;
+/*N*/ bImportSymNames = bExportSymNames = FALSE;
+/*N*/ nLang = Application::GetSettings().GetUILanguage();
+/*N*/ }
+
+
+/*N*/ SmNode *SmParser::Parse(const String &rBuffer)
+/*N*/ {
+/*N*/ BufferString = rBuffer;
+/*N*/ BufferString.ConvertLineEnd( LINEEND_LF );
+/*N*/ BufferIndex =
+/*N*/ nTokenIndex = 0;
+/*N*/ Row = 1;
+/*N*/ ColOff = 0;
+/*N*/ CurError = -1;
+/*N*/
+/*N*/ for (USHORT i = 0; i < ErrDescList.Count(); i++)
+/*N*/ delete ErrDescList.Remove(i);
+/*N*/
+/*N*/ ErrDescList.Clear();
+/*N*/
+/*N*/ NodeStack.Clear();
+/*N*/
+/*N*/ SetLanguage( Application::GetSettings().GetUILanguage() );
+/*N*/ NextToken();
+/*N*/ Table();
+/*N*/
+/*N*/ return NodeStack.Pop();
+/*N*/ }
+
+
+/*N*/ USHORT SmParser::AddError(SmParseError Type, SmNode *pNode)
+/*N*/ {
+/*N*/ SmErrorDesc *pErrDesc = new SmErrorDesc;
+/*N*/
+/*N*/ pErrDesc->Type = Type;
+/*N*/ pErrDesc->pNode = pNode;
+/*N*/ pErrDesc->Text = String(SmResId(RID_ERR_IDENT));
+/*N*/
+/*N*/ USHORT nRID;
+/*N*/ switch (Type)
+/*N*/ {
+/*N*/ case PE_UNEXPECTED_CHAR: nRID = RID_ERR_UNEXPECTEDCHARACTER; break;
+/*N*/ case PE_LGROUP_EXPECTED: nRID = RID_ERR_LGROUPEXPECTED; break;
+/*N*/ case PE_RGROUP_EXPECTED: nRID = RID_ERR_RGROUPEXPECTED; break;
+/*N*/ case PE_LBRACE_EXPECTED: nRID = RID_ERR_LBRACEEXPECTED; break;
+/*N*/ case PE_RBRACE_EXPECTED: nRID = RID_ERR_RBRACEEXPECTED; break;
+/*N*/ case PE_FUNC_EXPECTED: nRID = RID_ERR_FUNCEXPECTED; break;
+/*N*/ case PE_UNOPER_EXPECTED: nRID = RID_ERR_UNOPEREXPECTED; break;
+/*N*/ case PE_BINOPER_EXPECTED: nRID = RID_ERR_BINOPEREXPECTED; break;
+/*N*/ case PE_SYMBOL_EXPECTED: nRID = RID_ERR_SYMBOLEXPECTED; break;
+/*N*/ case PE_IDENTIFIER_EXPECTED: nRID = RID_ERR_IDENTEXPECTED; break;
+/*N*/ case PE_POUND_EXPECTED: nRID = RID_ERR_POUNDEXPECTED; break;
+/*N*/ case PE_COLOR_EXPECTED: nRID = RID_ERR_COLOREXPECTED; break;
+/*N*/ case PE_RIGHT_EXPECTED: nRID = RID_ERR_RIGHTEXPECTED; break;
+/*N*/
+/*N*/ default:
+/*N*/ nRID = RID_ERR_UNKOWN;
+/*N*/ }
+/*N*/ pErrDesc->Text += SmResId(nRID);
+/*N*/
+/*N*/ ErrDescList.Insert(pErrDesc);
+/*N*/
+/*N*/ return (USHORT) ErrDescList.GetPos(pErrDesc);
+/*N*/ }
+
+
+
+
+
+
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */