]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/DEVEL/mathml_editor/src/LPushLexer.cc
ocaml 3.09 transition
[helm.git] / helm / DEVEL / mathml_editor / src / LPushLexer.cc
index a41b016dda89e79fb61fc4236328606023b20138..a16801bf0d03f6e533be2fce52d5ffd33823173a 100644 (file)
@@ -1,4 +1,33 @@
+/* This file is part of EdiTeX, an editor of mathematical
+ * expressions based on TeX syntax.
+ * 
+ * Copyright (C) 2002-2003 Luca Padovani <lpadovan@cs.unibo.it>,
+ *                    2003 Paolo Marinelli <pmarinel@cs.unibo.it>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, please visit the project's home page
+ * http://helm.cs.unibo.it/editex/
+ * or send an email to <lpadovan@cs.unibo.it>
+ */
 
+#include <string>
+#include <cctype>
+#include <cassert>
+
+#include "ALogger.hh"
 #include "TToken.hh"
 #include "LPushLexer.hh"
 #include "APushParser.hh"
@@ -13,6 +42,8 @@ LPushLexer::reset()
 {
   buffer.erase();
   state = ACCEPT;
+
+  displayCursor();
 }
 
 void
@@ -34,7 +65,7 @@ LPushLexer::transaction(char ch, State newState)
     case '\r': parser.push(TToken(TToken::EOL, ch)); break;
     case '^': parser.push(TToken(TToken::SUPERSCRIPT)); break;
     case '_': parser.push(TToken(TToken::SUBSCRIPT)); break;
-    case '\t':
+    case '\t': parser.push(TToken(TToken::IGNORABLE_SPACE, ch)); break;
     case ' ': parser.push(TToken(TToken::SPACE, ch)); break;
     case '~': parser.push(TToken(TToken::ACTIVE, ch)); break;
     case '%': parser.push(TToken(TToken::COMMENT)); break;     
@@ -57,11 +88,6 @@ LPushLexer::push(char ch)
          buffer.push_back(ch);
          state = IDENTIFIER;
        }
-      else if (isspace(ch))
-        {
-         // we translate this space in a macro.
-         parser.push(TToken(TToken::CONTROL, "space"));
-       }
       else if (isdigit(ch))
         {
          buffer.push_back(ch);
@@ -110,15 +136,12 @@ LPushLexer::push(char ch)
          state = ACCEPT;
        }
       else if (isspace(ch))
