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