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