pa1.2: use flex and bason to implement expr parser

This commit is contained in:
xinyangli 2024-01-12 22:16:35 +08:00
parent 69264e69c6
commit 9cca9de2a8
No known key found for this signature in database
11 changed files with 297 additions and 29 deletions

1
nemu/src/isa/riscv64 Symbolic link
View file

@ -0,0 +1 @@
riscv32

2
nemu/src/monitor/sdb/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
addrexp_lex.h
addrexp.h

View file

@ -0,0 +1,13 @@
%{
#include <addrexp.h>
%}
%option noyywrap
%%
0[xX][0-9a-fA-F]+ { yylval = strtol(yytext, NULL, 16); return HEX_NUMBER; }
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
[+\-*/()] { return *yytext; }
[ \t] { }
. { printf("Unexpected character: %s\n", yytext); }
%%

View file

@ -0,0 +1,36 @@
%{
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
extern int yylex(void);
void yyerror(uint32_t *result, const char *s) {
fprintf(stderr, "Error: %s\n", s);
}
%}
%token NUMBER HEX_NUMBER
%start input
%define api.value.type { uint32_t }
%parse-param { uint32_t *result }
%left '+' '-'
%left '*' '/'
%%
input
: expression { *result = $1; }
;
expression
: expression '+' expression { $$ = $1 + $3; }
| expression '-' expression { $$ = $1 - $3; }
| expression '*' expression { $$ = $1 * $3; }
| expression '/' expression { $$ = $1 / $3; }
| '-' number { $$ = -$2; }
| '(' expression ')' { $$ = $2; }
| number { $$ = $1; }
number
: NUMBER
| HEX_NUMBER
%%

View file

@ -21,24 +21,18 @@
#include <regex.h>
enum {
TK_NOTYPE = 256, TK_EQ,
/* TODO: Add more token types */
TK_NOTYPE = 256, TK_EQ, TK_NUMBER,
LEX_GROUP_OPERATOR, LEX_GROUP_DIGIT
};
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
{"[ \t]+", TK_NOTYPE},
{"==", TK_EQ},
{"[0-9]+", LEX_GROUP_DIGIT},
{"[\\+-*/()", LEX_GROUP_OPERATOR},
};
#define NR_REGEX ARRLEN(rules)
@ -95,6 +89,16 @@ static bool make_token(char *e) {
*/
switch (rules[i].token_type) {
case LEX_GROUP_OPERATOR:
tokens[nr_token].type = *substr_start;
tokens[nr_token].str[0] = '\0';
nr_token++;
break;
case LEX_GROUP_DIGIT:
tokens[nr_token].type = TK_NUMBER;
nr_token++;
break;
case TK_NOTYPE: break;
default: TODO();
}

View file

@ -0,0 +1,3 @@
SRCS-y += src/monitor/sdb/addrexp.tag.c src/monitor/sdb/addrexp.yy.c
INC_PATH += src/monitor/sdb
LFLAGS += -DYY_NO_UNPUT -DYY_NO_INPUT

View file

@ -23,6 +23,8 @@
#include <readline/history.h>
#include <readline/readline.h>
#include <stdint.h>
#include <addrexp.h>
#include <addrexp_lex.h>
static int is_batch_mode = false;
@ -107,7 +109,7 @@ static word_t parse_uint(const char *arg, bool *success) {
char *endptr;
uintmax_t n = strtoumax(arg, &endptr, base);
if (errno == ERANGE || n > WORD_T_MAX) {
printf("%s is exceed the limit of uint\n", arg);
printf("%s exceed the limit of uint\n", arg);
*success = false;
return 0;
} else if (arg == endptr) {
@ -129,10 +131,14 @@ static paddr_t parse_expr(const char *arg, bool *success) {
*success = false;
return 0;
} else {
bool res = false;
// bool res = false;
// FIXME: We cannot use `parse_uint` here, it accept `-1234` as input
paddr_t addr = parse_uint(arg, &res);
*success = res;
// paddr_t addr = parse_uint(arg, &res);
// *success = res;
paddr_t addr;
yy_scan_string(arg);
*success = !yyparse(&addr);
yylex_destroy();
return addr;
}
}
@ -199,7 +205,7 @@ static int cmd_x(char *args) {
return 0;
wrong_usage:
printf("Invalid argument for command si: %s\n", args);
printf("Invalid argument for command x: %s\n", args);
printf("Usage: x [N: uint] [EXPR: <expr>]\n");
return 0;
}
@ -324,8 +330,8 @@ void sdb_mainloop() {
}
void init_sdb() {
/* Compile the regular expressions. */
init_regex();
// /* Compile the regular expressions. */
// init_regex();
/* Initialize the watchpoint pool. */
init_wp_pool();