X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2FDEVEL%2Fmathml_editor%2Fsrc%2FLPushLexer.cc;fp=helm%2FDEVEL%2Fmathml_editor%2Fsrc%2FLPushLexer.cc;h=6ee43b3e9fde2d88b74612465128d9e4736e3e85;hb=281107dfb0a5531ac13c9e183f39c05c65813e86;hp=0000000000000000000000000000000000000000;hpb=387aeebf96181c051b7f527a0901b173cfcdf194;p=helm.git diff --git a/helm/DEVEL/mathml_editor/src/LPushLexer.cc b/helm/DEVEL/mathml_editor/src/LPushLexer.cc new file mode 100644 index 000000000..6ee43b3e9 --- /dev/null +++ b/helm/DEVEL/mathml_editor/src/LPushLexer.cc @@ -0,0 +1,229 @@ + +#include "TToken.hh" +#include "LPushLexer.hh" +#include "APushParser.hh" + +LPushLexer::LPushLexer(ALogger& l, APushParser& p) : APushLexer(l, p) +{ + state = ACCEPT; +} + +void +LPushLexer::reset() +{ + buffer.erase(); + state = ACCEPT; +} + +void +LPushLexer::flush() +{ + push(-1); +} + +void +LPushLexer::transaction(char ch, State newState) +{ + switch (ch) + { + case '{': parser.push(TToken(TToken::BEGIN)); break; + case '}': parser.push(TToken(TToken::END)); break; + case '$': parser.push(TToken(TToken::SHIFT)); break; + case '&': parser.push(TToken(TToken::ALIGN)); break; + case '\n': + case '\r': parser.push(TToken(TToken::EOL, ch)); break; + case '^': parser.push(TToken(TToken::SUPERSCRIPT)); break; + case '_': parser.push(TToken(TToken::SUBSCRIPT)); break; + case '\t': + case ' ': parser.push(TToken(TToken::SPACE, ch)); break; + case '~': parser.push(TToken(TToken::ACTIVE, ch)); break; + case '%': parser.push(TToken(TToken::COMMENT)); break; + default: + if (isalpha(ch)) parser.push(TToken(TToken::LETTER, ch)); + else if (isdigit(ch)) parser.push(TToken(TToken::DIGIT, ch)); + else parser.push(TToken(TToken::OTHER, ch)); + break; + } + state = newState; +} + +void +LPushLexer::push(char ch) +{ + switch (state) + { + case ACCEPT: + if (ch == '\\') state = ESCAPE; + else if (ch == '#') state = PARAMETER; + else if (ch == -1) ; + else if (isalpha(ch)) + { + buffer.push_back(ch); + state = LONG_IDENTIFIER; + } + else transaction(ch, ACCEPT); + break; + case ESCAPE: + if (isalpha(ch)) + { + buffer.push_back(ch); + state = MACRO; + } + else if (ch == -1) error(); + else + { + parser.push(TToken(TToken::CONTROL, ch)); + state = ACCEPT; + } + break; + case MACRO: + if (ch == '\\') + { + parser.push(TToken(TToken::CONTROL, buffer)); + buffer.erase(); + state = ESCAPE; + } + else if (ch == '#') + { + parser.push(TToken(TToken::CONTROL, buffer)); + buffer.erase(); + state = PARAMETER; + } + else if (isalpha(ch)) + buffer.push_back(ch); + else if (ch == -1) + { + parser.push(TToken(TToken::CONTROL, buffer)); + buffer.erase(); + state = ACCEPT; + } + else + { + parser.push(TToken(TToken::CONTROL, buffer)); + buffer.erase(); + if (isspace(ch)) state = IGNORE_SPACE; + else transaction(ch, ACCEPT); + } + break; + case IGNORE_SPACE: + if (ch == '\\') state = ESCAPE; + else if (ch == '#') state = PARAMETER; + else if (isspace(ch)) ; + else if (ch == -1) state = ACCEPT; + else if (isalpha(ch)) + { + buffer.push_back(ch); + state = LONG_IDENTIFIER; + } + else transaction(ch, ACCEPT); + break; + case PARAMETER: + if (ch == -1) error(); + else + { + parser.push(TToken(TToken::PARAMETER, ch)); + state = ACCEPT; + } + break; + case LONG_IDENTIFIER: + if (ch == -1) + { + parser.push(TToken(TToken::LETTER, buffer)); + buffer.erase(); + state = ACCEPT; + } + else if (isalpha(ch) || isdigit(ch)) + { + buffer.push_back(ch); + } + else if (isspace(ch)) + { + parser.push(TToken(TToken::LETTER, buffer)); + + // the parser ignores spaces. But in this case, the space + // is a significant. So, we transform this space in the MACRO + // \; which will not be ignored. + // This is not a good solution. Having a special token, that will be + // interpreted as "function application" is a better one. + buffer.erase(); + buffer = ";"; + parser.push(TToken(TToken::CONTROL, buffer)); + buffer.erase(); + state = IGNORE_SPACE; + } + else if (ch == '\\') + { + parser.push(TToken(TToken::LETTER, buffer)); + buffer.erase(); + state = ESCAPE; + } + else + { + parser.push(TToken(TToken::LETTER, buffer)); + buffer.erase(); + transaction(ch, ACCEPT); + } + break; + default: + assert(0); + break; + } + + switch (state) + { + case ESCAPE: parser.setCursorHint("\\"); break; + case MACRO: parser.setCursorHint("\\" + buffer); break; + case PARAMETER: parser.setCursorHint("#"); break; + case LONG_IDENTIFIER: parser.setCursorHint(buffer); break; + default: parser.setCursorHint(""); break; + } +} + +void +LPushLexer::drop(bool alt) +{ + std::string restore = ""; + + switch (state) + { + case ACCEPT: + case IGNORE_SPACE: + restore = parser.drop(); + if (restore.length() > 0 && restore[0] == '\\') + { + buffer = std::string(restore, 1, restore.length() - 1); + state = (buffer.length() > 0) ? MACRO : ESCAPE; + } + break; + case ESCAPE: + state = ACCEPT; + break; + case MACRO: + if (alt) buffer.erase(); + else buffer.erase(buffer.length() - 1, 1); + if (buffer.length() == 0) state = ESCAPE; + break; + case LONG_IDENTIFIER: + buffer.erase(buffer.length() - 1, 1); + if (buffer.length() == 0) state = ACCEPT; + break; + case PARAMETER: + default: + assert(0); + break; + } + + switch (state) + { + case ESCAPE: parser.setCursorHint("\\"); break; + case MACRO: parser.setCursorHint("\\" + buffer); break; + case PARAMETER: parser.setCursorHint("#"); break; + default: parser.setCursorHint(""); break; + } +} + +bool +LPushLexer::error() const +{ + return false; +}