Removed everything related to ast
This commit is contained in:
parent
3c73708178
commit
8c21942dad
207
main.c
207
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 <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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user