From f923fc3f19d561b92dbb321de646703e2256839e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Luttringer?= Date: Sat, 19 Aug 2006 00:10:58 +0000 Subject: [PATCH] Fin des fonctions de creation et destruction de l'AST correction d'un bug dans basename Ajout des fichiers de l'ast au makefile Le 42sh est maintenant compile en static sous linux Reecriture du lexer facon LL1 (gettoken, lookahead) Separation des tokens en keywords et operators (XSI compliant) --- src/Makefile.am | 1 + src/ast/ast.h | 102 ++++++++++++++++++++++++-------------- src/ast/ast_and.c | 6 +-- src/ast/ast_bang.c | 6 +-- src/ast/ast_case.c | 59 +++++++++++----------- src/ast/ast_for.c | 6 +-- src/ast/ast_funcdec.c | 6 +-- src/ast/ast_if.c | 6 +-- src/ast/ast_or.c | 6 +-- src/ast/ast_pipe.c | 6 +-- src/ast/ast_sep.c | 6 +-- src/ast/ast_sepand.c | 6 +-- src/ast/ast_subshell.c | 6 +-- src/ast/ast_until.c | 6 +-- src/ast/ast_while.c | 6 +-- src/common/basename.c | 6 +-- src/parser/lexer.c | 104 ++++++++++++++++++++++----------------- src/parser/parser.c | 35 ++++++------- src/parser/parser.h | 37 ++++++++------ src/shell/shell.h | 4 +- src/shell/shell_prompt.c | 2 +- 21 files changed, 233 insertions(+), 189 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 859a64c..6c66f2a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,6 +8,7 @@ bin_PROGRAMS=42sh ast/ast_and.c \ ast/ast_bang.c \ ast/ast_case.c \ + ast/ast_cmd.c \ ast/ast_destruct.c \ ast/ast_for.c \ ast/ast_funcdec.c \ diff --git a/src/ast/ast.h b/src/ast/ast.h index 213687c..9b89df3 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -5,7 +5,7 @@ ** Login ** ** Started on Sun Jul 30 04:40:03 2006 Seblu -** Last update Fri Aug 18 15:56:25 2006 Seblu +** Last update Fri Aug 18 22:38:00 2006 Seblu */ #ifndef AST_H_ @@ -16,7 +16,7 @@ # include # include -typedef struct s_ast ts_ast_node; +typedef struct s_ast_node ts_ast_node; /* ** If ast node @@ -45,7 +45,7 @@ typedef struct s_case_item ts_case_item; struct s_case_item { char **pattern; - ts_ast_node *list; + ts_ast_node *exec; ts_case_item *next; }; @@ -86,12 +86,14 @@ typedef enum e_redir_type /* ** Redirection ast node */ -typedef struct s_redir_node +typedef struct s_redir ts_redir; +struct s_redir { te_redir_type type; int fd; - char *string; -} ts_redir_node; + char *word; + ts_redir *next; +}; /* ** Command ast node @@ -99,14 +101,14 @@ typedef struct s_redir_node typedef struct s_cmd_node { char **argv; - ts_redir_node **redirs; + ts_redir *redirs; char **prefix; } ts_cmd_node; /* ** Binary ast node -** Generic type, it's a contener ! -** T_PIPE, T_SEP_* , T_AND, T_OR : binary operator +** Generic node, it's a contener ! +** T_PIPE, T_SEP* , T_AND, T_OR : binary operator ** T_BANG : unary operator but ts_bin_op with right pointer is always NULL */ typedef struct s_bin_node @@ -152,7 +154,7 @@ typedef union u_node_item { ts_if_node child_if; ts_for_node child_for; - ts_case_node child_case; //todo + ts_case_node child_case; ts_while_node child_while; ts_while_node child_until; ts_cmd_node child_cmd; //todo @@ -169,7 +171,7 @@ typedef union u_node_item /* ** Generic ast node type */ -struct s_ast +struct s_ast_node { te_node_type type; tu_node_item body; @@ -192,7 +194,7 @@ void ast_destruct(ts_ast_node *ast); ** ** @return the node */ -ts_ast_node *ast_create_if(ts_ast_node *cond, +ts_ast_node *ast_if_create(ts_ast_node *cond, ts_ast_node *cond_true, ts_ast_node *cond_false); @@ -201,7 +203,7 @@ ts_ast_node *ast_create_if(ts_ast_node *cond, ** ** @param node node to destroy */ -void ast_destruct_if(ts_ast_node *node); +void ast_if_destruct(ts_ast_node *node); /*! ** Create a for ast node @@ -213,8 +215,8 @@ void ast_destruct_if(ts_ast_node *node); ** ** @return the node */ -ts_ast_node *ast_create_for(char *varname, - char **values, +ts_ast_node *ast_for_create(char *varname, + char **values, ts_ast_node *exec); /*! @@ -222,7 +224,35 @@ ts_ast_node *ast_create_for(char *varname, ** ** @param node node to destroy */ -void ast_destruct_for(ts_ast_node *node); +void ast_for_destruct(ts_ast_node *node); + +/*! +** Create a case ast node +** +** @param word reference word +** +** @return the node +*/ +ts_ast_node *ast_case_create(char *word); + +/*! +** Add a case item into a case node. An item is counpound of a set of word +** which match with reference word an case node and the corresponding +** +** @param node node where item will be added +** @param pattern list of word that can match to reference +** @param exec exec corresponding with match +*/ +void ast_case_add_item(ts_ast_node *node, + char **pattern, + ts_ast_node *exec); + +/*! +** Destruct a case ast node +** +** @param node node to destroy +*/ +void ast_case_destruct(ts_ast_node *node); /*! ** Create a while ast node @@ -232,14 +262,14 @@ void ast_destruct_for(ts_ast_node *node); ** ** @return the node */ -ts_ast_node *ast_create_while(ts_ast_node *cond, ts_ast_node *exec); +ts_ast_node *ast_while_create(ts_ast_node *cond, ts_ast_node *exec); /*! ** Destruct a while ast node ** ** @param node node to destroy */ -void ast_destruct_while(ts_ast_node *node); +void ast_while_destruct(ts_ast_node *node); /*! ** Create a until ast node @@ -249,14 +279,14 @@ void ast_destruct_while(ts_ast_node *node); ** ** @return the node */ -ts_ast_node *ast_create_until(ts_ast_node *cond, ts_ast_node *exec); +ts_ast_node *ast_until_create(ts_ast_node *cond, ts_ast_node *exec); /*! ** Destruct a until ast node ** ** @param node node to destroy */ -void ast_destruct_until(ts_ast_node *node); +void ast_until_destruct(ts_ast_node *node); /*! ** Create an and (&&) ast node @@ -266,14 +296,14 @@ void ast_destruct_until(ts_ast_node *node); ** ** @return the node */ -ts_ast_node *ast_create_and(ts_ast_node *lhs, ts_ast_node *rhs); +ts_ast_node *ast_and_create(ts_ast_node *lhs, ts_ast_node *rhs); /*! ** Destruct an and (&&) node ** ** @param node node to destroy */ -void ast_destruct_and(ts_ast_node *node); +void ast_and_destruct(ts_ast_node *node); /*! ** Create an or (||) ast node @@ -283,14 +313,14 @@ void ast_destruct_and(ts_ast_node *node); ** ** @return the node */ -ts_ast_node *ast_create_or(ts_ast_node *lhs, ts_ast_node *rhs); +ts_ast_node *ast_or_create(ts_ast_node *lhs, ts_ast_node *rhs); /*! ** Destruct an or (||) node ** ** @param node node to destroy */ -void ast_destruct_or(ts_ast_node *node); +void ast_or_destruct(ts_ast_node *node); /*! ** Create a subshell ($()) ast node @@ -299,14 +329,14 @@ void ast_destruct_or(ts_ast_node *node); ** ** @return the node */ -ts_ast_node *ast_create_subshell(ts_ast_node *child); +ts_ast_node *ast_subshell_create(ts_ast_node *child); /*! ** Destruct a subshell ($()) node ** ** @param node node to destroy */ -void ast_destruct_subshell(ts_ast_node *node); +void ast_subshell_destruct(ts_ast_node *node); /*! ** Create a funcdec (function declaration) ast node @@ -316,14 +346,14 @@ void ast_destruct_subshell(ts_ast_node *node); ** ** @return the node */ -ts_ast_node *ast_create_funcdec(char *name, ts_ast_node *body); +ts_ast_node *ast_fundec_create(char *name, ts_ast_node *body); /*! ** Destruct a funcdec ast node ** ** @param node node to destroy */ -void ast_destruct_funcdec(ts_ast_node *node); +void ast_funcdec_destruct(ts_ast_node *node); /*! ** Create a bang (!) ast node @@ -332,14 +362,14 @@ void ast_destruct_funcdec(ts_ast_node *node); ** ** @return the node */ -ts_ast_node *ast_create_bang(ts_ast_node *child); +ts_ast_node *ast_bang_create(ts_ast_node *child); /*! ** Destruct a bang (!) node ** ** @param node node to destroy */ -void ast_destruct_bang(ts_ast_node *node); +void ast_bang_destruct(ts_ast_node *node); /*! ** Create a pipe (|) ast node @@ -349,14 +379,14 @@ void ast_destruct_bang(ts_ast_node *node); ** ** @return the node */ -ts_ast_node *ast_create_pipe(ts_ast_node *lhs, ts_ast_node *rhs); +ts_ast_node *ast_pipe_create(ts_ast_node *lhs, ts_ast_node *rhs); /*! ** Destruct a pipe (|) node ** ** @param node node to destroy */ -void ast_destruct_pipe(ts_ast_node *node); +void ast_pipe_destruct(ts_ast_node *node); /*! ** Create a separtor (;) ast node @@ -366,14 +396,14 @@ void ast_destruct_pipe(ts_ast_node *node); ** ** @return the node */ -ts_ast_node *ast_create_sep(ts_ast_node *lhs, ts_ast_node *rhs); +ts_ast_node *ast_sep_create(ts_ast_node *lhs, ts_ast_node *rhs); /*! ** Destruct a sep (;) node ** ** @param node node to destroy */ -void ast_destruct_sep(ts_ast_node *node); +void ast_sep_destruct(ts_ast_node *node); /*! ** Create a sepand (&) ast node @@ -383,13 +413,13 @@ void ast_destruct_sep(ts_ast_node *node); ** ** @return the node */ -ts_ast_node *ast_create_sepand(ts_ast_node *lhs, ts_ast_node *rhs); +ts_ast_node *ast_sepand_create(ts_ast_node *lhs, ts_ast_node *rhs); /*! ** Destruct a sepand (&) node ** ** @param node node to destroy */ -void ast_destruct_sep(ts_ast_node *node); +void ast_sepand_destruct(ts_ast_node *node); #endif /* !AST_H_ */ diff --git a/src/ast/ast_and.c b/src/ast/ast_and.c index f63478c..46058ae 100644 --- a/src/ast/ast_and.c +++ b/src/ast/ast_and.c @@ -5,13 +5,13 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Thu Aug 3 03:03:31 2006 Seblu +** Last update Fri Aug 18 20:40:35 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 *ast_and_create(ts_ast_node *lhs, ts_ast_node *rhs) { ts_ast_node *node; @@ -22,7 +22,7 @@ ts_ast_node *ast_create_and(ts_ast_node *lhs, ts_ast_node *rhs) return node; } -void ast_destruct_and(ts_ast_node *node) +void ast_and_destruct(ts_ast_node *node) { if (node->type != T_AND) { ast_destruct(node); diff --git a/src/ast/ast_bang.c b/src/ast/ast_bang.c index dc46e78..7ea0606 100644 --- a/src/ast/ast_bang.c +++ b/src/ast/ast_bang.c @@ -5,13 +5,13 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Fri Aug 18 15:57:05 2006 Seblu +** Last update Fri Aug 18 20:43:52 2006 Seblu */ #include "../common/mem.h" #include "ast.h" -ts_ast_node *ast_create_bang(ts_ast_node *child) +ts_ast_node *ast_bang_create(ts_ast_node *child) { ts_ast_node *node; @@ -22,7 +22,7 @@ ts_ast_node *ast_create_bang(ts_ast_node *child) return node; } -void ast_destruct_bang(ts_ast_node *node) +void ast_bang_destruct(ts_ast_node *node) { if (node->type != T_BANG) { ast_destruct(node); diff --git a/src/ast/ast_case.c b/src/ast/ast_case.c index 7aae77a..c7f6ed8 100644 --- a/src/ast/ast_case.c +++ b/src/ast/ast_case.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Fri Aug 18 15:55:00 2006 Seblu +** Last update Fri Aug 18 22:32:35 2006 Seblu */ #include "../common/mem.h" @@ -24,41 +24,38 @@ ts_ast_node *ast_case_create(char *word) void ast_case_add_item(ts_ast_node *node, char **pattern, - ts_ast_node *list) + ts_ast_node *exec) { -/* ts_case_item *item; */ + ts_case_item *item; + ts_case_item **this; -/* 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; */ + if (node->type != T_CASE) + return; + secmalloc(item, sizeof (ts_case_item)); + item->pattern = pattern; + item->exec = exec; + item->next = NULL; + for (this = &node->body.child_case.items; *this; *this = (*this)->next) + ; //do nothing + *this = item; } void ast_case_destruct(ts_ast_node *node) { - node = node; -/* ts_case_item *this, *buf; */ + 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); */ + if (node->type != T_CASE) { + ast_destruct(node); + return; + } + free(node->body.child_case.word); + for (this = node->body.child_case.items; this; this = buf) { + for (register int i = 0; this->pattern[i]; ++i) + free(this->pattern[i]); + free(this->pattern); + ast_destruct(this->exec); + buf = this->next; + free(this); + } + free(node); } diff --git a/src/ast/ast_for.c b/src/ast/ast_for.c index 0dedb2a..dada22f 100644 --- a/src/ast/ast_for.c +++ b/src/ast/ast_for.c @@ -5,13 +5,13 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Thu Aug 3 03:03:31 2006 Seblu +** Last update Fri Aug 18 20:38:08 2006 Seblu */ #include "../common/mem.h" #include "ast.h" -ts_ast_node *ast_create_for(char *varname, +ts_ast_node *ast_for_create(char *varname, char **values, ts_ast_node *exec) { @@ -25,7 +25,7 @@ ts_ast_node *ast_create_for(char *varname, return node; } -void ast_destruct_for(ts_ast_node *node) +void ast_for_destruct(ts_ast_node *node) { if (node->type != T_FOR) { ast_destruct(node); diff --git a/src/ast/ast_funcdec.c b/src/ast/ast_funcdec.c index f60e929..21d548d 100644 --- a/src/ast/ast_funcdec.c +++ b/src/ast/ast_funcdec.c @@ -5,13 +5,13 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Fri Aug 18 15:55:42 2006 Seblu +** Last update Fri Aug 18 20:43:15 2006 Seblu */ #include "../common/mem.h" #include "ast.h" -ts_ast_node *ast_create_funcdec(char *name, ts_ast_node *body) +ts_ast_node *ast_funcdec_create(char *name, ts_ast_node *body) { ts_ast_node *node; @@ -22,7 +22,7 @@ ts_ast_node *ast_create_funcdec(char *name, ts_ast_node *body) return node; } -void ast_destruct_funcdec(ts_ast_node *node) +void ast_funcdec_destruct(ts_ast_node *node) { if (node->type != T_FUNCDEC) { ast_destruct(node); diff --git a/src/ast/ast_if.c b/src/ast/ast_if.c index 4ebb56c..ba16569 100644 --- a/src/ast/ast_if.c +++ b/src/ast/ast_if.c @@ -5,13 +5,13 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Thu Aug 3 03:03:31 2006 Seblu +** Last update Fri Aug 18 20:37:47 2006 Seblu */ #include "../common/mem.h" #include "ast.h" -ts_ast_node *ast_create_if(ts_ast_node *cond, +ts_ast_node *ast_if_create(ts_ast_node *cond, ts_ast_node *cond_true, ts_ast_node *cond_false) { @@ -25,7 +25,7 @@ ts_ast_node *ast_create_if(ts_ast_node *cond, return node; } -void ast_destruct_if(ts_ast_node *node) +void ast_if_destruct(ts_ast_node *node) { if (node->type != T_IF) { ast_destruct(node); diff --git a/src/ast/ast_or.c b/src/ast/ast_or.c index e4e15ff..71d2ec5 100644 --- a/src/ast/ast_or.c +++ b/src/ast/ast_or.c @@ -5,13 +5,13 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Thu Aug 3 03:03:31 2006 Seblu +** Last update Fri Aug 18 20:40:50 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 *ast_or_create(ts_ast_node *lhs, ts_ast_node *rhs) { ts_ast_node *node; @@ -22,7 +22,7 @@ ts_ast_node *ast_create_or(ts_ast_node *lhs, ts_ast_node *rhs) return node; } -void ast_destruct_or(ts_ast_node *node) +void ast_or_destruct(ts_ast_node *node) { if (node->type != T_OR) { ast_destruct(node); diff --git a/src/ast/ast_pipe.c b/src/ast/ast_pipe.c index 7c895f9..28ddc7a 100644 --- a/src/ast/ast_pipe.c +++ b/src/ast/ast_pipe.c @@ -5,13 +5,13 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Thu Aug 3 03:03:31 2006 Seblu +** Last update Fri Aug 18 20:44:37 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 *ast_pipe_create(ts_ast_node *lhs, ts_ast_node *rhs) { ts_ast_node *node; @@ -22,7 +22,7 @@ ts_ast_node *ast_create_pipe(ts_ast_node *lhs, ts_ast_node *rhs) return node; } -void ast_destruct_pipe(ts_ast_node *node) +void ast_pipe_destruct(ts_ast_node *node) { if (node->type != T_PIPE) { ast_destruct(node); diff --git a/src/ast/ast_sep.c b/src/ast/ast_sep.c index 2428eab..6215e52 100644 --- a/src/ast/ast_sep.c +++ b/src/ast/ast_sep.c @@ -5,13 +5,13 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Thu Aug 3 03:03:31 2006 Seblu +** Last update Fri Aug 18 20:48:47 2006 Seblu */ #include "../common/mem.h" #include "ast.h" -ts_ast_node *ast_create_sep(ts_ast_node *lhs, ts_ast_node *rhs) +ts_ast_node *ast_sep_create(ts_ast_node *lhs, ts_ast_node *rhs) { ts_ast_node *node; @@ -22,7 +22,7 @@ ts_ast_node *ast_create_sep(ts_ast_node *lhs, ts_ast_node *rhs) return node; } -void ast_destruct_sep(ts_ast_node *node) +void ast_sep_destruct(ts_ast_node *node) { if (node->type != T_SEP) { ast_destruct(node); diff --git a/src/ast/ast_sepand.c b/src/ast/ast_sepand.c index 8d9a774..41b1030 100644 --- a/src/ast/ast_sepand.c +++ b/src/ast/ast_sepand.c @@ -5,13 +5,13 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Thu Aug 3 03:03:31 2006 Seblu +** Last update Fri Aug 18 20:49:02 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 *ast_sepand_create(ts_ast_node *lhs, ts_ast_node *rhs) { ts_ast_node *node; @@ -22,7 +22,7 @@ ts_ast_node *ast_create_sepand(ts_ast_node *lhs, ts_ast_node *rhs) return node; } -void ast_destruct_sepand(ts_ast_node *node) +void ast_sepand_destruct(ts_ast_node *node) { if (node->type != T_SEPAND) { ast_destruct(node); diff --git a/src/ast/ast_subshell.c b/src/ast/ast_subshell.c index dc4ef11..5679df7 100644 --- a/src/ast/ast_subshell.c +++ b/src/ast/ast_subshell.c @@ -5,13 +5,13 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Thu Aug 3 03:03:31 2006 Seblu +** Last update Fri Aug 18 20:42:28 2006 Seblu */ #include "../common/mem.h" #include "ast.h" -ts_ast_node *ast_create_subshell(ts_ast_node *child) +ts_ast_node *ast_subshell_create(ts_ast_node *child) { ts_ast_node *node; @@ -22,7 +22,7 @@ ts_ast_node *ast_create_subshell(ts_ast_node *child) return node; } -void ast_destruct_subshell(ts_ast_node *node) +void ast_subshell_destruct(ts_ast_node *node) { if (node->type != T_SUBSHELL) { ast_destruct(node); diff --git a/src/ast/ast_until.c b/src/ast/ast_until.c index afcc291..7d35533 100644 --- a/src/ast/ast_until.c +++ b/src/ast/ast_until.c @@ -5,13 +5,13 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Thu Aug 3 03:03:31 2006 Seblu +** Last update Fri Aug 18 20:39:25 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 *ast_until_create(ts_ast_node *cond, ts_ast_node *exec) { ts_ast_node *node; @@ -22,7 +22,7 @@ ts_ast_node *ast_create_until(ts_ast_node *cond, ts_ast_node *exec) return node; } -void ast_destruct_until(ts_ast_node *node) +void ast_until_destruct(ts_ast_node *node) { if (node->type != T_UNTIL) { ast_destruct(node); diff --git a/src/ast/ast_while.c b/src/ast/ast_while.c index 7ab25fa..0983327 100644 --- a/src/ast/ast_while.c +++ b/src/ast/ast_while.c @@ -5,13 +5,13 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Thu Aug 3 03:03:31 2006 Seblu +** Last update Fri Aug 18 20:39:02 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 *ast_while_create(ts_ast_node *cond, ts_ast_node *exec) { ts_ast_node *node; @@ -22,7 +22,7 @@ ts_ast_node *ast_create_while(ts_ast_node *cond, ts_ast_node *exec) return node; } -void ast_destruct_while(ts_ast_node *node) +void ast_while_destruct(ts_ast_node *node) { if (node->type != T_WHILE) { ast_destruct(node); diff --git a/src/common/basename.c b/src/common/basename.c index 0c7cd2d..a669d83 100644 --- a/src/common/basename.c +++ b/src/common/basename.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Thu Aug 3 05:29:46 2006 Seblu -** Last update Thu Aug 3 10:36:04 2006 Seblu +** Last update Sat Aug 19 01:57:49 2006 Seblu */ #include @@ -18,7 +18,7 @@ char *basename(const char *path) if ((len = strlen(path)) == 0) return strdup(""); - //search first char without '/' from end string + //search first char WITHOUT '/' start at end string for (i = len - 1; ; --i) { if (path[i] != '/') { end = i; @@ -38,5 +38,5 @@ char *basename(const char *path) if (i == 0) break; } - return strndup(path + start, (start >= end) ? 0 : end - start); + return strndup(path + start, (start > end) ? 0 : end - start + 1); } diff --git a/src/parser/lexer.c b/src/parser/lexer.c index c032b31..4cf6542 100644 --- a/src/parser/lexer.c +++ b/src/parser/lexer.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Sun Jul 30 04:36:53 2006 Seblu -** Last update Thu Aug 3 12:39:34 2006 Seblu +** Last update Sat Aug 19 01:41:32 2006 Seblu */ #include @@ -21,18 +21,13 @@ 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); +static void lexer_eat(ts_parser *lex); + +static ts_token token_create(te_tokenid id, const char *string); -ts_token tokens[] = +static void token_set(ts_token *token, te_tokenid id, const char *s); + +ts_token operators[] = { {TOK_AND, "&&"}, {TOK_OR, "||"}, @@ -44,6 +39,14 @@ ts_token tokens[] = {TOK_LESSGREAT, "<>"}, {TOK_DLESSDASH, "<<-"}, {TOK_CLOBBER, ">|"}, + {TOK_SEP, ";"}, + {TOK_SEPAND, "&"}, + {TOK_NEWLINE, "\n"}, + {0, NULL} + }; + +ts_token keywords[] = + { {TOK_IF, "if"}, {TOK_THEN, "then"}, {TOK_ELSE, "else"}, @@ -60,34 +63,52 @@ ts_token tokens[] = {TOK_LBRACE, "{"}, {TOK_RBRACE, "}"}, {TOK_BANG, "!"}, - {TOK_SEP, ";"}, - {TOK_SEPAND, "&"}, - {TOK_NEWLINE, "\n"}, - {0,0} + {0, NULL} }; void lexer_reset(ts_parser *parser) { - set_current_token(parser, TOK_BEGIN, "begin"); - if (parser->buf != NULL) - free(parser->buf); + token_set(&parser->token, TOK_NONE, NULL); + if (parser->buf) free(parser->buf); parser->buf = NULL; parser->buf_size = parser->buf_pos = 0; } -const char *get_token_string(te_tokenid t) +ts_token lexer_lookahead(ts_parser *parser) { - for (register int i = 0; tokens[i].str; ++i) - if (tokens[i].id == t) - return tokens[i].str; - return NULL; + if (parser->status != PARSE_OK) + return token_create(TOK_ERR, NULL); + if (parser->token.id == TOK_NONE) + lexer_eat(parser); + return parser->token; } -ts_token lexer_get(ts_parser *parser) +ts_token lexer_gettoken(ts_parser *parser) { - if (parser->current.id == TOK_BEGIN) + ts_token buf; + + if (parser->status != PARSE_OK) + return token_create(TOK_ERR, NULL); + if (parser->token.id == TOK_NONE) lexer_eat(parser); - return parser->current; + buf = parser->token; + parser->token = token_create(TOK_NONE, NULL); + return buf; +} + +static ts_token token_create(te_tokenid id, const char *string) +{ + ts_token new = { id, string }; + + return new; +} + +static void token_set(ts_token *token, te_tokenid id, const char *s) +{ + if (token->id == TOK_WORD && token->str) + free((char*) token->str); + token->id = id; + token->str = s; } void lexer_eat(ts_parser *parser) @@ -100,7 +121,7 @@ void lexer_eat(ts_parser *parser) //if line is void, start readding if (parser->buf_size == 0) { if ((parser->buf = readline(get_prompt(TYPE_PS1))) == NULL) { - set_current_token(parser, TOK_EOF, "eof"); + token_set(&parser->token, TOK_EOF, "eof"); parser->status = PARSE_END; return; } @@ -110,7 +131,7 @@ void lexer_eat(ts_parser *parser) //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"); + token_set(&parser->token, TOK_EOF, "eof"); parser->status = PARSE_END; return; } @@ -121,14 +142,6 @@ void lexer_eat(ts_parser *parser) } } -static void set_current_token(ts_parser *p, te_tokenid t, const char *s) -{ - 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; @@ -147,7 +160,7 @@ static int lexer_reconize(ts_parser *parser) //check for leading \n token if (buf[*buf_pos] == '\n') { ++*buf_pos; - set_current_token(parser, TOK_NEWLINE, "\n"); + token_set(&parser->token, TOK_NEWLINE, "\n"); return 1; } //cut a token @@ -165,20 +178,21 @@ static int lexer_reconize(ts_parser *parser) backed = 1; if (!end_found) return 0; parser->buf_pos = token_pos; - printf("cutted token: '%s'\n", + 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, buf + token_start, + for (register int i = 0; keywords[i].str; ++i) + if (!strncmp(keywords[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); + token_set(&parser->token, keywords[i].id, keywords[i].str); + printf("reconized token: %d (%s)\n", keywords[i].id, keywords[i].str); return 1; } //althought this token is a word - set_current_token(parser, TOK_WORD, + token_set(&parser->token, TOK_WORD, strndup(buf + token_start, token_pos - token_start)); printf("reconized token (WORD): %d (%s)\n", - parser->current.id, parser->current.str); + parser->token.id, parser->token.str); return 1; } + diff --git a/src/parser/parser.c b/src/parser/parser.c index c2d2de0..d480f52 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Wed Aug 2 00:56:07 2006 Seblu -** Last update Fri Aug 18 15:46:11 2006 Seblu +** Last update Sat Aug 19 01:30:25 2006 Seblu */ #include @@ -29,7 +29,6 @@ */ static ts_ast_node *parse_input(ts_parser *parser); - static ts_ast_node *parse_list(ts_parser *parser); static ts_ast_node *parse_andor(ts_parser *parser); @@ -62,17 +61,16 @@ 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) */ -/* exit(42); */ -/* if (tok.id == TOK_NEWLINE) */ -/* lexer_reset(parser); */ -/* lexer_eat(parser); */ -/* } */ + while (1) + { + ts_token tok; + + tok = lexer_gettoken(parser); + if (tok.id == TOK_EOF) + exit(42); + if (tok.id == TOK_NEWLINE) + lexer_reset(parser); + } return parse_input(parser); } @@ -81,15 +79,13 @@ static ts_ast_node *parse_input(ts_parser *parser) ts_token cur_token; ts_ast_node *buf; - lexer_eat(parser); - cur_token = lexer_get(parser); + cur_token = lexer_gettoken(parser); if (cur_token.id == TOK_EOF) return NULL; if (cur_token.id == TOK_NEWLINE) - return ast_create_sep(NULL, NULL); + return ast_sep_create(NULL, NULL); buf = parse_list(parser); - lexer_eat(parser); - cur_token = lexer_get(parser); + cur_token = lexer_gettoken(parser); if (cur_token.id != TOK_EOF || cur_token.id != TOK_NEWLINE) parse_error(parser, cur_token); return buf; @@ -102,8 +98,7 @@ static ts_ast_node *parse_list(ts_parser *parser) /* ts_ast_node *rhs; */ lhs = parse_andor(parser); - lexer_eat(parser); - next_token = lexer_get(parser); + next_token = lexer_gettoken(parser); /* if (next_token.id == TOK_SEP) { */ /* lhs = parse_andor(parser); */ /* } */ diff --git a/src/parser/parser.h b/src/parser/parser.h index e5645c5..0e6659b 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -5,7 +5,7 @@ ** Login ** ** Started on Wed Aug 2 00:49:50 2006 Seblu -** Last update Thu Aug 3 12:28:14 2006 Seblu +** Last update Sat Aug 19 01:35:31 2006 Seblu */ #include @@ -47,7 +47,9 @@ typedef enum e_token TOK_SEPAND, TOK_WORD, TOK_EOF, - TOK_BEGIN + TOK_BEGIN, + TOK_NONE, + TOK_ERR } te_tokenid; typedef struct s_token @@ -66,7 +68,7 @@ typedef enum e_parser_status typedef struct s_parser { te_parser_status status; - ts_token current; + ts_token token; FILE *fs; char *buf; size_t buf_size; @@ -75,7 +77,9 @@ typedef struct s_parser } ts_parser; /* +** ============== ** FILE: parser.c +** ============== */ /*! @@ -105,35 +109,38 @@ void parse_error(ts_parser *parser, ts_token t); ts_ast_node *parse(ts_parser *parser); /* +** ============= ** FILE: lexer.c +** ============= */ /*! ** Set (or reset) the lexer +** This must be call by parser before each parse start +** This function is necessarity to correctly show the prompt ** ** @param parser lexer to reset */ void lexer_reset(ts_parser *parser); /*! -** Return the current token +** Return the next token and destroy it +** @warning The token MUST be freed ! ** -** @return the current token -*/ -ts_token lexer_get(ts_parser *lex); - -/*! -** Eat a token (miam miam) +** @param parser parser/lexer structure +** +** @return the next token */ -void lexer_eat(ts_parser *lex); +ts_token lexer_gettoken(ts_parser *parser); /*! -** Return a token string. Transform a t_token into string +** Return the next token without destruction of it. +** @warning The token string MUST NOT be freed ! ** -** @param t token id to transform +** @param parser parser/lexer structure ** -** @return token string representation +** @return the look ahead token */ -const char *get_token_string(te_tokenid t); +ts_token lexer_lookahead(ts_parser *parser); #endif diff --git a/src/shell/shell.h b/src/shell/shell.h index 821a244..884b2aa 100644 --- a/src/shell/shell.h +++ b/src/shell/shell.h @@ -5,7 +5,7 @@ ** Login ** ** Started on Sun Jul 16 20:03:53 2006 Seblu -** Last update Thu Aug 3 07:01:26 2006 Seblu +** Last update Sat Aug 19 01:45:54 2006 Seblu */ #ifndef SHELL_H_ @@ -29,7 +29,7 @@ typedef struct s_shell { /* struct s_var *vars; */ /* struct s_func *funcs; */ -/* struct s_history *history; */ +/* struct s_history *history; */ ts_opt *opt; char *name; int status; diff --git a/src/shell/shell_prompt.c b/src/shell/shell_prompt.c index 45a6033..1f9459f 100644 --- a/src/shell/shell_prompt.c +++ b/src/shell/shell_prompt.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Sun Jul 30 02:27:59 2006 Seblu -** Last update Thu Aug 3 11:10:46 2006 Seblu +** Last update Sat Aug 19 01:44:07 2006 Seblu */ #include -- GitLab