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
|
CFLAGS := -g -O0 -nostdlib
|
||||||
|
|
||||||
UNAME := $(shell uname)
|
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"
|
#include "system/system.h"
|
||||||
|
|
||||||
unsigned char prefix[] = "%> ";
|
unsigned char prefix[] = "%> ";
|
||||||
|
|
||||||
/* Makefile-defined system entry point. */
|
/* Makefile-defined system entry point. */
|
||||||
MSH_ENTRY_POINT {
|
MSH_ENTRY_POINT {
|
||||||
|
msh_lexer *lexer = msh_lexer_new();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int out;
|
int out;
|
||||||
unsigned char *buf = msh_callocate(2048, sizeof(unsigned char));
|
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;
|
int i = 0, n = 0, last = 0;
|
||||||
unsigned long long sz = 0;
|
unsigned long long sz = 0;
|
||||||
|
|
||||||
|
|
@ -16,25 +18,13 @@ MSH_ENTRY_POINT {
|
||||||
while ((out = msh_read_input(buf, &sz, 2048)), !out) {
|
while ((out = msh_read_input(buf, &sz, 2048)), !out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* args */
|
msh_lexer_parse(lexer, buf, sz + 1);
|
||||||
for (i = 0; i < sz; i++) {
|
msh_lexer_execute(lexer);
|
||||||
if (buf[i] == ' ') {
|
|
||||||
*(buf + i) = '\0';
|
|
||||||
if (i != sz - 1) {
|
|
||||||
args[n++] = buf + last;
|
|
||||||
last = i + 1;
|
|
||||||
if (n >= 2048) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
args[n++] = buf + last;
|
// msh_execute(buf, args);
|
||||||
|
|
||||||
msh_execute(buf, args);
|
|
||||||
|
|
||||||
msh_deallocate(buf);
|
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) {
|
int msh_execute(unsigned char *cmd, unsigned char **args) {
|
||||||
SIZE_TYPE fork = (SIZE_TYPE)SYSCALL(fork, 0);
|
SIZE_TYPE fork = (SIZE_TYPE)SYSCALL(fork, 0);
|
||||||
|
// int fork = 0;
|
||||||
if (fork == 0) {
|
if (fork == 0) {
|
||||||
SYSCALL(execve, cmd, args, 0);
|
SYSCALL(execve, cmd, args, 0);
|
||||||
msh_deallocate(args);
|
|
||||||
SYSCALL(kill, fork, SIGKILL);
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
siginfo_t info;
|
siginfo_t info;
|
||||||
SYSCALL(waitid, P_ALL, 0, &info, WEXITED);
|
SYSCALL(waitid, P_ALL, 0, &info, WEXITED);
|
||||||
|
SYSCALL(kill, fork, SIGKILL);
|
||||||
return info.si_code;
|
return info.si_code;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue