/*************************************************************************************** * Copyright (c) 2014-2022 Zihao Yu, Nanjing University * * NEMU is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: * http://license.coscl.org.cn/MulanPSL2 * * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * * See the Mulan PSL v2 for more details. ***************************************************************************************/ // Modified by: Zhiyi Zhang in 2024.08 #include "common.h" /* We use regex to parse the expression. * You can use regular expressions as well. */ #include enum { TK_NOTYPE = 256, TK_EQ, /* TODO: Add more token types */ }; static struct rule { const char *regex; int token_type; } rules[] = { /* TODO: Add more rules. * Pay attention to the precedence level of different rules. */ {" +", TK_NOTYPE}, // spaces {"\\+", '+'}, // plus {"==", TK_EQ}, // equal }; #define NR_REGEX ARRLEN(rules) static std::regex re[NR_REGEX] = {}; /* Rules are used for many times. * Therefore we compile them only once before any usage. */ void init_regex() { for (int i = 0; i < NR_REGEX; i ++) { try { re[i] = std::regex(rules[i].regex, std::regex_constants::ECMAScript); } catch(const std::regex_error & e) { panic("regex compilation failed: %s\n%s", e.what(), rules[i].regex); } } } typedef struct token { int type; char str[32]; } Token; static Token tokens[32] = { -1 }; static int nr_token = -1; static bool make_token(char *e) { int position = 0; int i; std::cmatch pmatch; nr_token = 0; while (e[position] != '\0') { /* Try all rules one by one. */ for (i = 0; i < NR_REGEX; i ++) { if (std::regex_search(e + position, pmatch, re[i], std::regex_constants::match_continuous)) { char *substr_start = e + position; int substr_len = pmatch.length(); Log("match rules[%d] = \"%s\" at position %d with len %d: %.*s", i, rules[i].regex, position, substr_len, substr_len, substr_start); position += substr_len; /* TODO: Now a new token is recognized with rules[i]. Add codes * to record the token in the array `tokens'. For certain types * of tokens, some extra actions should be performed. */ switch (rules[i].token_type) { default: TODO(); } break; } } if (i == NR_REGEX) { printf("no match at position %d\n%s\n%*.s^\n", position, e, position, ""); return false; } } return true; } uint32_t expr(char *e, bool *success) { if (!make_token(e)) { *success = false; return 0; } /* TODO: Insert codes to evaluate the expression. */ TODO(); return 0; }