-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexpr-xx.c
executable file
·118 lines (97 loc) · 3.15 KB
/
expr-xx.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Define operator precedence
typedef struct {
char op;
int precedence;
int is_right_associative; // 1 for right-associative, 0 otherwise
} Operator;
Operator operators[] = {
{'^', 4, 1}, // Right-associative
{'*', 3, 0},
{'/', 3, 0},
{'%', 3, 0},
{'+', 2, 0},
{'-', 2, 0},
{'<', 1, 0},
{'>', 1, 0},
{'E', 1, 0}, // '==' operator
{'N', 1, 0}, // '!=' operator
{'A', 0, 0}, // '&&' operator
{'O', 0, 0}, // '||' operator
{0, 0, 0} // Sentinel value
};
// Get precedence of an operator
int get_precedence(char op) {
for (int i = 0; operators[i].op; i++) {
if (operators[i].op == op) {
return operators[i].precedence;
}
}
return -1; // Not an operator
}
// Check if an operator is right-associative
int is_right_associative(char op) {
for (int i = 0; operators[i].op; i++) {
if (operators[i].op == op) {
return operators[i].is_right_associative;
}
}
return 0; // Default is left-associative
}
// Parse an expression using precedence
Node *parse_expression(int min_precedence) {
Node *left = unary(); // Start with a unary expression
while (*input) {
skip_whitespace();
char op = *input;
int precedence = get_precedence(op);
if (precedence < min_precedence) {
break; // Operator has lower precedence, stop parsing
}
input++; // Consume the operator
Node *right = parse_expression(precedence + (is_right_associative(op) ? 0 : 1));
left = new_node(op, 0, left, right); // Create a new operator node
}
return left;
}
// Adjust the `expression` function to start with the precedence-based parsing
Node *expression() {
return parse_expression(0); // Start with the lowest precedence
}
Node *parse_expression(int min_precedence);
// Parse a factor (handles numbers, variables, and parenthesized expressions)
Node *factor() {
skip_whitespace();
if (*input == '(') {
input++; // Consume '('
Node *result = parse_expression(0); // Parse the inner expression
skip_whitespace();
if (*input == ')') {
input++; // Consume ')'
} else {
fprintf(stderr, "Error: Expected ')'\n");
exit(1);
}
return result;
}
return number_or_variable(); // Parse a number or variable
}
// Parse an expression using precedence, now with parentheses handling
Node *parse_expression(int min_precedence) {
Node *left = factor(); // Start with a factor
while (*input) {
skip_whitespace();
char op = *input;
int precedence = get_precedence(op);
if (precedence < min_precedence) {
break; // Operator has lower precedence, stop parsing
}
input++; // Consume the operator
Node *right = parse_expression(precedence + (is_right_associative(op) ? 0 : 1));
left = new_node(op, 0, left, right); // Create a new operator node
}
return left;
}
// Adjust the `expression` function to start with the precedence-based parsing
Node *expression() {
return parse_expression(0); // Start with the lowest precedence
}