]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/mathml_editor/src/TPushLexer.cc
C++ 3.2 aware changes
[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
29 #include "TToken.hh"
30 #include "TPushLexer.hh"
31 #include "APushParser.hh"
32
33 TPushLexer::TPushLexer(ALogger& l, APushParser& p) : APushLexer(l, p)
34 {
35   state = ACCEPT;
36 }
37
38 void
39 TPushLexer::reset()
40 {
41   buffer.erase();
42   state = ACCEPT;
43 }
44
45 void
46 TPushLexer::flush()
47 {
48   push(-1);
49 }
50
51 void
52 TPushLexer::transaction(char ch, State newState)
53 {
54   switch (ch)
55     {
56     case '{': parser.push(TToken(TToken::BEGIN)); break;
57     case '}': parser.push(TToken(TToken::END)); break;
58     case '$': parser.push(TToken(TToken::SHIFT)); break;
59     case '&': parser.push(TToken(TToken::ALIGN)); break;
60     case '\n':
61     case '\r': parser.push(TToken(TToken::EOL, ch)); break;
62     case '^': parser.push(TToken(TToken::SUPERSCRIPT)); break;
63     case '_': parser.push(TToken(TToken::SUBSCRIPT)); break;
64     case '\t':
65     case ' ': parser.push(TToken(TToken::IGNORABLE_SPACE, ch)); break;
66     case '~': parser.push(TToken(TToken::ACTIVE, ch)); break;
67     case '%': parser.push(TToken(TToken::COMMENT)); break;     
68     default:
69       if (isalpha(ch)) parser.push(TToken(TToken::LETTER, ch));
70       else if (isdigit(ch)) parser.push(TToken(TToken::DIGIT, ch));
71       else parser.push(TToken(TToken::OTHER, ch));
72       break;
73     }
74   state = newState;
75 }
76
77 void
78 TPushLexer::push(char ch)
79 {
80   switch (state)
81     {
82     case ACCEPT:
83       if (ch == '\\') state = ESCAPE;
84       else if (ch == '#') state = PARAMETER;
85       else if (ch == -1) ;
86       else transaction(ch, ACCEPT);
87       break;
88     case ESCAPE:
89       if (isalpha(ch))
90         {
91           buffer.push_back(ch);
92           state = MACRO;
93         }
94       else if (ch == -1) error();
95       else
96         {
97           parser.push(TToken(TToken::CONTROL, ch));
98           state = ACCEPT;
99         }
100       break;
101     case MACRO:
102       if (ch == '\\')
103         {
104           parser.push(TToken(TToken::CONTROL, buffer));
105           buffer.erase();
106           state = ESCAPE;
107         }
108       else if (ch == '#')
109         {
110           parser.push(TToken(TToken::CONTROL, buffer));
111           buffer.erase();
112           state = PARAMETER;
113         }
114       else if (isalpha(ch))
115         buffer.push_back(ch);
116       else if (ch == -1)
117         {
118           parser.push(TToken(TToken::CONTROL, buffer));
119           buffer.erase();
120           state = ACCEPT;
121         }
122       else
123         {
124           parser.push(TToken(TToken::CONTROL, buffer));
125           buffer.erase();
126           if (isspace(ch)) state = IGNORE_SPACE;
127           else transaction(ch, ACCEPT);
128         }
129       break;
130     case IGNORE_SPACE:
131       if (ch == '\\') state = ESCAPE;
132       else if (ch == '#') state = PARAMETER;
133       else if (isspace(ch)) ;
134       else if (ch == -1) state = ACCEPT;
135       else transaction(ch, ACCEPT);
136       break;
137     case PARAMETER:
138       if (ch == -1) error();
139       else
140         {
141           parser.push(TToken(TToken::PARAMETER, ch));
142           state = ACCEPT;
143         }
144       break;
145     default:
146       assert(0);
147       break;
148     }
149
150   displayCursor();
151
152 }
153
154 void
155 TPushLexer::drop(bool alt)
156 {
157   std::string restore = "";
158
159   switch (state)
160     {
161     case ACCEPT:
162     case IGNORE_SPACE:
163       restore = parser.drop(alt);
164       if (restore.length() > 0 && restore[0] == '\\')
165         {
166           buffer = std::string(restore, 1, restore.length() - 1);
167           state = (buffer.length() > 0) ? MACRO : ESCAPE;
168         }
169       break;
170     case ESCAPE:
171       state = ACCEPT;
172       break;
173     case MACRO:
174       if (alt) buffer.erase();
175       else buffer.erase(buffer.length() - 1, 1);
176       if (buffer.length() == 0) state = ESCAPE;
177       break;
178     case PARAMETER:
179     default:
180       assert(0);
181       break;
182     }
183
184   displayCursor();
185
186 }
187
188 void
189 TPushLexer::displayCursor()
190 {
191   switch (state)
192     {
193     case ESCAPE: parser.setCursorHint("\\"); break;
194     case MACRO: parser.setCursorHint("\\" + buffer); break;
195     case PARAMETER: parser.setCursorHint("#"); break;
196     default: parser.setCursorHint(""); break;
197     }
198 }
199
200 bool
201 TPushLexer::error() const
202 {
203   return false;
204 }