Debugger: Make operator lexing a bit more generic
@@ -21,7 +21,6 @@ LEX_EXPECT_DECIMAL,
LEX_EXPECT_HEX_FIRST, LEX_EXPECT_HEX, LEX_EXPECT_PREFIX, - LEX_EXPECT_OPERATOR, LEX_EXPECT_OPERATOR2, };@@ -91,31 +90,6 @@ break;
} *state = LEX_ERROR; } - if (*state == LEX_ROOT || *state == LEX_ERROR) { - struct Token lvNext; - lvNext.type = TOKEN_OPERATOR_TYPE; - *state = LEX_ROOT; - switch (operator) { - case '-': - lvNext.operatorValue = OP_NEGATE; - break; - case '~': - lvNext.operatorValue = OP_FLIP; - break; - case '!': - lvNext.operatorValue = OP_NOT; - break; - case '*': - lvNext.operatorValue = OP_DEREFERENCE; - break; - default: - lvNext.type = TOKEN_ERROR_TYPE; - *state = LEX_ERROR; - return; - } - *LexVectorAppend(lv) = lvNext; - return; - } struct Token lvNext; lvNext.type = TOKEN_OPERATOR_TYPE; switch (operator) {@@ -155,6 +129,9 @@ break;
case '!': lvNext.operatorValue = OP_NOT; break; + case '~': + lvNext.operatorValue = OP_FLIP; + break; default: *state = LEX_ERROR; return;@@ -190,14 +167,14 @@ lvNext->type = TOKEN_UINT_TYPE;
lvNext->uintValue = next; lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_CLOSE_PAREN_TYPE; - *state = LEX_EXPECT_OPERATOR; + *state = LEX_ROOT; break; case ' ': case '\t': lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_UINT_TYPE; lvNext->uintValue = next; - *state = LEX_EXPECT_OPERATOR; + *state = LEX_ROOT; break; default: *state = LEX_ERROR;@@ -264,21 +241,30 @@ case '$':
state = LEX_EXPECT_HEX_FIRST; next = 0; break; - case '%': - state = LEX_EXPECT_BINARY_FIRST; - next = 0; - break; case '(': state = LEX_ROOT; lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_OPEN_PAREN_TYPE; break; - case '!': + case '=': + case '+': case '-': + case '*': + case '/': + case '%': + case '&': + case '|': + case '^': + case '<': + case '>': + case '!': case '~': - case '*': _lexOperator(lv, token, &state); break; + case ')': + lvNext = LexVectorAppend(lv); + lvNext->type = TOKEN_CLOSE_PAREN_TYPE; + break; case ' ': case '\t': break;@@ -305,6 +291,7 @@ case '^':
case '<': case '>': case '!': + case '~': lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_IDENTIFIER_TYPE; lvNext->identifierValue = strndup(tokenStart, string - tokenStart - 1);@@ -316,14 +303,14 @@ lvNext->type = TOKEN_IDENTIFIER_TYPE;
lvNext->identifierValue = strndup(tokenStart, string - tokenStart - 1); lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_CLOSE_PAREN_TYPE; - state = LEX_EXPECT_OPERATOR; + state = LEX_ROOT; break; case ' ': case '\t': lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_IDENTIFIER_TYPE; lvNext->identifierValue = strndup(tokenStart, string - tokenStart - 1); - state = LEX_EXPECT_OPERATOR; + state = LEX_ROOT; break; default: break;@@ -446,33 +433,6 @@ _lexValue(lv, token, next, &state);
break; } break; - case LEX_EXPECT_OPERATOR: - switch (token) { - case '=': - case '+': - case '-': - case '*': - case '/': - case '%': - case '&': - case '|': - case '^': - case '<': - case '>': - case '!': - _lexOperator(lv, token, &state); - break; - case ')': - lvNext = LexVectorAppend(lv); - lvNext->type = TOKEN_CLOSE_PAREN_TYPE; - break; - case ' ': - case '\t': - break; - default: - state = LEX_ERROR; - } - break; case LEX_ERROR: // This shouldn't be reached break;@@ -494,7 +454,6 @@ lvNext->type = TOKEN_IDENTIFIER_TYPE;
lvNext->identifierValue = strndup(tokenStart, string - tokenStart); break; case LEX_ROOT: - case LEX_EXPECT_OPERATOR: case LEX_EXPECT_OPERATOR2: break; case LEX_EXPECT_BINARY_FIRST:@@ -568,9 +527,6 @@ tree->lhs->token.uintValue = token->uintValue;
tree->rhs = _parseTreeCreate(); tree->token.type = TOKEN_SEGMENT_TYPE; i = _parseExpression(tree->rhs, lv, i + 1, precedence, openParens); - if (tree->token.type == TOKEN_ERROR_TYPE) { - tree->token.type = TOKEN_ERROR_TYPE; - } break; case TOKEN_OPEN_PAREN_TYPE: ++*openParens;@@ -583,6 +539,21 @@ }
--*openParens; return i + 1; case TOKEN_OPERATOR_TYPE: + if (tree->token.type == TOKEN_ERROR_TYPE) { + switch (token->operatorValue) { + case OP_SUBTRACT: + token->operatorValue = OP_NEGATE; + break; + case OP_MULTIPLY: + token->operatorValue = OP_DEREFERENCE; + break; + case OP_NOT: + case OP_FLIP: + break; + default: + break; + } + } newPrecedence = _operatorPrecedence[token->operatorValue]; if (newPrecedence < precedence) { newTree = _parseTreeCreate();
@@ -59,14 +59,6 @@ assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE);
assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 2); } -M_TEST_DEFINE(lexSigilBinary) { - LEX("%10"); - - assert_int_equal(LexVectorSize(lv), 1); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 2); -} - M_TEST_DEFINE(lexHex) { LEX("0x10");@@ -106,13 +98,6 @@ }
M_TEST_DEFINE(lexTruncatedBinary) { LEX("0b"); - - assert_int_equal(LexVectorSize(lv), 1); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexTruncatedSigilBinary) { - LEX("%"); assert_int_equal(LexVectorSize(lv), 1); assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_ERROR_TYPE);@@ -372,32 +357,12 @@ assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_UINT_TYPE);
assert_int_equal(LexVectorGetPointer(lv, 2)->uintValue, 1); } -M_TEST_DEFINE(lexNegateOperator) { - LEX("-1"); - - assert_int_equal(LexVectorSize(lv), 2); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->operatorValue, OP_NEGATE); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->uintValue, 1); -} - M_TEST_DEFINE(lexFlipOperator) { LEX("~1"); assert_int_equal(LexVectorSize(lv), 2); assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_OPERATOR_TYPE); assert_int_equal(LexVectorGetPointer(lv, 0)->operatorValue, OP_FLIP); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->uintValue, 1); -} - -M_TEST_DEFINE(lexDereferenceOperator) { - LEX("*1"); - - assert_int_equal(LexVectorSize(lv), 2); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->operatorValue, OP_DEREFERENCE); assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_UINT_TYPE); assert_int_equal(LexVectorGetPointer(lv, 1)->uintValue, 1); }@@ -562,138 +527,6 @@ assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE);
assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_SHIFT_R); } -M_TEST_DEFINE(lexEqualsInvalidOperator) { - LEX("1=|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_ASSIGN); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexIdentifierEqualsInvalidOperator) { - LEX("x=|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); - assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_ASSIGN); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexNotInvalidOperator) { - LEX("1!|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_NOT); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexIdentifierNotInvalidOperator) { - LEX("x!|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); - assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_NOT); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexLessInvalidOperator) { - LEX("1<|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_LESS); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexIdentifierLessInvalidOperator) { - LEX("x<|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); - assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_LESS); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexGreaterInvalidOperator) { - LEX("1>|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_GREATER); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexIdentifierGreaterInvalidOperator) { - LEX("x>|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); - assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_GREATER); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexAndInvalidOperator) { - LEX("1&|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_AND); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexIdentifierAndInvalidOperator) { - LEX("x&|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); - assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_AND); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexOrInvalidOperator) { - LEX("1|>"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_OR); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexIdentifierOrInvalidOperator) { - LEX("x|>"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); - assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_OR); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - M_TEST_DEFINE(lexSimpleExpression) { LEX("1+1");@@ -834,7 +667,6 @@ cmocka_unit_test(lexEmpty),
cmocka_unit_test(lexInt), cmocka_unit_test(lexDecimal), cmocka_unit_test(lexBinary), - cmocka_unit_test(lexSigilBinary), cmocka_unit_test(lexHex), cmocka_unit_test(lexSigilHex), cmocka_unit_test(lexSigilSegmentHex),@@ -844,7 +676,6 @@ cmocka_unit_test(lexInvalidBinary),
cmocka_unit_test(lexTruncatedHex), cmocka_unit_test(lexTruncatedSigilHex), cmocka_unit_test(lexTruncatedBinary), - cmocka_unit_test(lexTruncatedSigilBinary), cmocka_unit_test(lexIdentifier), cmocka_unit_test(lexAddOperator), cmocka_unit_test(lexIdentifierAddOperator),@@ -868,9 +699,7 @@ cmocka_unit_test(lexGreaterOperator),
cmocka_unit_test(lexIdentifierGreaterOperator), cmocka_unit_test(lexNotOperator), cmocka_unit_test(lexNotNotOperator), - cmocka_unit_test(lexNegateOperator), cmocka_unit_test(lexFlipOperator), - cmocka_unit_test(lexDereferenceOperator), cmocka_unit_test(lexEqualsOperator), cmocka_unit_test(lexIdentifierEqualsOperator), cmocka_unit_test(lexNotEqualsOperator),@@ -887,18 +716,6 @@ cmocka_unit_test(lexShiftLOperator),
cmocka_unit_test(lexIdentifierShiftLOperator), cmocka_unit_test(lexShiftROperator), cmocka_unit_test(lexIdentifierShiftROperator), - cmocka_unit_test(lexEqualsInvalidOperator), - cmocka_unit_test(lexIdentifierEqualsInvalidOperator), - cmocka_unit_test(lexNotInvalidOperator), - cmocka_unit_test(lexIdentifierNotInvalidOperator), - cmocka_unit_test(lexLessInvalidOperator), - cmocka_unit_test(lexIdentifierLessInvalidOperator), - cmocka_unit_test(lexGreaterInvalidOperator), - cmocka_unit_test(lexIdentifierGreaterInvalidOperator), - cmocka_unit_test(lexAndInvalidOperator), - cmocka_unit_test(lexIdentifierAndInvalidOperator), - cmocka_unit_test(lexOrInvalidOperator), - cmocka_unit_test(lexIdentifierOrInvalidOperator), cmocka_unit_test(lexSimpleExpression), cmocka_unit_test(lexOpenParen), cmocka_unit_test(lexCloseParen),
@@ -56,6 +56,12 @@
assert_int_equal(tree->token.type, TOKEN_ERROR_TYPE); } +M_TEST_DEFINE(parseError) { + PARSE("1 2"); + + assert_int_equal(tree->token.type, TOKEN_ERROR_TYPE); +} + M_TEST_DEFINE(parseSimpleExpression) { PARSE("1+2");@@ -108,11 +114,35 @@ assert_int_equal(tree->rhs->token.type, TOKEN_UINT_TYPE);
assert_int_equal(tree->rhs->token.uintValue, 3); } +M_TEST_DEFINE(parseIsolatedOperator) { + PARSE("+"); + + assert_int_equal(tree->token.type, TOKEN_OPERATOR_TYPE); + assert_int_equal(tree->lhs->token.type, TOKEN_ERROR_TYPE); + assert_int_equal(tree->rhs->token.type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(parseUnaryChainedOperator) { + PARSE("1+*2"); + + assert_int_equal(tree->token.type, TOKEN_OPERATOR_TYPE); + assert_int_equal(tree->token.operatorValue, OP_ADD); + assert_int_equal(tree->lhs->token.type, TOKEN_UINT_TYPE); + assert_int_equal(tree->lhs->token.uintValue, 1); + assert_int_equal(tree->rhs->token.type, TOKEN_OPERATOR_TYPE); + assert_int_equal(tree->rhs->token.operatorValue, OP_DEREFERENCE); + assert_int_equal(tree->rhs->rhs->token.type, TOKEN_UINT_TYPE); + assert_int_equal(tree->rhs->rhs->token.uintValue, 2); +} + M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(Parser, cmocka_unit_test(parseEmpty), cmocka_unit_test(parseInt), cmocka_unit_test(parseLexError), + cmocka_unit_test(parseError), cmocka_unit_test(parseSimpleExpression), cmocka_unit_test(parseAddMultplyExpression), cmocka_unit_test(parseParentheticalExpression), - cmocka_unit_test(parseParentheticalAddMultplyExpression)) + cmocka_unit_test(parseParentheticalAddMultplyExpression), + cmocka_unit_test(parseIsolatedOperator), + cmocka_unit_test(parseUnaryChainedOperator))