]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/math_parser.C
small cleanup, doxygen, formatting changes
[lyx.git] / src / mathed / math_parser.C
index 621e85af6832730a57310f5b8dea402b400357c3..d5de9bef843efc86c6df3830055354bcda9f8912 100644 (file)
 #include <cctype>
 
 #ifdef __GNUG__
-#pragma implementation "math_parser.h"
+#pragma implementation
 #endif
 
 #include "math_parser.h"
+#include "array.h"
+#include "math_rowst.h"
 #include "math_iter.h"
 #include "math_inset.h"
 #include "math_macro.h"
+#include "math_macrotable.h"
+#include "math_macrotemplate.h"
 #include "math_root.h"
+#include "math_matrixinset.h"
+#include "math_accentinset.h"
+#include "math_bigopinset.h"
+#include "math_funcinset.h"
+#include "math_spaceinset.h"
+#include "math_dotsinset.h"
+#include "math_fracinset.h"
+#include "math_deliminset.h"
+#include "math_decorationinset.h"
 #include "debug.h"
 #include "support/lyxlib.h"
+#include "mathed/support.h"
+#include "boost/array.hpp"
 
 using std::istream;
 using std::endl;
 
+
+extern MathMatrixInset * create_multiline(short int type, int cols);
+
+
 enum {
        FLAG_BRACE      = 1,    //  A { needed
        FLAG_BRACE_ARG  = 2,    //  Next { is argument
@@ -46,31 +65,47 @@ enum {
        FLAG_BRACK_END  = 256   // Next ] ends the parsing process
 };
 
+
+///
+union YYSTYPE {
+    ///
+    unsigned char c;
+    ///
+    char const * s;
+    ///
+    int i;
+    ///
+    latexkeys const * l;
+};
+
 static
 YYSTYPE yylval;
 
 
 static
-short mathed_env = LM_EN_INTEXT;
+MathedInsetTypes mathed_env = LM_OT_MIN;
 
 string mathed_label;
 
 
-char const * latex_mathenv[] = { 
+int const latex_mathenv_num = 12;
+char const * latex_mathenv[latex_mathenv_num] = { 
    "math", 
    "displaymath", 
    "equation", 
    "eqnarray*",
    "eqnarray",
+   "align*",
+   "align",
+   "alignat*",
+   "alignat",
+   "multline*",
+   "multline",
    "array"
 };
 
 
 
-char const * latex_mathspace[] = {
-   "!", ",", ":", ";", "quad", "qquad"
-};
-
 
 char const * latex_special_chars = "#$%&_{}";
            
@@ -93,7 +128,9 @@ enum lexcode_enum {
 };
 
 static lexcode_enum lexcode[256];  
-static char yytext[256];
+#warning Replace with string
+//static char yytext[256];
+static array<char, 256> yytext;
 static int yylineno;
 static istream * yyis;
 static bool yy_mtextmode= false;
@@ -148,10 +185,13 @@ char LexGetArg(char lf, bool accept_spaces= false)
       yyis->get(cc);
       c = cc;
       if (c > ' ') {
-        if (!lf) lf = c; else
-        if (c != lf)
+        if (!lf) 
+            lf = c;
+        else if (c != lf) {
                 lyxerr << "Math parse error: unexpected '"
                        << c << "'" << endl;
+                return '\0';
+        }
         break;
       }
    }
@@ -170,7 +210,7 @@ char LexGetArg(char lf, bool accept_spaces= false)
       if (c == lf) ++bcnt;
       if (c == rg) --bcnt;
       if ((c > ' ' || (c == ' ' && accept_spaces)) && bcnt > 0) *(p++) = c;
-   } while (bcnt > 0 && yyis->good());
+   } while (bcnt > 0 && yyis->good() && p - yytext.data() < 255);
    *p = '\0';
    return rg;
 }
