From 4638e4a0170795799e9adc8cf97184d969ba417b Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Sat, 12 Jul 2014 17:58:03 -0700 Subject: [PATCH] Add parenthesis support --- src/debugger/cli-debugger.c | 1 + src/debugger/parser.c | 65 +++++++++++++++++++++++++++++++++++-- src/debugger/parser.h | 3 ++ 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index fc76a5711..f9f196c74 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -336,6 +336,7 @@ static uint32_t _evaluateParseTree(struct ARMDebugger* debugger, struct ParseTre case TOKEN_IDENTIFIER_TYPE: return _lookupIdentifier(debugger, tree->token.identifierValue, dv); case TOKEN_ERROR_TYPE: + default: dv->type = DV_ERROR_TYPE; } return 0; diff --git a/src/debugger/parser.c b/src/debugger/parser.c index 4282b188a..ee462b497 100644 --- a/src/debugger/parser.c +++ b/src/debugger/parser.c @@ -25,6 +25,7 @@ static struct LexVector* _lexOperator(struct LexVector* lv, char operator) { lv = lvNext; lvNext = malloc(sizeof(struct LexVector)); lvNext->next = lv->next; + lvNext->token.type = TOKEN_ERROR_TYPE; lv->next = lvNext; return lvNext; } @@ -39,6 +40,7 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) { enum LexState state = LEX_ROOT; const char* tokenStart = 0; + struct LexVector* lvNext; while (length > 0 && string[0] && string[0] != ' ' && state != LEX_ERROR) { char token = string[0]; @@ -68,6 +70,15 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) { state = LEX_EXPECT_HEX; next = 0; break; + case '(': + state = LEX_ROOT; + lv->token.type = TOKEN_OPEN_PAREN_TYPE; + lvNext = malloc(sizeof(struct LexVector)); + lvNext->next = lv->next; + lvNext->token.type = TOKEN_ERROR_TYPE; + lv->next = lvNext; + lv = lvNext; + break; default: if (tolower(token) >= 'a' && tolower(token <= 'z')) { state = LEX_EXPECT_IDENTIFIER; @@ -88,6 +99,11 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) { lv = _lexOperator(lv, token); state = LEX_ROOT; break; + case ')': + lv->token.type = TOKEN_IDENTIFIER_TYPE; + lv->token.identifierValue = strndup(tokenStart, string - tokenStart - 1); + state = LEX_EXPECT_OPERATOR; + break; default: break; } @@ -117,6 +133,11 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) { lv = _lexOperator(lv, token); state = LEX_ROOT; break; + case ')': + lv->token.type = TOKEN_UINT_TYPE; + lv->token.uintValue = next; + state = LEX_EXPECT_OPERATOR; + break; default: state = LEX_ERROR; } @@ -166,6 +187,11 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) { lv = _lexOperator(lv, token); state = LEX_ROOT; break; + case ')': + lv->token.type = TOKEN_UINT_TYPE; + lv->token.uintValue = next; + state = LEX_EXPECT_OPERATOR; + break; default: state = LEX_ERROR; break; @@ -183,6 +209,23 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) { break; } break; + case LEX_EXPECT_OPERATOR: + switch (token) { + case '+': + case '-': + case '*': + case '/': + lvNext = malloc(sizeof(struct LexVector)); + lvNext->next = lv->next; + lvNext->token.type = TOKEN_CLOSE_PAREN_TYPE; + lv->next = lvNext; + lv = _lexOperator(lv->next, token); + state = LEX_ROOT; + break; + default: + state = LEX_ERROR; + } + break; case LEX_ERROR: // This shouldn't be reached break; @@ -199,6 +242,12 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) { lv->token.type = TOKEN_IDENTIFIER_TYPE; lv->token.identifierValue = strndup(tokenStart, string - tokenStart); break; + case LEX_EXPECT_OPERATOR: + lvNext = malloc(sizeof(struct LexVector)); + lvNext->next = lv->next; + lvNext->token.type = TOKEN_CLOSE_PAREN_TYPE; + lv->next = lvNext; + break; case LEX_ERROR: default: lv->token.type = TOKEN_ERROR_TYPE; @@ -222,7 +271,7 @@ static struct ParseTree* _parseTreeCreate() { return tree; } -static struct LexVector* _parseExpression(struct ParseTree* tree, struct LexVector* lv, int precedence) { +static struct LexVector* _parseExpression(struct ParseTree* tree, struct LexVector* lv, int precedence, int openParens) { struct ParseTree* newTree = 0; while (lv) { int newPrecedence; @@ -237,6 +286,16 @@ static struct LexVector* _parseExpression(struct ParseTree* tree, struct LexVect return 0; } break; + case TOKEN_OPEN_PAREN_TYPE: + lv = _parseExpression(tree, lv->next, INT_MAX, openParens + 1); + break; + case TOKEN_CLOSE_PAREN_TYPE: + if (openParens <= 0) { + tree->token.type = TOKEN_ERROR_TYPE; + return 0; + } + return lv->next; + break; case TOKEN_OPERATOR_TYPE: newPrecedence = _operatorPrecedence[lv->token.operatorValue]; if (newPrecedence < precedence) { @@ -245,7 +304,7 @@ static struct LexVector* _parseExpression(struct ParseTree* tree, struct LexVect tree->lhs = newTree; tree->rhs = _parseTreeCreate(); tree->token = lv->token; - lv = _parseExpression(tree->rhs, lv->next, newPrecedence); + lv = _parseExpression(tree->rhs, lv->next, newPrecedence, openParens); if (tree->token.type == TOKEN_ERROR_TYPE) { tree->token.type = TOKEN_ERROR_TYPE; } @@ -271,7 +330,7 @@ void parseLexedExpression(struct ParseTree* tree, struct LexVector* lv) { tree->lhs = 0; tree->rhs = 0; - _parseExpression(tree, lv, _operatorPrecedence[OP_ASSIGN]); + _parseExpression(tree, lv, _operatorPrecedence[OP_ASSIGN], 0); } void lexFree(struct LexVector* lv) { diff --git a/src/debugger/parser.h b/src/debugger/parser.h index a6551f4bf..78cbfa2fe 100644 --- a/src/debugger/parser.h +++ b/src/debugger/parser.h @@ -11,6 +11,7 @@ enum LexState { LEX_EXPECT_DECIMAL, LEX_EXPECT_HEX, LEX_EXPECT_PREFIX, + LEX_EXPECT_OPERATOR }; enum Operation { @@ -27,6 +28,8 @@ struct Token { TOKEN_UINT_TYPE, TOKEN_IDENTIFIER_TYPE, TOKEN_OPERATOR_TYPE, + TOKEN_OPEN_PAREN_TYPE, + TOKEN_CLOSE_PAREN_TYPE, } type; union { uint32_t uintValue;