aboutsummaryrefslogtreecommitdiff
path: root/tests/sysy_lvX/072_expr_eval.sy
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.001@gmail.com>2026-09-15 08:16:43 +0800
committerRichard Qin <richard.qin.001@gmail.com>2026-09-15 08:16:43 +0800
commit4022e5c95210631e4aceb08eaf9d9071aa5aefc4 (patch)
treea5922559836e45fb3459a3d070367912e1035b1a /tests/sysy_lvX/072_expr_eval.sy
downloadrcc-master.tar.gz
rcc-master.tar.xz
Set up a git repoHEADmaster
Diffstat (limited to 'tests/sysy_lvX/072_expr_eval.sy')
-rw-r--r--tests/sysy_lvX/072_expr_eval.sy145
1 files changed, 145 insertions, 0 deletions
diff --git a/tests/sysy_lvX/072_expr_eval.sy b/tests/sysy_lvX/072_expr_eval.sy
new file mode 100644
index 0000000..08e95a0
--- /dev/null
+++ b/tests/sysy_lvX/072_expr_eval.sy
@@ -0,0 +1,145 @@
+const int TOKEN_NUM = 0, TOKEN_OTHER = 1;
+int last_char = 32, num, other;
+int cur_token;
+
+int next_char() {
+ last_char = getch();
+ return last_char;
+}
+
+int is_space(int c) {
+ if (c == 32 || c == 10) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+int is_num(int c) {
+ if (c >= 48 && c <= 57) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+int next_token() {
+ while (is_space(last_char)) next_char();
+ if (is_num(last_char)) {
+ num = last_char - 48;
+ while (is_num(next_char())) {
+ num = num * 10 + last_char - 48;
+ }
+ cur_token = TOKEN_NUM;
+ }
+ else {
+ other = last_char;
+ next_char();
+ cur_token = TOKEN_OTHER;
+ }
+ return cur_token;
+}
+
+int panic() {
+ putch(112);
+ putch(97);
+ putch(110);
+ putch(105);
+ putch(99);
+ putch(33);
+ putch(10);
+ return -1;
+}
+
+int get_op_prec(int op) {
+ // +, -
+ if (op == 43 || op == 45) return 10;
+ // *, /, %
+ if (op == 42 || op == 47 || op == 37) return 20;
+ // other
+ return 0;
+}
+
+void stack_push(int s[], int v) {
+ s[0] = s[0] + 1;
+ s[s[0]] = v;
+}
+
+int stack_pop(int s[]) {
+ int last = s[s[0]];
+ s[0] = s[0] - 1;
+ return last;
+}
+
+int stack_peek(int s[]) {
+ return s[s[0]];
+}
+
+int stack_size(int s[]) {
+ return s[0];
+}
+
+int eval_op(int op, int lhs, int rhs) {
+ // +
+ if (op == 43) return lhs + rhs;
+ // -
+ if (op == 45) return lhs - rhs;
+ // *
+ if (op == 42) return lhs * rhs;
+ // /
+ if (op == 47) return lhs / rhs;
+ // %
+ if (op == 37) return lhs % rhs;
+ // other
+ return 0;
+}
+
+int eval() {
+ int oprs[256] = {}, ops[256] = {};
+ // get the first value
+ if (cur_token != TOKEN_NUM) return panic();
+ stack_push(oprs, num);
+ next_token();
+ // evaluate
+ while (cur_token == TOKEN_OTHER) {
+ // get operator
+ int op = other;
+ if (!get_op_prec(op)) break;
+ next_token();
+ // handle operator
+ while (stack_size(ops) && get_op_prec(stack_peek(ops)) >= get_op_prec(op)) {
+ // evaluate the current operation
+ int cur_op = stack_pop(ops);
+ int rhs = stack_pop(oprs), lhs = stack_pop(oprs);
+ stack_push(oprs, eval_op(cur_op, lhs, rhs));
+ }
+ stack_push(ops, op);
+ // get next expression
+ if (cur_token != TOKEN_NUM) return panic();
+ stack_push(oprs, num);
+ next_token();
+ }
+ // eat ';'
+ next_token();
+ // clear the operator stack
+ while (stack_size(ops)) {
+ int cur_op = stack_pop(ops);
+ int rhs = stack_pop(oprs), lhs = stack_pop(oprs);
+ stack_push(oprs, eval_op(cur_op, lhs, rhs));
+ }
+ return stack_peek(oprs);
+}
+
+int main() {
+ int count = getint();
+ getch();
+ next_token();
+ while (count) {
+ putint(eval());
+ putch(10);
+ count = count - 1;
+ }
+ return 0;
+}