ExpressionParser: Fix parse exception string

The main point of this commit is to fix this line:

temp << (char)type << "' got '" << token.string << "'";

which gets printed when DeskCalc encounters a parse error.

Specifically the (char)type part needed fixing.

This code would try to print the char equivalent of a token which got
converted to lower ascii character between 0 and 15. This would at
best result in a newline and never anything helpful.

I took the germ of idea and expanded upon it reassigning the TOKENs to the
numeric values of the printable characters they represent where applicable.
For instance TOKEN_STAR now has a value of 42 which is ascii for '*'. By
using implicit char -> int conversion the numeric value is avoided in the code.

So now (char)type will, in many cases get you the equivalent ascii char
represented by that type. Those that don't such as TOKEN_IDENTIFIER and
TOKEN_CONSTANT are special cased.

Once the TOKEN's values correspond to their ASCII equivalents some other
simplifications became possible interchanging the TOKEN and the character
it represents.
This commit is contained in:
John Scipione
2013-06-26 19:21:09 -04:00
parent 51f758db3f
commit 91a5e06148
+67 -60
View File
@@ -21,32 +21,33 @@
static const int32 kMaxDecimalPlaces = 32;
enum {
TOKEN_IDENTIFIER = 0,
enum {
TOKEN_NONE = 0,
TOKEN_IDENTIFIER,
TOKEN_CONSTANT,
TOKEN_PLUS,
TOKEN_MINUS,
TOKEN_END_OF_LINE = '\n',
TOKEN_STAR,
TOKEN_SLASH,
TOKEN_MODULO,
TOKEN_PLUS = '+',
TOKEN_MINUS = '-',
TOKEN_POWER,
TOKEN_FACTORIAL,
TOKEN_STAR = '*',
TOKEN_SLASH = '/',
TOKEN_MODULO = '%',
TOKEN_OPENING_BRACKET,
TOKEN_CLOSING_BRACKET,
TOKEN_POWER = '^',
TOKEN_FACTORIAL = '!',
TOKEN_AND,
TOKEN_OR,
TOKEN_NOT,
TOKEN_OPENING_BRACKET = '(',
TOKEN_CLOSING_BRACKET = ')',
TOKEN_NONE,
TOKEN_END_OF_LINE
TOKEN_AND = '&',
TOKEN_OR = '|',
TOKEN_NOT = '~'
};
struct ExpressionParser::Token {
Token()
: string(""),
@@ -218,50 +219,25 @@ class ExpressionParser::Tokenizer {
int32 type = TOKEN_NONE;
switch (*fCurrentChar) {
case '+':
type = TOKEN_PLUS;
case TOKEN_PLUS:
case TOKEN_MINUS:
case TOKEN_STAR:
case TOKEN_SLASH:
case TOKEN_MODULO:
case TOKEN_POWER:
case TOKEN_FACTORIAL:
case TOKEN_OPENING_BRACKET:
case TOKEN_CLOSING_BRACKET:
case TOKEN_AND:
case TOKEN_OR:
case TOKEN_NOT:
case TOKEN_END_OF_LINE:
type = *fCurrentChar;
break;
case '-':
type = TOKEN_MINUS;
break;
case '*':
type = TOKEN_STAR;
break;
case '/':
case '\\':
case ':':
type = TOKEN_SLASH;
break;
case '%':
type = TOKEN_MODULO;
break;
case '^':
type = TOKEN_POWER;
break;
case '!':
type = TOKEN_FACTORIAL;
break;
case '(':
type = TOKEN_OPENING_BRACKET;
break;
case ')':
type = TOKEN_CLOSING_BRACKET;
break;
case '&':
type = TOKEN_AND;
break;
case '|':
type = TOKEN_OR;
break;
case '~':
type = TOKEN_NOT;
break;
case '\n':
type = TOKEN_END_OF_LINE;
type = TOKEN_SLASH;
break;
case 'x':
@@ -755,9 +731,40 @@ ExpressionParser::_EatToken(int32 type)
{
Token token = fTokenizer->NextToken();
if (token.type != type) {
BString temp("expected '");
temp << (char)type << "' got '" << token.string << "'";
BString expected;
switch (type) {
case TOKEN_IDENTIFIER:
expected = "an identifier";
break;
case TOKEN_CONSTANT:
expected = "a constant";
break;
case TOKEN_PLUS:
case TOKEN_MINUS:
case TOKEN_STAR:
case TOKEN_MODULO:
case TOKEN_POWER:
case TOKEN_FACTORIAL:
case TOKEN_OPENING_BRACKET:
case TOKEN_CLOSING_BRACKET:
case TOKEN_AND:
case TOKEN_OR:
case TOKEN_NOT:
expected << "'" << (char)type << "'";
break;
case TOKEN_SLASH:
expected = "'/', '\\', or ':'";
break;
case TOKEN_END_OF_LINE:
expected = "'\\n'";
break;
}
BString temp;
temp << "Expected " << expected.String() << " got '" << token.string << "'";
throw ParseException(temp.String(), token.position);
}
}