#include #include #include #include "lists.h" #include "tokens.h" // The token data type needs to remember: // - what type it is (left paren, right paren, operator, or integer). // - if it is an operator, what operator it is // - if it is an integer, what integer it is. // For the type, we use the following convention: // token_type = 0 => LEFT_PAREN // token_type = 1 => RIGHT_PAREN // token_type = 2 => OPERATOR // token_type = 3 => INTEGER const int LEFT_PAREN_TYPE = 0; const int RIGHT_PAREN_TYPE = 1; const int OPERATOR_TYPE = 2; const int INTEGER_TYPE = 3; struct token_struct { int token_type; char operator; int integer; }; Token newToken() { Token result = malloc(sizeof(result)); result->token_type = -1; result->operator = 0; result->integer = 0; } int tokenIsLeftParen(Token token) { return (token->token_type == LEFT_PAREN_TYPE); } int tokenIsRightParen(Token token) { return (token->token_type == RIGHT_PAREN_TYPE); } int tokenIsOperator(Token token) { return (token->token_type == OPERATOR_TYPE); } int tokenIsInt(Token token) { return (token->token_type == INTEGER_TYPE); } char tokenOperator(Token token) { if (tokenIsOperator(token) == 0) { tokenPrint(token); printf("error: this token is not an operator\n"); exit(1); } return token->operator; } int tokenInt(Token token) { if (tokenIsInt(token) == 0) { tokenPrint(token); printf("error: this token is not an operator\n"); exit(1); } return token->integer; } void tokenPrint(Token token) { if (token->token_type == LEFT_PAREN_TYPE) { printf("("); } else if (token->token_type == RIGHT_PAREN_TYPE) { printf(")"); } else if (token->token_type == OPERATOR_TYPE) { printf("%c", token->operator); } else if (token->token_type == INTEGER_TYPE) { printf("%d", token->integer); } } // some auxiliary functions, to interface tokens with lists and stacks. void printTokenList(list tokens) { link i; printf("\n"); for (i = listFirst(tokens); i != NULL; i = linkNext(i)) { Token token = (Token) linkItem(i); tokenPrint(token); printf(" "); } printf("\n"); } // This is the most important function, it converts a string into // a list of tokens. list tokenize(char * input) { list result = newList(); int index = 0; while (input[index] != 0) { Token token = newToken(); char current = input[index]; if (current == '(') { token->token_type = LEFT_PAREN_TYPE; } else if (current == ')') { token->token_type = RIGHT_PAREN_TYPE; } else if ((current == '+') || (current == '-') || (current == '*') || (current == '/')) { token->token_type = OPERATOR_TYPE; token->operator = current; } else if ((current >= '0') && (current <= '9')) { token->token_type = INTEGER_TYPE; int number = 0; while((current >= '0') && (current <= '9')) { number = 10 * number + (current - '0'); index++; current = input[index]; } index--; token->integer = number; } if (token->token_type != -1) { insertAtEnd(result, newLink(token)); } index++; } return result; }