Removed everything related to ast

This commit is contained in:
Ilya Bezrukov 2024-10-17 11:29:12 +03:00
parent 3c73708178
commit 8c21942dad

207
main.c
View File

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