Commit 09da92f1 authored by Seblu's avatar Seblu

travail renaison

parent 1b8af76d
......@@ -5,7 +5,7 @@ input: list '\n'
list: and_or ((';'|'&') and_or)* ['&'|';']
and_or: pipeline (('&&'|'||') ('\n')* pipeline)*
and_or: pipeline (('&&'|'||') ('\n')* pipeline)*
pipeline: ['!'] command ('|' ('\n')* command)*
......@@ -58,7 +58,7 @@ else_clause: 'else' compound_list
do_group: 'do' compound_list 'done'
case_clause: pattern (';;' (\n)* pattern)* [;;]
case_clause: case_item (';;' (\n)* case_item)* [;;]
pattern: ['('] WORD ('|' WORD)* ')' ( ('\n')* | compound_list )
case_item: ['('] WORD ('|' WORD)* ')' ( ('\n')* | compound_list )
......@@ -5,8 +5,20 @@ bin_PROGRAMS=42sh
42sh_SOURCES= ast/ast.h \
ast/ast_and.c \
ast/ast_bang.c \
ast/ast_case.c \
ast/ast_destruct.c \
ast/ast_for.c \
ast/ast_funcdec.c \
ast/ast_if.c \
ast/ast_or.c \
ast/ast_pipe.c \
ast/ast_sep.c \
ast/ast_sepand.c \
ast/ast_subshell.c \
ast/ast_until.c \
ast/ast_while.c \
common/common.h \
common/mem.h \
common/strmerge.c \
......
This diff is collapsed.
/*
** ast_and.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Thu Aug 3 03:03:31 2006 Seblu
*/
#include "../common/mem.h"
#include "ast.h"
ts_ast_node *ast_create_and(ts_ast_node *lhs, ts_ast_node *rhs)
{
ts_ast_node *node;
secmalloc(node, sizeof (ts_ast_node));
node->type = T_AND;
node->body.child_and.lhs = lhs;
node->body.child_and.rhs = rhs;
return node;
}
void ast_destruct_and(ts_ast_node *node)
{
if (node->type != T_AND) {
ast_destruct(node);
return;
}
ast_destruct(node->body.child_and.lhs);
ast_destruct(node->body.child_and.rhs);
free(node);
}
/*
** ast_bang.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Fri Aug 18 15:57:05 2006 Seblu
*/
#include "../common/mem.h"
#include "ast.h"
ts_ast_node *ast_create_bang(ts_ast_node *child)
{
ts_ast_node *node;
secmalloc(node, sizeof (ts_ast_node));
node->type = T_BANG;
node->body.child_bang.lhs = child;
node->body.child_bang.rhs = NULL;
return node;
}
void ast_destruct_bang(ts_ast_node *node)
{
if (node->type != T_BANG) {
ast_destruct(node);
return;
}
ast_destruct(node->body.child_bang.lhs);
free(node);
}
/*
** ast_for.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Fri Aug 18 15:55:00 2006 Seblu
*/
#include "../common/mem.h"
#include "ast.h"
ts_ast_node *ast_case_create(char *word)
{
ts_ast_node *node;
secmalloc(node, sizeof (ts_ast_node));
node->type = T_CASE;
node->body.child_case.word = word;
node->body.child_case.items = NULL;
return node;
}
void ast_case_add_item(ts_ast_node *node,
char **pattern,
ts_ast_node *list)
{
/* ts_case_item *item; */
/* secmalloc(item, sizeof (ts_case_item)); */
/* item->pattern = pattern; */
/* item->list = list; */
node = node;
pattern = pattern;
list = list;
/* for (ts_case_item **this = &node->items; */
/* *this; */
/* *this = (*this)->next) */
/* ; //do nothing */
/* *this = item; */
}
void ast_case_destruct(ts_ast_node *node)
{
node = node;
/* ts_case_item *this, *buf; */
/* if (node->type != T_CASE) { */
/* ast_destruct(node); */
/* return; */
/* } */
/* free(node->body.child_case.word); */
/* /\* for (ts_case_item *this = node->items; *\/ */
/* /\* this; *\/ */
/* /\* this = this->next) *\/ */
/* /\* for (register int i = 0; node->body.child_case.items[i]; ++i) { *\/ */
/* //fixme for multiple pattern */
/* free(node->body.child_case.items[i].pattern); */
/* ast_destruct(node->body.child_case.items[i].list); */
/* } */
/* free(node->body.child_case.items); */
/* free(node); */
}
/*
** ast_for.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Thu Aug 3 03:03:31 2006 Seblu
*/
#include "../common/mem.h"
#include "ast.h"
ts_ast_node *ast_create_for(char *varname,
char **values,
ts_ast_node *exec)
{
ts_ast_node *node;
secmalloc(node, sizeof (ts_ast_node));
node->type = T_FOR;
node->body.child_for.varname = varname;
node->body.child_for.values = values;
node->body.child_for.exec = exec;
return node;
}
void ast_destruct_for(ts_ast_node *node)
{
if (node->type != T_FOR) {
ast_destruct(node);
return;
}
free(node->body.child_for.varname);
for (register int i = 0; node->body.child_for.values[i]; ++i)
free(node->body.child_for.values[i]);
free(node->body.child_for.values);
ast_destruct(node->body.child_for.exec);
free(node);
}
/*
** ast_funcdec.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Fri Aug 18 15:55:42 2006 Seblu
*/
#include "../common/mem.h"
#include "ast.h"
ts_ast_node *ast_create_funcdec(char *name, ts_ast_node *body)
{
ts_ast_node *node;
secmalloc(node, sizeof (ts_ast_node));
node->type = T_FUNCDEC;
node->body.child_funcdec.name = name;
node->body.child_funcdec.body = body;
return node;
}
void ast_destruct_funcdec(ts_ast_node *node)
{
if (node->type != T_FUNCDEC) {
ast_destruct(node);
return;
}
free(node->body.child_funcdec.name);
ast_destruct(node->body.child_funcdec.body);
free(node);
}
/*
** ast_if.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Thu Aug 3 03:03:31 2006 Seblu
*/
#include "../common/mem.h"
#include "ast.h"
ts_ast_node *ast_create_if(ts_ast_node *cond,
ts_ast_node *cond_true,
ts_ast_node *cond_false)
{
ts_ast_node *node;
secmalloc(node, sizeof (ts_ast_node));
node->type = T_IF;
node->body.child_if.cond = cond;
node->body.child_if.cond_true = cond_true;
node->body.child_if.cond_false = cond_false;
return node;
}
void ast_destruct_if(ts_ast_node *node)
{
if (node->type != T_IF) {
ast_destruct(node);
return;
}
ast_destruct(node->body.child_if.cond);
ast_destruct(node->body.child_if.cond_true);
ast_destruct(node->body.child_if.cond_false);
free(node);
}
/*
** ast_or.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Thu Aug 3 03:03:31 2006 Seblu
*/
#include "../common/mem.h"
#include "ast.h"
ts_ast_node *ast_create_or(ts_ast_node *lhs, ts_ast_node *rhs)
{
ts_ast_node *node;
secmalloc(node, sizeof (ts_ast_node));
node->type = T_OR;
node->body.child_or.lhs = lhs;
node->body.child_or.rhs = rhs;
return node;
}
void ast_destruct_or(ts_ast_node *node)
{
if (node->type != T_OR) {
ast_destruct(node);
return;
}
ast_destruct(node->body.child_or.lhs);
ast_destruct(node->body.child_or.rhs);
free(node);
}
/*
** ast_pipe.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Thu Aug 3 03:03:31 2006 Seblu
*/
#include "../common/mem.h"
#include "ast.h"
ts_ast_node *ast_create_pipe(ts_ast_node *lhs, ts_ast_node *rhs)
{
ts_ast_node *node;
secmalloc(node, sizeof (ts_ast_node));
node->type = T_PIPE;
node->body.child_pipe.lhs = lhs;
node->body.child_pipe.rhs = rhs;
return node;
}
void ast_destruct_pipe(ts_ast_node *node)
{
if (node->type != T_PIPE) {
ast_destruct(node);
return;
}
ast_destruct(node->body.child_pipe.lhs);
ast_destruct(node->body.child_pipe.rhs);
free(node);
}
......@@ -2,7 +2,7 @@
** ast_sep.c for 42sh
**
** Made by Seblu
** Login <luttri_s@epita.fr>
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Thu Aug 3 03:03:31 2006 Seblu
......@@ -11,14 +11,6 @@
#include "../common/mem.h"
#include "ast.h"
/*!
** Create a separtor ast node
**
** @param lhs left child
** @param rhs right child
**
** @return the node
*/
ts_ast_node *ast_create_sep(ts_ast_node *lhs, ts_ast_node *rhs)
{
ts_ast_node *node;
......@@ -30,11 +22,6 @@ ts_ast_node *ast_create_sep(ts_ast_node *lhs, ts_ast_node *rhs)
return node;
}
/*!
** Destruct and separator node
**
** @param node node to destroy
*/
void ast_destruct_sep(ts_ast_node *node)
{
if (node->type != T_SEP) {
......
/*
** ast_sepand.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Thu Aug 3 03:03:31 2006 Seblu
*/
#include "../common/mem.h"
#include "ast.h"
ts_ast_node *ast_create_sepand(ts_ast_node *lhs, ts_ast_node *rhs)
{
ts_ast_node *node;
secmalloc(node, sizeof (ts_ast_node));
node->type = T_SEPAND;
node->body.child_sepand.lhs = lhs;
node->body.child_sepand.rhs = rhs;
return node;
}
void ast_destruct_sepand(ts_ast_node *node)
{
if (node->type != T_SEPAND) {
ast_destruct(node);
return;
}
ast_destruct(node->body.child_sepand.lhs);
ast_destruct(node->body.child_sepand.rhs);
free(node);
}
/*
** ast_subshell.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Thu Aug 3 03:03:31 2006 Seblu
*/
#include "../common/mem.h"
#include "ast.h"
ts_ast_node *ast_create_subshell(ts_ast_node *child)
{
ts_ast_node *node;
secmalloc(node, sizeof (ts_ast_node));
node->type = T_SUBSHELL;
node->body.child_subshell.lhs = child;
node->body.child_subshell.rhs = NULL;
return node;
}
void ast_destruct_subshell(ts_ast_node *node)
{
if (node->type != T_SUBSHELL) {
ast_destruct(node);
return;
}
ast_destruct(node->body.child_subshell.lhs);
free(node);
}
/*
** ast_until.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Thu Aug 3 03:03:31 2006 Seblu
*/
#include "../common/mem.h"
#include "ast.h"
ts_ast_node *ast_create_until(ts_ast_node *cond, ts_ast_node *exec)
{
ts_ast_node *node;
secmalloc(node, sizeof (ts_ast_node));
node->type = T_UNTIL;
node->body.child_until.cond = cond;
node->body.child_until.exec = exec;
return node;
}
void ast_destruct_until(ts_ast_node *node)
{
if (node->type != T_UNTIL) {
ast_destruct(node);
return;
}
ast_destruct(node->body.child_until.cond);
ast_destruct(node->body.child_until.exec);
free(node);
}
/*
** ast_while.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Thu Aug 3 03:03:31 2006 Seblu
*/
#include "../common/mem.h"
#include "ast.h"
ts_ast_node *ast_create_while(ts_ast_node *cond, ts_ast_node *exec)
{
ts_ast_node *node;
secmalloc(node, sizeof (ts_ast_node));
node->type = T_WHILE;
node->body.child_while.cond = cond;
node->body.child_while.exec = exec;
return node;
}
void ast_destruct_while(ts_ast_node *node)
{
if (node->type != T_WHILE) {
ast_destruct(node);
return;
}
ast_destruct(node->body.child_while.cond);
ast_destruct(node->body.child_while.exec);
free(node);
}
......@@ -10,6 +10,7 @@
#include <string.h>
#include <stdlib.h>
#include "mem.h"
char *strndup(const char *str, size_t n)
{
......@@ -21,8 +22,7 @@ char *strndup(const char *str, size_t n)
max_length = n;
if ((length = strlen(str)) > max_length)
length = max_length;
if ((new = malloc((length + 1) * sizeof (char))) == NULL)
return NULL;
secmalloc(new, (length + 1) * sizeof (char));
for (i = 0; i < length; ++i)
new[i] = str[i];
new[length] = 0;
......
......@@ -10,11 +10,27 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "parser.h"
#include "../shell/shell.h"
#include "../readline/readline.h"
#include "../common/common.h"
int lexer_reconize(ts_parser *parser);
#define is_quote(c) ((c) == '"' || (c) == '\'' || (c) == '`')
#define is_sep(c) ((c) == ' ' || (c) == '\t' || (c) == '\v')
static int lexer_reconize(ts_parser *parser);
/*!
** Set the current token for a parser
**
** @param p the parser
** @param t new token id
** @param s new token str
**
** @return token string representation
*/
static void set_current_token(ts_parser *p, te_tokenid t, const char *s);
ts_token tokens[] =
{
......@@ -52,69 +68,117 @@ ts_token tokens[] =
void lexer_reset(ts_parser *parser)
{
parser->current.id = TOK_NONE;
parser->current.str = "none";
set_current_token(parser, TOK_BEGIN, "begin");
if (parser->buf != NULL)
free(parser->buf);
parser->buf = NULL;
parser->buf_size = 0;
parser->buf_pos = 0;
parser->buf_size = parser->buf_pos = 0;
}
const char *get_token_string(t_token t)
const char *get_token_string(te_tokenid t)
{
for (register int i = 0; tokens[i].str; ++i)
if (tokens[i].id == t)
return tokens[i].str;
return "unknow";
return NULL;
}
ts_token lexer_get(ts_parser *parser)
{
if (parser->current.id == TOK_NONE)
if (parser->current.id == TOK_BEGIN)
lexer_eat(parser);
return parser->current;
}
void lexer_eat(ts_parser *parser)
{
char *lbuf, *lbuf2;
// return EOF (the last), if file is ended
if (parser->status == PARSE_END)
return;
//if line is void, start readding
if (parser->buf_size == 0) {
if ((parser->buf = readline(get_prompt(TYPE_PS1))) == NULL) {
parser->current.id = TOK_EOF;
set_current_token(parser, TOK_EOF, "eof");
parser->status = PARSE_END;
return;
}
parser->buf_pos = 0;
parser->buf_size = strlen(parser->buf);
}
if (parser->buf_size > 0 &&
parser->buf_size != parser->buf_pos) {
if (lexer_reconize(parser))
return;
}
do
if ((parser->buf = readline(get_prompt(TYPE_PS2))) == NULL) {
parser->current.id = TOK_EOF;
//read line while a token will not be reconized
while (!lexer_reconize(parser)) {
if ((lbuf2 = readline(get_prompt(TYPE_PS2))) == NULL) {
set_current_token(parser, TOK_EOF, "eof");
parser->status = PARSE_END;
return;
}
while (lexer_reconize(parser));
lbuf = parser->buf;
parser->buf = strmerge(2, lbuf, lbuf2);
parser->buf_size = strlen(parser->buf);
free(lbuf), free(lbuf2);
}
}
int lexer_reconize(ts_parser *parser)
static void set_current_token(ts_parser *p, te_tokenid t, const char *s)
{
size_t n;
if (p->current.id == TOK_WORD)
free((char*)p->current.str);
p->current.id = t;
p->current.str = s;
}
static int lexer_reconize(ts_parser *parser)
{
const char *buf = parser->buf;
const size_t buf_size = parser->buf_size;
size_t *buf_pos = &parser->buf_pos;
size_t token_start;
size_t token_pos;
int end_found = 0;
char backed = 0;
char quoted = 0;
//eat spaces (" ",\t, \v)
while (*buf_pos < buf_size &&
is_sep(buf[*buf_pos]))
++*buf_pos;
//check for leading \n token
if (buf[*buf_pos] == '\n') {
++*buf_pos;
set_current_token(parser, TOK_NEWLINE, "\n");
return 1;
}
//cut a token
token_start = token_pos = *buf_pos;
for (; !end_found && token_pos < buf_size; ++token_pos)
if (backed)
backed = 0;
else if (!quoted && (buf[token_pos] == '\n' || is_sep(buf[token_pos])))
{ end_found = 1; break; }
else if (!quoted && is_quote(buf[token_pos]))
quoted = buf[token_pos];
else if (quoted && buf[token_pos] == quoted)
quoted = 0;
else if (!backed && buf[token_pos] == '\\')
backed = 1;
if (!end_found) return 0;
parser->buf_pos = token_pos;
printf("cutted token: '%s'\n",
strndup(buf + token_start, token_pos - token_start));
//check if it's a registered keyword
for (register int i = 0; tokens[i].str; ++i)
if (!strncmp(tokens[i].str, parser->buf + parser->buf_pos,
n = strlen(tokens[i].str))) {
parser->current = tokens[i];
parser->buf_pos += n;
printf("reconized %d\n", tokens[i].id);
if (!strncmp(tokens[i].str, buf + token_start,
token_pos - token_start)) {
set_current_token(parser, tokens[i].id, tokens[i].str);
printf("reconized token: %d (%s)\n", tokens[i].id, tokens[i].str);
return 1;
}
parser->current.id = TOK_NONE;
parser->current.str = "none";
return 0;
//althought this token is a word
set_current_token(parser, TOK_WORD,
strndup(buf + token_start, token_pos - token_start));
printf("reconized token (WORD): %d (%s)\n",
parser->current.id, parser->current.str);
return 1;
}
......@@ -5,7 +5,7 @@
** Login <seblu@epita.fr>
**
** Started on Wed Aug 2 00:56:07 2006 Seblu
** Last update Thu Aug 3 12:30:15 2006 Seblu
** Last update Fri Aug 18 15:46:11 2006 Seblu
*/
#include <stdio.h>
......@@ -61,6 +61,18 @@ ts_ast_node *parse(ts_parser *parser)
{
lexer_reset(parser);
parser->status = PARSE_OK;
//test lexer mode
/* while (1) */
/* { */
/* ts_token tok; */
/* tok = lexer_get(parser); */
/* if (tok.id == TOK_EOF) */