more properer lexer
This commit is contained in:
parent
0b96d7c8b3
commit
a6b0234183
5 changed files with 207 additions and 21 deletions
2
Makefile
2
Makefile
|
|
@ -1,4 +1,4 @@
|
|||
SOURCES := src/main.c
|
||||
SOURCES := src/main.c src/util.c src/lexer/lexer.c
|
||||
CFLAGS := -g -O0 -nostdlib
|
||||
|
||||
UNAME := $(shell uname)
|
||||
|
|
|
|||
155
src/lexer/lexer.c
Normal file
155
src/lexer/lexer.c
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
#include "lexer.h"
|
||||
|
||||
#include "../system/system.h"
|
||||
|
||||
struct msh_lexer_t {
|
||||
msh_lexer_item_list *item_list_head;
|
||||
msh_lexer_item_list *item_list_cur;
|
||||
};
|
||||
|
||||
msh_lexer *msh_lexer_new() {
|
||||
msh_lexer *l = msh_allocate(sizeof(struct msh_lexer_t));
|
||||
l->item_list_head = msh_allocate(sizeof(struct msh_lexer_item_list_t));
|
||||
|
||||
l->item_list_head->item = 0;
|
||||
l->item_list_head->next = 0;
|
||||
|
||||
l->item_list_cur = l->item_list_head;
|
||||
|
||||
return l;
|
||||
};
|
||||
|
||||
void msh_lexer_push_item(msh_lexer *lexer, msh_lexer_item_type type,
|
||||
unsigned char *buf, SIZE_TYPE strlen) {
|
||||
int i;
|
||||
msh_lexer_item *item = msh_callocate(sizeof(msh_lexer_item), 1);
|
||||
|
||||
item->str = msh_allocate(strlen * sizeof(unsigned char));
|
||||
for (i = 0; i < strlen; i++) {
|
||||
item->str[i] = buf[i];
|
||||
}
|
||||
item->strlen = strlen;
|
||||
item->type = type;
|
||||
|
||||
lexer->item_list_cur->item = item;
|
||||
lexer->item_list_cur->next = 0;
|
||||
|
||||
lexer->item_list_cur->next = msh_callocate(sizeof(msh_lexer_item_list), 1);
|
||||
lexer->item_list_cur = lexer->item_list_cur->next;
|
||||
};
|
||||
|
||||
void msh_lexer_parse(msh_lexer *lexer, unsigned char *buf, SIZE_TYPE sz) {
|
||||
int i = 0, n = 0, last = 0;
|
||||
|
||||
unsigned char *cur_word_buf = msh_callocate(1024, sizeof(unsigned char));
|
||||
|
||||
for (i = 0; i < sz; i++) {
|
||||
int do_clear = 0;
|
||||
switch (buf[i]) {
|
||||
/*case '#':
|
||||
do_clear = 1;
|
||||
break;
|
||||
case '|':
|
||||
if (i + 1 < sz) {
|
||||
if (buf[i + 1] == '|') {
|
||||
msh_lexer_push_item(lexer, MSH_LEXER_ITEM_TYPE_OP_OR, buf, 2);
|
||||
last = i + 2;
|
||||
} else {
|
||||
msh_lexer_push_item(lexer, MSH_LEXER_ITEM_TYPE_OP_PIPE, buf, 1);
|
||||
last = i + 1;
|
||||
}
|
||||
}
|
||||
do_clear = 1;
|
||||
break;
|
||||
case '&':
|
||||
if (i + 1 < sz) {
|
||||
if (buf[i + 1] == '&') {
|
||||
msh_lexer_push_item(lexer, MSH_LEXER_ITEM_TYPE_OP_AND, buf, 2);
|
||||
last = i + 2;
|
||||
} else {
|
||||
msh_lexer_push_item(lexer, MSH_LEXER_ITEM_TYPE_OP_CONTROL, buf, 1);
|
||||
last = i + 1;
|
||||
}
|
||||
}
|
||||
do_clear = 1;
|
||||
break;
|
||||
case ';':
|
||||
msh_lexer_push_item(lexer, MSH_LEXER_ITEM_TYPE_OP_SEMICOLON, buf, 1);
|
||||
do_clear = 1;
|
||||
break;
|
||||
*/
|
||||
case ' ':
|
||||
case '\n':
|
||||
case '\0':
|
||||
cur_word_buf[n++] = '\0';
|
||||
msh_lexer_push_item(lexer, MSH_LEXER_ITEM_TYPE_WORD, cur_word_buf, n);
|
||||
do_clear = 1;
|
||||
break;
|
||||
default:
|
||||
cur_word_buf[n++] = buf[i];
|
||||
break;
|
||||
}
|
||||
if (do_clear) {
|
||||
msh_deallocate(cur_word_buf);
|
||||
cur_word_buf = msh_callocate(1024, sizeof(unsigned char));
|
||||
n = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void msh_lexer_execute(msh_lexer *lexer) {
|
||||
msh_lexer_item_list *list = lexer->item_list_head;
|
||||
unsigned char *cmd = 0;
|
||||
|
||||
SIZE_TYPE cmd_size = 0;
|
||||
SIZE_TYPE args_size = 0;
|
||||
unsigned char **args = 0;
|
||||
int is_first_arg = 0, n = 0;
|
||||
|
||||
while (list != 0) {
|
||||
if (!list->item) {
|
||||
break;
|
||||
}
|
||||
if (cmd == 0) {
|
||||
cmd = list->item->str;
|
||||
cmd_size = list->item->strlen;
|
||||
} else {
|
||||
args_size += 1;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
list = lexer->item_list_head;
|
||||
args = msh_allocate((args_size + 1) * sizeof(unsigned char *));
|
||||
while (list != 0) {
|
||||
if (!list->item) {
|
||||
break;
|
||||
}
|
||||
args[n++] = list->item->str;
|
||||
list = list->next;
|
||||
}
|
||||
args[n++] = 0;
|
||||
|
||||
msh_execute(cmd, args);
|
||||
|
||||
msh_deallocate(args);
|
||||
|
||||
msh_lexer_flush(lexer);
|
||||
};
|
||||
|
||||
void msh_lexer_flush(msh_lexer *lexer) {
|
||||
msh_lexer_item_list *list = lexer->item_list_head;
|
||||
while (list->item != 0) {
|
||||
msh_deallocate(list->item->str);
|
||||
msh_deallocate(list->item);
|
||||
list = list->next;
|
||||
if (list == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
lexer->item_list_cur = lexer->item_list_head;
|
||||
}
|
||||
|
||||
void msh_lexer_free(msh_lexer *lexer) {
|
||||
msh_deallocate(lexer->item_list_head);
|
||||
msh_deallocate(lexer);
|
||||
};
|
||||
41
src/lexer/lexer.h
Normal file
41
src/lexer/lexer.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef __MSH_LEXER_H
|
||||
#define __MSH_LEXER_H
|
||||
|
||||
#include "../util.h"
|
||||
|
||||
typedef enum msh_lexer_item_type_t {
|
||||
MSH_LEXER_ITEM_TYPE_UNKNOWN = 0,
|
||||
MSH_LEXER_ITEM_TYPE_WORD,
|
||||
MSH_LEXER_ITEM_TYPE_COMMENT, /* # */
|
||||
MSH_LEXER_ITEM_TYPE_OP_OR, /* || */
|
||||
MSH_LEXER_ITEM_TYPE_OP_AND, /* && */
|
||||
MSH_LEXER_ITEM_TYPE_OP_PIPE, /* | */
|
||||
MSH_LEXER_ITEM_TYPE_OP_CONTROL, /* & */
|
||||
MSH_LEXER_ITEM_TYPE_OP_SEMICOLON, /* ; */
|
||||
} msh_lexer_item_type;
|
||||
|
||||
typedef struct msh_lexer_item_t {
|
||||
msh_lexer_item_type type;
|
||||
unsigned char *str;
|
||||
SIZE_TYPE strlen;
|
||||
} msh_lexer_item;
|
||||
|
||||
typedef struct msh_lexer_item_list_t {
|
||||
msh_lexer_item *item;
|
||||
struct msh_lexer_item_list_t *next;
|
||||
} msh_lexer_item_list;
|
||||
|
||||
typedef struct msh_lexer_t msh_lexer;
|
||||
|
||||
msh_lexer *msh_lexer_new();
|
||||
void msh_lexer_parse(msh_lexer *lexer, unsigned char *buf, SIZE_TYPE sz);
|
||||
void msh_lexer_push_item(msh_lexer *lexer, msh_lexer_item_type type,
|
||||
unsigned char *buf, SIZE_TYPE strlen);
|
||||
|
||||
void msh_lexer_flush(msh_lexer *lexer);
|
||||
|
||||
void msh_lexer_execute(msh_lexer *lexer);
|
||||
|
||||
void msh_lexer_free(msh_lexer *lexer);
|
||||
|
||||
#endif
|
||||
26
src/main.c
26
src/main.c
|
|
@ -1,13 +1,15 @@
|
|||
#include "lexer/lexer.h"
|
||||
#include "system/system.h"
|
||||
|
||||
unsigned char prefix[] = "%> ";
|
||||
|
||||
/* Makefile-defined system entry point. */
|
||||
MSH_ENTRY_POINT {
|
||||
msh_lexer *lexer = msh_lexer_new();
|
||||
|
||||
while (1) {
|
||||
int out;
|
||||
unsigned char *buf = msh_callocate(2048, sizeof(unsigned char));
|
||||
unsigned char **args = msh_callocate(2048 * 2, sizeof(unsigned char));
|
||||
int i = 0, n = 0, last = 0;
|
||||
unsigned long long sz = 0;
|
||||
|
||||
|
|
@ -16,25 +18,13 @@ MSH_ENTRY_POINT {
|
|||
while ((out = msh_read_input(buf, &sz, 2048)), !out) {
|
||||
}
|
||||
|
||||
/* args */
|
||||
for (i = 0; i < sz; i++) {
|
||||
if (buf[i] == ' ') {
|
||||
*(buf + i) = '\0';
|
||||
if (i != sz - 1) {
|
||||
args[n++] = buf + last;
|
||||
last = i + 1;
|
||||
if (n >= 2048) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
msh_lexer_parse(lexer, buf, sz + 1);
|
||||
msh_lexer_execute(lexer);
|
||||
|
||||
args[n++] = buf + last;
|
||||
|
||||
msh_execute(buf, args);
|
||||
// msh_execute(buf, args);
|
||||
|
||||
msh_deallocate(buf);
|
||||
msh_deallocate(args);
|
||||
}
|
||||
|
||||
msh_lexer_free(lexer);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,14 +27,14 @@ void msh_write(unsigned char *st, SIZE_TYPE size) {
|
|||
|
||||
int msh_execute(unsigned char *cmd, unsigned char **args) {
|
||||
SIZE_TYPE fork = (SIZE_TYPE)SYSCALL(fork, 0);
|
||||
// int fork = 0;
|
||||
if (fork == 0) {
|
||||
SYSCALL(execve, cmd, args, 0);
|
||||
msh_deallocate(args);
|
||||
SYSCALL(kill, fork, SIGKILL);
|
||||
return 0;
|
||||
} else {
|
||||
siginfo_t info;
|
||||
SYSCALL(waitid, P_ALL, 0, &info, WEXITED);
|
||||
SYSCALL(kill, fork, SIGKILL);
|
||||
return info.si_code;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue