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}
T ::= F{*F}{/F}
E ::= T{+T}
T ::= F{*F}
F ::= (E)|i
U ::= -|+|_
'_' stands for empty sequence
*/
@ -15,199 +12,103 @@ U ::= -|+|_
#include <stdbool.h>
#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);
}