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}
|
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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user