-        {
-         parser.push(TToken(TToken::CONTROL, buffer));
-         buffer.erase();
-         /*
-          * we comment this line, because a space after a macro 
-          * is useful to exit from a macro
-         //parser.push(TToken(TToken::CONTROL, ";"));
-         */
-         state = ACCEPT;
+          {
+           // we don't call transaction, because a white space is useful to exit from the macro,
+           // without "side effect". It's the TeX syntax.
+           parser.push(TToken(TToken::CONTROL, buffer));
+           buffer.erase();
+           state = ACCEPT;
        }
       else if (isdigit(ch))
         {
@@ -153,41 +176,51 @@ LPushLexer::push(char ch)
         {
          buffer.push_back(ch);
        }
-      else if (isspace(ch))
+      else if (ch == '\\') state = ESCAPED_CHARACTER;
+      else if (ch == '#')
         {
          parser.push(TToken(TToken::LETTER, buffer));
          buffer.erase();
-         parser.push(TToken(TToken::CONTROL, "space"));
-         state = ACCEPT;
+         state = PARAMETER;
        }
-      else if (ch == '\\')
+      else
         {
          parser.push(TToken(TToken::LETTER, buffer));
          buffer.erase();
-         state = ESCAPE;
+         transaction(ch, ACCEPT);
        }
-      else if (ch == '#')
+      break;
+    case ESCAPED_CHARACTER:
+      if ((ch == '-') || (ch == '_') || (ch == '/'))
         {
+         buffer.push_back(ch);
+         state = IDENTIFIER;
+       }
+      else if (isalpha(ch))
+       {
          parser.push(TToken(TToken::LETTER, buffer));
          buffer.erase();
-         state = PARAMETER;
+         buffer.push_back(ch);
+         state = MACRO;
        }
-      else
+      else if (ch == -1) error();
+      else if (isdigit(ch))
         {
          parser.push(TToken(TToken::LETTER, buffer));
          buffer.erase();
-         transaction(ch, ACCEPT);
+         buffer.push_back(ch);
+         state = NUMBER;
        }
-      break;
-    case NUMBER:
-      if (isdigit(ch)) buffer.push_back(ch);
-      else if (isspace(ch))
-        {
-         parser.push(TToken(TToken::DIGIT, buffer));
+      else
+       {
+         parser.push(TToken(TToken::LETTER, buffer));
          buffer.erase();
-         parser.push(TToken(TToken::CONTROL, "space"));
+         parser.push(TToken(TToken::CONTROL, ch));
          state = ACCEPT;
        }
+      break;
+    case NUMBER:
+      if (isdigit(ch)) buffer.push_back(ch);
       else if (isalpha(ch))
         {
          parser.push(TToken(TToken::DIGIT, buffer));
@@ -225,15 +258,8 @@ LPushLexer::push(char ch)
       break;
     }
 
-  switch (state)
-    {
-    case ESCAPE: parser.setCursorHint("\\"); break;
-    case MACRO: parser.setCursorHint("\\" + buffer); break;
-    case PARAMETER: parser.setCursorHint("#"); break;
-    case IDENTIFIER: parser.setCursorHint(buffer); break;
-    case NUMBER: parser.setCursorHint(buffer); break;
-    default: parser.setCursorHint(""); break;
-    }
+  displayCursor();
+
 }
 
 void
@@ -244,10 +270,40 @@ LPushLexer::drop(bool alt)
   switch (state)
     {
     case ACCEPT:
-      restore = parser.drop(alt);
-      if (restore.length() > 0 && restore[0] == '\\')
+      {
+        restore = parser.drop(alt);
+        long bs_pos = restore.find('\\');
+        if ((restore.length() > 0) && (bs_pos != std::string::npos))
+          {
+           // in this case we have to control the blackslash's position
+           if (bs_pos == 0)
+             {
+               //logger.debug(restore);
+               buffer = std::string(restore, 1, restore.length() - 1);
+               state = (buffer.length() > 0) ? MACRO : ESCAPE;
+             }
+           else
+             {
+               assert(bs_pos == restore.length() - 1);
+               buffer = std::string(restore, 0, bs_pos);
+               state = ESCAPED_CHARACTER;
+             }
+         }
+        else if (restore.length() > 0 && isdigit(restore[0]))
+          {
+           buffer = restore;
+           state = NUMBER;
+         }
+        else if (restore.length() > 0 && isalpha(restore[0]))
+          {
+           buffer = restore;
+           state = IDENTIFIER;
+         }
+      }
+      break;
+/*      if (restore.length() > 0 && restore[0] == '\\')
        {
-         cout << restore << endl;
+         logger.debug(restore);
          buffer = std::string(restore, 1, restore.length() - 1);
          state = (buffer.length() > 0) ? MACRO : ESCAPE;
        }
@@ -261,6 +317,9 @@ LPushLexer::drop(bool alt)
          buffer = restore;
          state = IDENTIFIER;
        }
+      break;*/
+    case ESCAPED_CHARACTER:
+      state = IDENTIFIER;
       break;
     case ESCAPE:
       state = ACCEPT;
@@ -271,9 +330,19 @@ LPushLexer::drop(bool alt)
       if (buffer.length() == 0) state = ESCAPE;
       break;
     case IDENTIFIER:
-      if (alt) buffer.erase(); 
-      else buffer.erase(buffer.length() - 1, 1);
-      if (buffer.length() == 0) state = ACCEPT;
+      switch (buffer[buffer.length() - 1])
+       {
+       case '-':
+       case '_':
+         buffer.erase(buffer.length() - 1, 1);
+         if (alt) state = ESCAPED_CHARACTER;
+         break;
+       default:
+          if (alt) buffer.erase(); 
+          else buffer.erase(buffer.length() - 1, 1);
+          if (buffer.length() == 0) state = ACCEPT;
+          break;
+       }
       break;
     case NUMBER:
       if (alt) buffer.erase();
@@ -287,9 +356,17 @@ LPushLexer::drop(bool alt)
       break;
     }
 
+  displayCursor();
+
+}
+
+void
+LPushLexer::displayCursor()
+{
   switch (state)
     {
     case ESCAPE: parser.setCursorHint("\\"); break;
+    case ESCAPED_CHARACTER: parser.setCursorHint(buffer + "\\"); break;
     case MACRO: parser.setCursorHint("\\" + buffer); break;
     case PARAMETER: parser.setCursorHint("#"); break;
     case IDENTIFIER: parser.setCursorHint(buffer); break;