+
+#include "TLexerPush.hh"
+
+TLexerPush::TLexerPush()
+{
+ state = ACCEPT;
+}
+
+TToken
+TLexerPush::pop()
+{
+ if (tokens.empty()) throw EmptyBuffer();
+ else
+ {
+ TToken res = tokens.front();
+ tokens.pop_front();
+ if (tokens.size() == 1 && state == CONTROL) state = ACCEPT;
+ return res;
+ }
+}
+
+TToken
+TLexerPush::front() const
+{
+ if (tokens.empty()) throw EmptyBuffer();
+ else return tokens.front();
+}
+
+bool
+TLexerPush::empty() const
+{
+ return tokens.empty();
+}
+
+bool
+TLexerPush::pending() const
+{
+ return state == ESCAPE;
+}
+
+bool
+TLexerPush::ambiguous() const
+{
+ return tokens.size() == 1 && state == CONTROL;
+}
+
+void
+TLexerPush::push(TChar ch)
+{
+ switch (state)
+ {
+ case ACCEPT:
+ if (ch == '\\') state = ESCAPE;
+ else tokens.push_back(TToken(ch));
+ break;
+ case ESCAPE:
+ tokens.push_back(TToken(TToken::CONTROL, std::string(1, ch)));
+ if (isUnicodeAlpha(ch)) state = CONTROL;
+ else state = ACCEPT;
+ break;
+ case CONTROL:
+ if (ch == '\\') state = ESCAPE;
+ else if (isUnicodeAlpha(ch))
+ {
+ assert(!tokens.empty());
+ TToken& tok = tokens.back();
+ tok.value.push_back(ch);
+ }
+ else if (isUnicodeSpace(ch)) state = IGNORE_SPACE;
+ else
+ {
+ tokens.push_back(TToken(ch));
+ state = ACCEPT;
+ }
+ break;
+ case IGNORE_SPACE:
+ if (ch == '\\') state = ESCAPE;
+ else if (isUnicodeSpace(ch)) ;
+ else tokens.push_back(TToken(ch));
+ break;
+ }
+}