]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/mathml_editor/src/TPushLexer.cc
ocaml 3.09 transition
[helm.git] / helm / DEVEL / mathml_editor / src / TPushLexer.cc
1 /* This file is part of EdiTeX, an editor of mathematical
2  * expressions based on TeX syntax.
3  * 
4  * Copyright (C) 2002-2003 Luca Padovani <lpadovan@cs.unibo.it>,
5  *                    2003 Paolo Marinelli <pmarinel@cs.unibo.it>.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * For more information, please visit the project's home page
22  * http://helm.cs.unibo.it/editex/
23  * or send an email to <lpadovan@cs.unibo.it>
24  */
25
26 #include <string>
27 #include <cctype>
28 #include <cassert>
29
30 #include "TToken.hh"
31 #include "TPushLexer.hh"
32 #include "APushParser.hh"
33
34 TPushLexer::TPushLexer(ALogger& l, APushParser& p) : APushLexer(l, p)
35 {
36   state = ACCEPT;
37 }
38
39 void
40 TPushLexer::reset()
41 {
42   buffer.erase();
43   state = ACCEPT;
44
45   displayCursor();
46 }
47
48 void
49 TPushLexer::flush()
50 {
51   push(-1);
52 }
53
54 void
55 TPushLexer::transaction(char ch, State newState)
56 {
57   switch (ch)
58     {
59     case '{': parser.push(TToken(TToken::BEGIN)); break;
60     case '}': parser.push(TToken(TToken::END)); break;
61     case '$': parser.push(TToken(TToken::SHIFT)); break;
62     case '&': parser.push(TToken(TToken::ALIGN)); break;
63     case '\n':
64     case '\r': parser.push(TToken(TToken::EOL, ch)); break;
65     case '^': parser.push(TToken(TToken::SUPERSCRIPT)); break;
66     case '_': parser.push(TToken(TToken::SUBSCRIPT)); break;
67     case '\t':
68     case ' ': parser.push(TToken(TToken::IGNORABLE_SPACE, ch)); break;
69     case '~': parser.push(TToken(TToken::ACTIVE, ch)); break;
70     case '%': parser.push(TToken(TToken::COMMENT)); break;     
71     default:
72       if (isalpha(ch)) parser.push(TToken(TToken::LETTER, ch));
73       else if (isdigit(ch)) parser.push(TToken(TToken::DIGIT, ch));
74       else parser.push(TToken(TToken::OTHER, ch));
75       break;
76     }
77   state = newState;
78 }
79
80 void
81 TPushLexer::push(char ch)
82 {
83   switch (state)
84     {
85     case ACCEPT:
86       if (ch == '\\') state = ESCAPE;
87       else if (ch == '#') state = PARAMETER;
88       else if (ch == -1) ;
89       else transaction(ch, ACCEPT);
90       break;
91     case ESCAPE:
92       if (isalpha(ch))
93         {
94           buffer.push_back(ch);
95           state = MACRO;
96         }
97       else if (ch == -1) error();
98       else
99         {
100           parser.push(TToken(TToken::CONTROL, ch));
101           state = ACCEPT;
102         }
103       break;
104     case MACRO:
105       if (ch == '\\')
106         {
107           parser.push(TToken(TToken::CONTROL, buffer));
108           buffer.erase();
109           state = ESCAPE;
110         }
111       else if (ch == '#')
112         {
113           parser.push(TToken(TToken::CONTROL, buffer));
114           buffer.erase();
115           state = PARAMETER;
116         }
117       else if (isalpha(ch))
118         buffer.push_back(ch);
119       else if (ch == -1)
120         {
121           parser.push(TToken(TToken::CONTROL, buffer));
122           buffer.erase();
123           state = ACCEPT;
124         }
125       else
126         {
127           parser.push(TToken(TToken::CONTROL, buffer));
128           buffer.erase();
129           if (isspace(ch)) state = IGNORE_SPACE;
130           else transaction(ch, ACCEPT);
131         }
132       break;
133     case IGNORE_SPACE:
134       if (ch == '\\') state = ESCAPE;
135       else if (ch == '#') state = PARAMETER;
136       else if (isspace(ch)) ;
137       else if (ch == -1) state = ACCEPT;
138       else transaction(ch, ACCEPT);
139       break;
140     case PARAMETER:
141       if (ch == -1) error();
142       else
143         {
144           parser.push(TToken(TToken::PARAMETER, ch));
145           state = ACCEPT;
146         }
147       break;
148     default:
149       assert(0);
150       break;
151     }
152
153   displayCursor();
154
155 }
156
157 void
158 TPushLexer::drop(bool alt)
159 {
160   std::string restore = "";
161
162   switch (state)
163     {
164     case ACCEPT:
165     case IGNORE_SPACE:
166       restore = parser.drop(alt);
167       if (restore.length() > 0 && restore[0] == '\\')
168         {
169           buffer = std::string(restore, 1, restore.length() - 1);
170           state = (buffer.length() > 0) ? MACRO : ESCAPE;
171         }
172       break;
173     case ESCAPE:
174       state = ACCEPT;
175       break;
176     case MACRO:
177       if (alt) buffer.erase();
178       else buffer.erase(buffer.length() - 1, 1);
179       if (buffer.length() == 0) state = ESCAPE;
180       break;
181     case PARAMETER:
182     default:
183       assert(0);
184       break;
185     }
186
187   displayCursor();
188
189 }
190
191 void
192 TPushLexer::displayCursor()
193 {
194   switch (state)
195     {
196     case ESCAPE: parser.setCursorHint("\\"); break;
197     case MACRO: parser.setCursorHint("\\" + buffer); break;
198     case PARAMETER: parser.setCursorHint("#"); break;
199     default: parser.setCursorHint(""); break;
200     }
201 }
202
203 bool
204 TPushLexer::error() const
205 {
206   return false;
207 }