> compile NEMU
221220000 张三 Linux zzy 5.15.146.1-microsoft-standard-WSL2 #1 SMP Thu Jan 11 04:09:03 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux 20:14:34 up 10:54, 2 users, load average: 0.37, 0.15, 0.05
This commit is contained in:
@ -58,4 +58,4 @@ LINKAGE += $(ARCHIVES)
|
|||||||
else
|
else
|
||||||
# Include rules to build NEMU
|
# Include rules to build NEMU
|
||||||
include $(NEMU_HOME)/scripts/native.mk
|
include $(NEMU_HOME)/scripts/native.mk
|
||||||
endif
|
endif
|
@ -139,6 +139,34 @@ static bool make_token(char *e) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool check_parentheses(Token* tokens, size_t len, size_t p, size_t q) {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
word_t eval(size_t p, size_t q) {
|
||||||
|
if (p > q) {
|
||||||
|
/* Bad expression */
|
||||||
|
panic("bad expression");
|
||||||
|
}
|
||||||
|
else if (p == q) {
|
||||||
|
/* Single token.
|
||||||
|
* For now this token should be a number.
|
||||||
|
* Return the value of the number.
|
||||||
|
*/
|
||||||
|
return atoi(tokens[p].str);
|
||||||
|
}
|
||||||
|
else if (check_parentheses(tokens, ARRLEN(tokens), p, q) == true) {
|
||||||
|
/* The expression is surrounded by a matched pair of parentheses.
|
||||||
|
* If that is the case, just throw away the parentheses.
|
||||||
|
*/
|
||||||
|
return eval(p + 1, q - 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* We should do more things here. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
word_t expr(char *e, bool *success) {
|
word_t expr(char *e, bool *success) {
|
||||||
if (!make_token(e)) {
|
if (!make_token(e)) {
|
||||||
@ -148,9 +176,7 @@ word_t expr(char *e, bool *success) {
|
|||||||
|
|
||||||
/* TODO: Insert codes to evaluate the expression. */
|
/* TODO: Insert codes to evaluate the expression. */
|
||||||
// TODO();
|
// TODO();
|
||||||
for (int i = 0; i < nr_token; i++) {
|
|
||||||
Log("token[%d].type = %d, token[%d].str = %s", i, tokens[i].type, i, tokens[i].str);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,6 @@ static int cmd_c(char *args) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int cmd_q(char *args) {
|
static int cmd_q(char *args) {
|
||||||
set_nemu_state(NEMU_END, 0, 0);
|
set_nemu_state(NEMU_END, 0, 0);
|
||||||
return -1;
|
return -1;
|
||||||
|
5
nemu/tests/Makefile
Normal file
5
nemu/tests/Makefile
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
CC = gcc
|
||||||
|
CFLAGS = -Og -std=c99 -Wall -Werror -D__TEST__
|
||||||
|
|
||||||
|
test_sdb_expr:
|
||||||
|
$(CC) $(CFLAGS) -o $@ $@.c
|
187
nemu/tests/test_sdb_expr.c
Normal file
187
nemu/tests/test_sdb_expr.c
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define panic(fmt, ...) printf(fmt, ## __VA_ARGS__)
|
||||||
|
#define Log(fmt, ...) printf(fmt, ## __VA_ARGS__)
|
||||||
|
|
||||||
|
#define ARRLEN(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||||
|
typedef uint32_t word_t;
|
||||||
|
|
||||||
|
/* We use the POSIX regex functions to process regular expressions.
|
||||||
|
* Type 'man regex' for more information about POSIX regex functions.
|
||||||
|
*/
|
||||||
|
#include <regex.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TK_NOTYPE = 256, TK_EQ,
|
||||||
|
TK_DEC,
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
{"-", '-'}, // sub
|
||||||
|
{"\\*", '*'}, // mul
|
||||||
|
{"/", '/'}, // div
|
||||||
|
{"\\(", '('}, // (
|
||||||
|
{"\\)", ')'}, // )
|
||||||
|
{"[0-9]+", TK_DEC}, // dec number
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NR_REGEX ARRLEN(rules)
|
||||||
|
|
||||||
|
static regex_t re[NR_REGEX] = {};
|
||||||
|
|
||||||
|
/* Rules are used for many times.
|
||||||
|
* Therefore we compile them only once before any usage.
|
||||||
|
*/
|
||||||
|
void init_regex() {
|
||||||
|
int i;
|
||||||
|
char error_msg[128];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
for (i = 0; i < NR_REGEX; i ++) {
|
||||||
|
ret = regcomp(&re[i], rules[i].regex, REG_EXTENDED);
|
||||||
|
if (ret != 0) {
|
||||||
|
regerror(ret, &re[i], error_msg, 128);
|
||||||
|
panic("regex compilation failed: %s\n%s", error_msg, rules[i].regex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct token {
|
||||||
|
int type;
|
||||||
|
char str[32];
|
||||||
|
} Token;
|
||||||
|
|
||||||
|
static Token tokens[32] __attribute__((used)) = {};
|
||||||
|
static int nr_token __attribute__((used)) = 0;
|
||||||
|
|
||||||
|
static bool make_token(char *e) {
|
||||||
|
int position = 0;
|
||||||
|
int i;
|
||||||
|
regmatch_t pmatch;
|
||||||
|
|
||||||
|
nr_token = 0;
|
||||||
|
|
||||||
|
while (e[position] != '\0') {
|
||||||
|
/* Try all rules one by one. */
|
||||||
|
for (i = 0; i < NR_REGEX; i ++) {
|
||||||
|
if (regexec(&re[i], e + position, 1, &pmatch, 0) == 0 && pmatch.rm_so == 0) {
|
||||||
|
char *substr_start = e + position;
|
||||||
|
int substr_len = pmatch.rm_eo;
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
tokens[nr_token].type = rules[i].token_type;
|
||||||
|
switch (rules[i].token_type) {
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
case '*':
|
||||||
|
case '/':
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
break;
|
||||||
|
case TK_DEC:
|
||||||
|
if (substr_len + 1 > sizeof(((Token*)0)->str)) {
|
||||||
|
printf("token string is too long");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
strncpy(tokens[nr_token].str, substr_start, substr_len);
|
||||||
|
tokens[nr_token].str[substr_len] = '\0';
|
||||||
|
break;
|
||||||
|
case TK_EQ:
|
||||||
|
case TK_NOTYPE:
|
||||||
|
break;
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
nr_token ++;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == NR_REGEX) {
|
||||||
|
printf("no match at position %d\n%s\n%*.s^\n", position, e, position, "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check_parentheses(size_t p, size_t q) {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
word_t eval(size_t p, size_t q) {
|
||||||
|
if (p > q) {
|
||||||
|
/* Bad expression */
|
||||||
|
panic("bad expression");
|
||||||
|
}
|
||||||
|
else if (p == q) {
|
||||||
|
/* Single token.
|
||||||
|
* For now this token should be a number.
|
||||||
|
* Return the value of the number.
|
||||||
|
*/
|
||||||
|
return atoi(tokens[p].str);
|
||||||
|
}
|
||||||
|
else if (check_parentheses(p, q) == true) {
|
||||||
|
/* The expression is surrounded by a matched pair of parentheses.
|
||||||
|
* If that is the case, just throw away the parentheses.
|
||||||
|
*/
|
||||||
|
return eval(p + 1, q - 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* We should do more things here. */
|
||||||
|
return eval(p, p) + eval(p + 1, q);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
word_t expr(char *e, bool *success) {
|
||||||
|
if (!make_token(e)) {
|
||||||
|
*success = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Insert codes to evaluate the expression. */
|
||||||
|
// TODO();
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
init_regex();
|
||||||
|
|
||||||
|
make_token("1+2");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user