diff --git a/main.c b/main.c index 0655a91..484d9c5 100644 --- a/main.c +++ b/main.c @@ -1,11 +1,8 @@ /* -E ::= UT{+T}{-T} -T ::= F{*F}{/F} +E ::= T{+T} +T ::= F{*F} F ::= (E)|i -U ::= -|+|_ - -'_' stands for empty sequence */ @@ -15,199 +12,103 @@ U ::= -|+|_ #include -#define fatal(...) {\ - fprintf(stderr, "\nError at char %d\n", number);\ - fprintf(stderr, "%s\n", line);\ - for (int i = 0; i < number - 1; i++)\ - fputc(' ', stderr);\ - fprintf(stderr, "^\nMessage: ");\ - fprintf(stderr, __VA_ARGS__);\ - exit(1);\ - } +#define eprintf(...) fprintf(stderr, __VA_ARGS__) -typedef enum _NodeType { - NNUM = 1, - NOP = 2 -} NodeType; +typedef enum TokenType { + INT, + PLUS, + MINUS, + LBRACE, + RBRACE +} TokenType; -typedef struct _Node Node; -struct _Node { - Node *parent; - Node *left; - Node *right; +typedef struct _Token { + TokenType type; - NodeType type; + int value; +} Token; - int number; - char operator; // + - * / m p -}; -Node *e(); -Node *t(); -Node *f(); -Node *u(); - -char line[1024]; -int symbol; -int number = 0; +void fatal(const char* message); void scan(); -int LRN(Node *node); +void e(); +void t(); +void f(); + + +const int LINE_MAX = 1024; +char *line; + +int symbol; +int char_num = 0; int main(int argc, char* argv[]) { - - memset(line, 0, 1024); + line = calloc(sizeof(char), LINE_MAX); + memset(line, 0, LINE_MAX); scan(); - Node *root = e(); + e(); if (symbol != '\n') { - fatal("Syntax invalid\n"); + fatal("Syntax invalid"); } printf("Success\n"); - printf("Answer: %d\n", LRN(root)); + free(line); return 0; } void scan() { symbol = getchar(); if (symbol == '\n') - line[number++] = ' '; + line[char_num++] = ' '; else - line[number++] = symbol; + line[char_num++] = symbol; } -Node *e() { - Node *left, *right, *root; - - root = u(); - left = t(); - - if (root != NULL) { - root->left = left; - left = root; - } - - while (symbol == '+' || symbol == '-') { - root = calloc(sizeof(Node), 1); - root->type = NOP; - root->operator = symbol; - +void e() { + t(); + while (symbol == '+') { scan(); - right = t(); - - root->left = left; - root->right = right; - - left->parent = root; - right->parent = root; - left = root; - right = NULL; + t(); } - return root; } -Node *t() { - Node *left, *right, *root; - root = left = f(); - - while (symbol == '*' || symbol == '/') { - root = calloc(sizeof(Node), 1); - root->type = NOP; - root->operator = symbol; - +void t() { + f(); + while (symbol == '*') { scan(); - right = f(); - - root->left = left; - root->right = right; - - left->parent = root; - right->parent = root; - left = root; - right = NULL; + f(); } - return root; } -Node *f() { - Node *node; +void f() { if (symbol == '(') { scan(); - node = e(); + e(); if (symbol != ')') { - fatal("Expected parentheses, found '%c'\n", symbol); + fatal("Expected parentheses"); } } - else if (symbol < '0' || symbol > '9') { - if (symbol == '\n') { - fatal("LF too early\n"); - } - else { - fatal("Unexpected symbol '%c'\n", symbol); - } + else if (symbol >= '0' && symbol <= '9') { + ; + } + else if (symbol == '\n') { + fatal("LF too early"); } else { - node = calloc(sizeof(Node), 1); - node->type = NNUM; - node->number = (int) (symbol - '0'); + fatal("Unexpected symbol"); } scan(); - return node; } -Node *u() { - if (symbol == '-' || symbol == '+') { - Node *node = calloc(sizeof(Node), 1); - node->type = NOP; - node->operator = (symbol == '+') ? 'p' : 'm'; - scan(); - return node; - } - return NULL; -} - -int LRN(Node *node) { - int l, r, answer; - - if (node == NULL) - return 0; - - if (node->left != NULL) - l = LRN(node->left); - - if (node->right != NULL) - r = LRN(node->right); - - if (node->type == NOP) { - switch (node->operator) { - case '+': - answer = l + r; break; - case '-': - answer = l - r; break; - case '*': - answer = l * r; break; - case '/': - answer = l / r; break; - case 'm': - answer = -l; break; - case 'p': - answer = +l; break; - default: - fatal("Invalid operator indentifier: '%c'\n", node->operator); break; - } - } - else if (node->type == NNUM) { - answer = node->number; - } - else { - answer = 0; - } - - free(node); - return answer; +void fatal(const char* message) { + eprintf("\nError at char %d\n%s\n", char_num, line); + eprintf("%*c\n", char_num, '^'); + eprintf("Message: %s\n", message); + exit(1); }