@@ -242,19 +282,19 @@ int yylex(void)
                 return LM_TK_NEWLINE;
         }
         if (c == '(') {
-                yylval.i = LM_EN_INTEXT;
+                yylval.i = LM_OT_MIN;
                 return LM_TK_BEGIN;
         }
         if (c == ')') {
-                yylval.i = LM_EN_INTEXT;
+                yylval.i = LM_OT_MIN;
                 return LM_TK_END;
         }
         if (c == '[') {
-                yylval.i = LM_EN_DISPLAY;
+                yylval.i = LM_OT_PAR;
                 return LM_TK_BEGIN;
         }
         if (c == ']') {
-                yylval.i = LM_EN_DISPLAY;
+                yylval.i = LM_OT_PAR;
                 return LM_TK_END;
         }
         if (strchr(latex_special_chars, c)) {
@@ -269,7 +309,8 @@ int yylex(void)
         }
         if (lexcode[c] == LexAlpha || lexcode[c] == LexDigit) {
            char * p = &yytext[0];
-           while (lexcode[c] == LexAlpha || lexcode[c] == LexDigit) {
+           while ((lexcode[c] == LexAlpha || lexcode[c] == LexDigit)
+                  && p - yytext.data() < 255) {
               *p = c;
               yyis->get(cc);
               c = cc;
@@ -277,15 +318,16 @@ int yylex(void)
            }
            *p = '\0';
            if (yyis->good()) yyis->putback(c);
-           latexkeys * l = in_word_set (yytext, strlen(yytext));
+           latexkeys const * l = in_word_set (yytext.data(), strlen(yytext.data()));
            if (l) {
               if (l->token == LM_TK_BEGIN || l->token == LM_TK_END) { 
                  int i;
                  LexGetArg('{');
-//               for (i = 0; i < 5 && strncmp(yytext, latex_mathenv[i],
+//               for (i = 0; i < 5 && compare(yytext, latex_mathenv[i],
 //                             strlen(latex_mathenv[i])); ++i);
                  
-                 for (i = 0; i < 6 && strcmp(yytext, latex_mathenv[i]); ++i);
+                 for (i = 0; i < latex_mathenv_num
+                              && compare(yytext.data(), latex_mathenv[i]); ++i);
                  yylval.i = i;
               } else
               if (l->token == LM_TK_SPACE) 
@@ -294,7 +336,7 @@ int yylex(void)
                 yylval.l = l;
               return l->token;
            } else { 
-              yylval.s = yytext;
+              yylval.s = yytext.data();
               return LM_TK_UNDEF;
            }
         }
@@ -363,8 +405,8 @@ MathedInset * doAccent(MathedInset * p)
 }
 
 
-LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
-                           MathParInset ** mtx)
+MathedArray * mathed_parse(unsigned flags = 0, MathedArray * array = 0,
+                           MathParInset ** mtx = 0)
 {
    int t = yylex();
    int tprev = 0;
@@ -382,7 +424,7 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
     MathedRowSt * crow = (mt) ? mt->getRowSt() : 0;
 
    ++plevel;
-   if (!array) array = new LyxArrayBase;
+   if (!array) array = new MathedArray;
    MathedIter data(array);
    while (t) {
       if ((flags & FLAG_BRACE) && t != LM_TK_OPEN) {
@@ -419,17 +461,15 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
          string const name(&yytext[1]);
          
          // ugly trick to be removed soon (lyx3)
-         //char c; yyis->get(c);
-         //yyis->putback(c);
          char const c = yyis->peek();
          if (c == '[') {
              LexGetArg('[');
-             na = lyx::atoi(yytext);
+             na = lyx::atoi(yytext.data());
          }  
          macro = new MathMacroTemplate(name, na);
          flags = FLAG_BRACE|FLAG_BRACE_LAST;
          *mtx = macro;
-         macro->SetData(array);
+         macro->setData(array);
          break;
       }
     case LM_TK_SPECIAL:
@@ -519,8 +559,8 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
     case '^':
       {  
         MathParInset * p = new MathParInset(size, "", LM_OT_SCRIPT);
-        LyxArrayBase * ar = mathed_parse(FLAG_BRACE_OPT|FLAG_BRACE_LAST, 0);
-        p->SetData(ar);
+        MathedArray * ar = mathed_parse(FLAG_BRACE_OPT|FLAG_BRACE_LAST, 0);
+        p->setData(ar);
 //      lyxerr << "UP[" << p->GetStyle() << "]" << endl;
         data.Insert (p, LM_TC_UP);
         break;
@@ -528,8 +568,8 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
     case '_':
       {
         MathParInset * p = new MathParInset(size, "", LM_OT_SCRIPT);
-        LyxArrayBase * ar = mathed_parse(FLAG_BRACE_OPT|FLAG_BRACE_LAST, 0);
-        p->SetData(ar);
+        MathedArray * ar = mathed_parse(FLAG_BRACE_OPT|FLAG_BRACE_LAST, 0);
+        p->setData(ar);
         data.Insert (p, LM_TC_DOWN);
         break;
       }
@@ -626,8 +666,8 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
     case LM_TK_FRAC:
       {
         MathFracInset * fc = new MathFracInset(fractype);
-        LyxArrayBase * num = mathed_parse(FLAG_BRACE|FLAG_BRACE_LAST);
-        LyxArrayBase * den = mathed_parse(FLAG_BRACE|FLAG_BRACE_LAST);
+        MathedArray * num = mathed_parse(FLAG_BRACE|FLAG_BRACE_LAST);
+        MathedArray * den = mathed_parse(FLAG_BRACE|FLAG_BRACE_LAST);
         fc->SetData(num, den);
         data.Insert(fc, LM_TC_ACTIVE_INSET);
         break;
@@ -641,13 +681,13 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
         if (c == '[') {
             rt = new MathRootInset(size);
             rt->setArgumentIdx(0);
-            rt->SetData(mathed_parse(FLAG_BRACK_END, 0, &rt));
+            rt->setData(mathed_parse(FLAG_BRACK_END, 0, &rt));
             rt->setArgumentIdx(1);
         } else {
                 yyis->putback(c);
             rt = new MathSqrtInset(size);
         }
-        rt->SetData(mathed_parse(FLAG_BRACE|FLAG_BRACE_LAST, 0, &rt));
+        rt->setData(mathed_parse(FLAG_BRACE|FLAG_BRACE_LAST, 0, &rt));
         data.Insert(rt, LM_TC_ACTIVE_INSET);
         break;
       }
@@ -658,13 +698,13 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
         if (lfd == LM_TK_SYM || lfd == LM_TK_STR || lfd == LM_TK_BOP|| lfd == LM_TK_SPECIAL)
           lfd = (lfd == LM_TK_SYM) ? yylval.l->id: yylval.i;
 //      lyxerr << "L[" << lfd << " " << lfd << "]";
-        LyxArrayBase * a = mathed_parse(FLAG_RIGHT);
+        MathedArray * a = mathed_parse(FLAG_RIGHT);
         int rgd = yylex();
 //      lyxerr << "R[" << rgd << "]";
         if (rgd == LM_TK_SYM || rgd == LM_TK_STR || rgd == LM_TK_BOP || rgd == LM_TK_SPECIAL)
           rgd = (rgd == LM_TK_SYM) ? yylval.l->id: yylval.i;    
         MathDelimInset * dl = new MathDelimInset(lfd, rgd);
-        dl->SetData(a);
+        dl->setData(a);
         data.Insert(dl, LM_TC_ACTIVE_INSET);
 //      lyxerr << "RL[" << lfd << " " << rgd << "]";
         break;
@@ -692,7 +732,7 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
       {  
         MathDecorationInset * sq = new MathDecorationInset(yylval.l->id,
                                                            size);
-        sq->SetData(mathed_parse(FLAG_BRACE|FLAG_BRACE_LAST));
+        sq->setData(mathed_parse(FLAG_BRACE|FLAG_BRACE_LAST));
         data.Insert(sq, LM_TC_ACTIVE_INSET);
         break;
       }
@@ -734,7 +774,7 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
           else
             data.Insert(p, p->getTCode());
           for (int i = 0; p->setArgumentIdx(i); ++i)
-            p->SetData(mathed_parse(FLAG_BRACE|FLAG_BRACE_LAST));
+            p->setData(mathed_parse(FLAG_BRACE|FLAG_BRACE_LAST));
        }
        else {
           MathedInset * q = new MathFuncInset(yylval.s, LM_OT_UNDEF);
@@ -748,35 +788,35 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
       }
     case LM_TK_END:
       {
-         if (mathed_env != yylval.i && yylval.i!= LM_EN_ARRAY)
+         if (mathed_env != yylval.i && yylval.i != LM_OT_MATRIX)
           mathPrintError("Unmatched environment");
         // debug info [made that conditional -JMarc]
         if (lyxerr.debugging(Debug::MATHED))
                 lyxerr << "[" << yylval.i << "]" << endl;
         --plevel;
         if (mt) { // && (flags & FLAG_END)) {
-           mt->SetData(array);
+           mt->setData(array);
            array = 0;
         }
         return array;
       }
     case LM_TK_BEGIN:
       {
-        if (yylval.i == LM_EN_ARRAY) {
+        if (yylval.i == LM_OT_MATRIX) {
            char ar[120], ar2[8];
            ar[0] = ar2[0] = '\0'; 
             char rg = LexGetArg(0);
            if (rg == ']') {
-              strcpy(ar2, yytext);
+              strcpy(ar2, yytext.data());
               rg = LexGetArg('{');
            }
-           strcpy(ar, yytext);
+           strcpy(ar, yytext.data());
            int const nc = parse_align(ar, ar2);
            MathParInset * mm = new MathMatrixInset(nc, 0);
            mm->SetAlign(ar2[0], ar);
                    data.Insert(mm, LM_TC_ACTIVE_INSET);
             mathed_parse(FLAG_END, mm->GetData(), &mm);
-        } else if (yylval.i >= LM_EN_INTEXT && yylval.i<= LM_EN_EQNARRAY) {
+        } else if (is_eqn_type(yylval.i)) {
             if (plevel!= 0) {
                 mathPrintError("Misplaced environment");
                 break;
@@ -786,12 +826,25 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
                 panic = true;
             }
             
-            mathed_env = yylval.i;
-            if (mathed_env>= LM_EN_DISPLAY) {
+            mathed_env = static_cast<MathedInsetTypes>(yylval.i);
+            if (mathed_env != LM_OT_MIN) {
                 size = LM_ST_DISPLAY;
-                if (mathed_env>LM_EN_EQUATION) {
-                    mt = new MathMatrixInset(3, -1);
-                    mt->SetAlign(' ', "rcl");
+                if (is_multiline(mathed_env)) {
+                    int cols = 1;
+                    if (is_multicolumn(mathed_env)) {
+                        if (mathed_env != LM_OT_ALIGNAT &&
+                            mathed_env != LM_OT_ALIGNATN &&
+                            yyis->good()) {
+                            char c;
+                            yyis->get(c);
+                            if (c != '%')
+                                    lyxerr << "Math parse error: unexpected '"
+                                           << c << "'" << endl;
+                        }
+                        LexGetArg('{');
+                        cols = strToInt(string(yytext.data()));
+                    }
+                    mt = create_multiline(mathed_env, cols);
                     if (mtx) *mtx = mt;
                     flags |= FLAG_END;
 //                  data.Insert(' ', LM_TC_TAB);
@@ -802,14 +855,14 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
                 mt->SetType(mathed_env);
                 crow = mt->getRowSt();
             }
-                              
+
 #ifdef DEBUG
             lyxerr << "MATH BEGIN[" << mathed_env << "]" << endl;
 #endif
         } else {
 //          lyxerr << "MATHCRO[" << yytext << "]";
             MathMacro * p = 
-              MathMacroTable::mathMTable.getMacro(yytext);
+              MathMacroTable::mathMTable.getMacro(yytext.data());
             if (p) {
                 data.Insert(p, p->getTCode());
                 p->setArgumentIdx(0);
@@ -842,14 +895,14 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
          if (rg != '}') {
             mathPrintError("Expected '{'");
              // debug info
-            lyxerr << "[" << yytext << "]" << endl;
+            lyxerr << "[" << yytext.data() << "]" << endl;
              panic = true;
             break;
          } 
          if (crow) {
-             crow->setLabel(yytext);
+             crow->setLabel(yytext.data());
          } else {
-                 mathed_label = yytext;
+                 mathed_label = yytext.data();
          }
 #ifdef DEBUG
          lyxerr << "Label[" << mathed_label << "]" << endl;
@@ -859,7 +912,7 @@ LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * array,
      default:
        mathPrintError("Unrecognized token");
        // debug info
-       lyxerr << "[" << t << " " << yytext << "]" << endl;
+       lyxerr << "[" << t << " " << yytext.data() << "]" << endl;
        break;
     }
     tprev = t;