3 #include "LPushLexer.hh"
4 #include "APushParser.hh"
6 LPushLexer::LPushLexer(ALogger& l, APushParser& p) : APushLexer(l, p)
25 LPushLexer::transaction(char ch, State newState)
29 case '{': parser.push(TToken(TToken::BEGIN)); break;
30 case '}': parser.push(TToken(TToken::END)); break;
31 case '$': parser.push(TToken(TToken::SHIFT)); break;
32 case '&': parser.push(TToken(TToken::ALIGN)); break;
34 case '\r': parser.push(TToken(TToken::EOL, ch)); break;
35 case '^': parser.push(TToken(TToken::SUPERSCRIPT)); break;
36 case '_': parser.push(TToken(TToken::SUBSCRIPT)); break;
38 case ' ': parser.push(TToken(TToken::SPACE, ch)); break;
39 case '~': parser.push(TToken(TToken::ACTIVE, ch)); break;
40 case '%': parser.push(TToken(TToken::COMMENT)); break;
42 if (isalpha(ch)) parser.push(TToken(TToken::LETTER, ch));
43 else if (isdigit(ch)) parser.push(TToken(TToken::DIGIT, ch));
44 else parser.push(TToken(TToken::OTHER, ch));
51 LPushLexer::push(char ch)
56 if (ch == '\\') state = ESCAPE;
57 else if (ch == '#') state = PARAMETER;
62 state = LONG_IDENTIFIER;
64 else transaction(ch, ACCEPT);
72 else if (ch == -1) error();
75 parser.push(TToken(TToken::CONTROL, ch));
82 parser.push(TToken(TToken::CONTROL, buffer));
88 parser.push(TToken(TToken::CONTROL, buffer));
96 parser.push(TToken(TToken::CONTROL, buffer));
102 parser.push(TToken(TToken::CONTROL, buffer));
104 if (isspace(ch)) state = IGNORE_SPACE;
105 else transaction(ch, ACCEPT);
109 if (ch == '\\') state = ESCAPE;
110 else if (ch == '#') state = PARAMETER;
111 else if (isspace(ch)) ;
112 else if (ch == -1) state = ACCEPT;
113 else if (isalpha(ch))
115 buffer.push_back(ch);
116 state = LONG_IDENTIFIER;
118 else transaction(ch, ACCEPT);
121 if (ch == -1) error();
124 parser.push(TToken(TToken::PARAMETER, ch));
128 case LONG_IDENTIFIER:
131 parser.push(TToken(TToken::LETTER, buffer));
135 else if (isalpha(ch) || isdigit(ch))
137 buffer.push_back(ch);
139 else if (isspace(ch))
141 parser.push(TToken(TToken::LETTER, buffer));
143 // the parser ignores spaces. But in this case, the space
144 // is a significant. So, we transform this space in the MACRO
145 // \; which will not be ignored.
146 // This is not a good solution. Having a special token, that will be
147 // interpreted as "function application" is a better one.
150 parser.push(TToken(TToken::CONTROL, buffer));
152 state = IGNORE_SPACE;
156 parser.push(TToken(TToken::LETTER, buffer));
162 parser.push(TToken(TToken::LETTER, buffer));
164 transaction(ch, ACCEPT);
174 case ESCAPE: parser.setCursorHint("\\"); break;
175 case MACRO: parser.setCursorHint("\\" + buffer); break;
176 case PARAMETER: parser.setCursorHint("#"); break;
177 case LONG_IDENTIFIER: parser.setCursorHint(buffer); break;
178 default: parser.setCursorHint(""); break;
183 LPushLexer::drop(bool alt)
185 std::string restore = "";
191 restore = parser.drop();
192 if (restore.length() > 0 && restore[0] == '\\')
194 buffer = std::string(restore, 1, restore.length() - 1);
195 state = (buffer.length() > 0) ? MACRO : ESCAPE;
202 if (alt) buffer.erase();
203 else buffer.erase(buffer.length() - 1, 1);
204 if (buffer.length() == 0) state = ESCAPE;
206 case LONG_IDENTIFIER:
207 buffer.erase(buffer.length() - 1, 1);
208 if (buffer.length() == 0) state = ACCEPT;
218 case ESCAPE: parser.setCursorHint("\\"); break;
219 case MACRO: parser.setCursorHint("\\" + buffer); break;
220 case PARAMETER: parser.setCursorHint("#"); break;
221 default: parser.setCursorHint(""); break;
226 LPushLexer::error() const