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;
+ default: parser.push(TToken(TToken::OTHER, ch)); break;
}
state = newState;
}
else if (isalpha(ch))
{
buffer.push_back(ch);
- state = LONG_IDENTIFIER;
+ state = IDENTIFIER;
+ }
+ else if (isspace(ch))
+ {
+ // we translate this space in a macro.
+ parser.push(TToken(TToken::CONTROL, "space"));
+ }
+ else if (isdigit(ch))
+ {
+ buffer.push_back(ch);
+ state = NUMBER;
}
else transaction(ch, ACCEPT);
break;
state = MACRO;
}
else if (ch == -1) error();
+ else if (isdigit(ch))
+ {
+ // in this case, the previous '\' is ignored
+ buffer.push_back(ch);
+ state = NUMBER;
+ }
else
{
parser.push(TToken(TToken::CONTROL, ch));
buffer.erase();
state = ACCEPT;
}
- else
- {
+ else if (isspace(ch))
+ {
parser.push(TToken(TToken::CONTROL, buffer));
buffer.erase();
- if (isspace(ch)) state = IGNORE_SPACE;
- else transaction(ch, ACCEPT);
+ /*
+ * we comment this line, because a space after a macro
+ * is useful to exit from a macro
+ //parser.push(TToken(TToken::CONTROL, ";"));
+ */
+ state = 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))
+ else if (isdigit(ch))
{
+ parser.push(TToken(TToken::CONTROL, buffer));
+ buffer.erase();
buffer.push_back(ch);
- state = LONG_IDENTIFIER;
+ state = NUMBER;
}
- else transaction(ch, ACCEPT);
+ else
+ {
+ parser.push(TToken(TToken::CONTROL, buffer));
+ buffer.erase();
+ transaction(ch, ACCEPT);
+ }
break;
case PARAMETER:
if (ch == -1) error();
state = ACCEPT;
}
break;
- case LONG_IDENTIFIER:
+ case IDENTIFIER:
if (ch == -1)
{
parser.push(TToken(TToken::LETTER, buffer));
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;
+ parser.push(TToken(TToken::CONTROL, "space"));
+ state = ACCEPT;
}
else if (ch == '\\')
{
buffer.erase();
state = ESCAPE;
}
+ else if (ch == '#')
+ {
+ parser.push(TToken(TToken::LETTER, buffer));
+ buffer.erase();
+ state = PARAMETER;
+ }
else
{
parser.push(TToken(TToken::LETTER, buffer));
transaction(ch, ACCEPT);
}
break;
+ case NUMBER:
+ if (isdigit(ch)) buffer.push_back(ch);
+ else if (isspace(ch))
+ {
+ parser.push(TToken(TToken::DIGIT, buffer));
+ buffer.erase();
+ parser.push(TToken(TToken::CONTROL, "space"));
+ state = ACCEPT;
+ }
+ else if (isalpha(ch))
+ {
+ parser.push(TToken(TToken::DIGIT, buffer));
+ buffer.erase();
+ buffer.push_back(ch);
+ state = IDENTIFIER;
+ }
+ else if (ch == -1)
+ {
+ parser.push(TToken(TToken::DIGIT, buffer));
+ buffer.erase();
+ state = ACCEPT;
+ }
+ else if (ch == '\\')
+ {
+ parser.push(TToken(TToken::DIGIT, buffer));
+ buffer.erase();
+ state = ESCAPE;
+ }
+ else if (ch == '#')
+ {
+ parser.push(TToken(TToken::DIGIT, buffer));
+ buffer.erase();
+ state = PARAMETER;
+ }
+ else
+ {
+ parser.push(TToken(TToken::DIGIT, buffer));
+ buffer.erase();
+ transaction(ch, ACCEPT);
+ }
+ break;
default:
assert(0);
break;
case ESCAPE: parser.setCursorHint("\\"); break;
case MACRO: parser.setCursorHint("\\" + buffer); break;
case PARAMETER: parser.setCursorHint("#"); break;
- case LONG_IDENTIFIER: parser.setCursorHint(buffer); break;
+ case IDENTIFIER: parser.setCursorHint(buffer); break;
+ case NUMBER: parser.setCursorHint(buffer); break;
default: parser.setCursorHint(""); break;
}
}
switch (state)
{
case ACCEPT:
- case IGNORE_SPACE:
- restore = parser.drop();
+ restore = parser.drop(alt);
if (restore.length() > 0 && restore[0] == '\\')
{
+ cout << restore << endl;
buffer = std::string(restore, 1, restore.length() - 1);
state = (buffer.length() > 0) ? MACRO : ESCAPE;
}
+ else if (restore.length() > 0 && isdigit(restore[0]))
+ {
+ buffer = restore;
+ state = NUMBER;
+ }
+ else if (restore.length() > 0 && isalpha(restore[0]))
+ {
+ buffer = restore;
+ state = IDENTIFIER;
+ }
break;
case ESCAPE:
state = ACCEPT;
else buffer.erase(buffer.length() - 1, 1);
if (buffer.length() == 0) state = ESCAPE;
break;
- case LONG_IDENTIFIER:
- buffer.erase(buffer.length() - 1, 1);
+ case IDENTIFIER:
+ if (alt) buffer.erase();
+ else buffer.erase(buffer.length() - 1, 1);
+ if (buffer.length() == 0) state = ACCEPT;
+ break;
+ case NUMBER:
+ if (alt) buffer.erase();
+ else buffer.erase(buffer.length() - 1, 1);
if (buffer.length() == 0) state = ACCEPT;
break;
case PARAMETER:
default:
- assert(0);
+ //assert(0);
+ error();
break;
}
case ESCAPE: parser.setCursorHint("\\"); break;
case MACRO: parser.setCursorHint("\\" + buffer); break;
case PARAMETER: parser.setCursorHint("#"); break;
+ case IDENTIFIER: parser.setCursorHint(buffer); break;
+ case NUMBER: parser.setCursorHint(buffer); break;
default: parser.setCursorHint(""); break;
}
}