Commit 1b8af76d authored by Seblu's avatar Seblu

avancement du lexer/parser

parent 3064cafb
good_input: simple_list '\n'
input: list '\n'
list EOF
| '\n'
| EOF
redirection: [NUMBER] '>' WORD
| [NUMBER] '<' WORD
| [NUMBER] '>>' WORD
| [NUMBER] '<<' WORD
| [NUMBER] '<<-' WORD
| [NUMBER] '>&' WORD
| [NUMBER] '<&' WORD
| [NUMBER] '>|' WORD
| [NUMBER] '<>' WORD
element: WORD
| redirection
list: and_or ((';'|'&') and_or)* ['&'|';']
cmd_prefix: ASSIGMENT_WORD
| redirection
and_or: pipeline (('&&'|'||') ('\n')* pipeline)*
simple_command: (cmp_prefix)* (element)+
pipeline: ['!'] command ('|' ('\n')* command)*
command: simple_command
| shell_command (redirection)*
| function_def
simple_list: and_or ((';'|'&') and_or)* ['&'|';']
| funcdec
and_or: pipeline (('&&'|'||') ('\n')* pipeline)*
pipeline: ['!'] command ('|' ('\n')* command)*
simple_command: (cmp_prefix)* (element)+
shell_command: '{' compound_list '}'
| '(' compound_list ')'
......@@ -39,10 +23,25 @@ shell_command: '{' compound_list '}'
| rule_case
| rule_if
rule_if: 'if' compound_list 'then' compound_list [else_clause] 'fi'
funcdec: ['function'] WORD '(' ')' ('\n')* shell_command (redirection)*
else_clause: 'else' compound_list
| 'elif' compound_list 'then' compound_list [else_clause]
redirection: [NUMBER] '>' WORD
| [NUMBER] '<' WORD
| [NUMBER] '>>' WORD
| [NUMBER] '<<' WORD
| [NUMBER] '<<-' WORD
| [NUMBER] '>&' WORD
| [NUMBER] '<&' WORD
| [NUMBER] '>|' WORD
| [NUMBER] '<>' WORD
cmd_prefix: ASSIGMENT_WORD
| redirection
element: WORD
| redirection
compound_list: ('\n')* and_or ((';'|'&'|'\n') ('\n')* and_or)* [(('&'|';'|'\n') ('\n')*)]
rule_for: 'for' WORD ('\n')* ['in' (WORD)+ (';'|'\n') ('\n')*] do_group
......@@ -50,14 +49,16 @@ rule_while: 'while' compound_list do_group
rule_until: 'until' compound_list do_group
do_group: 'do' compound_list 'done'
rule_case: 'case' WORD ('\n')* 'in' ('\n')* [case_clause] 'esac'
compound_list: ('\n')* and_or ((';'|'&'|'\n') ('\n')* and_or)* [(('&'|';'|'\n') ('\n')*)]
rule_if: 'if' compound_list 'then' compound_list [else_clause] 'fi'
else_clause: 'else' compound_list
| 'elif' compound_list 'then' compound_list [else_clause]
case: 'case' WORD ('\n')* 'in' ('\n')* [case_clause] 'esac'
do_group: 'do' compound_list 'done'
case_clause: pattern (';;' (\n)* pattern)* [;;]
pattern: ['('] WORD ('|' WORD)* ')' ( ('\n')* | compound_list )
function: ['function'] WORD '(' ')' ('\n')* shell_command (redirection)*
......@@ -5,17 +5,23 @@ bin_PROGRAMS=42sh
42sh_SOURCES= ast/ast.h \
ast/ast_destruct.c \
ast/ast_sep.c \
common/common.h \
common/macro.h \
common/mem.h \
common/strmerge.c \
common/strvmerge.c \
lexer/lexer.h \
common/strndup.c \
common/basename.c \
exec/exec.h \
exec/exec_ast.c \
opt/opt.h \
opt/opt.c \
opt/opt_init.c \
opt/opt_parser.c \
parser/parser.h \
parser/parser.c \
parser/lexer.c \
readline/readline.h \
readline/readline.c \
readline/getln.c \
......
......@@ -5,7 +5,7 @@
** Login <seblu@epita.fr>
**
** Started on Sun Jul 30 04:40:03 2006 Seblu
** Last update Wed Aug 2 17:54:14 2006 Seblu
** Last update Thu Aug 3 03:03:42 2006 Seblu
*/
#ifndef AST_H_
......@@ -16,13 +16,12 @@
# include <stdlib.h>
# include <assert.h>
struct s_ast;
typedef struct s_ast ts_ast_node;
/*
** If ast node
*/
typedef struct
typedef struct s_if_node
{
ts_ast_node *cond;
ts_ast_node *cond_true;
......@@ -32,7 +31,7 @@ typedef struct
/*
** For ast node
*/
typedef struct
typedef struct s_for_node
{
char *name;
ts_ast_node *values;
......@@ -42,7 +41,7 @@ typedef struct
/*
** Case ast node
*/
typedef struct
typedef struct s_case_node
{
char *word;
//FIXME
......@@ -52,7 +51,7 @@ typedef struct
/*
** While ast node
*/
typedef struct
typedef struct s_while_node
{
ts_ast_node *cond;
ts_ast_node *exec;
......@@ -61,7 +60,7 @@ typedef struct
/*
** Enumerate different type of redirection
*/
typedef enum
typedef enum e_redir_type
{
R_LESS, /* < */
R_LESSAND, /* <& */
......@@ -77,7 +76,7 @@ typedef enum
/*
** Redirection ast node
*/
typedef struct
typedef struct s_redir_node
{
te_redir_type type;
int fd;
......@@ -87,7 +86,7 @@ typedef struct
/*
** Command ast node
*/
typedef struct
typedef struct s_cmd_node
{
char **argv;
ts_redir_node **redirs;
......@@ -100,16 +99,16 @@ typedef struct
** 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
typedef struct s_bin_node
{
ts_ast_node *left;
ts_ast_node *right;
ts_ast_node *lhs;
ts_ast_node *rhs;
} ts_bin_node;
/*
** Subshell ast node
*/
typedef struct
typedef struct s_subshell_node
{
ts_ast_node *head;
} ts_subshell_node;
......@@ -117,7 +116,7 @@ typedef struct
/*
** Funcdec node
*/
typedef struct
typedef struct s_funcdec_node
{
char *name;
ts_ast_node *body;
......@@ -126,7 +125,7 @@ typedef struct
/*
** Enumerate all node type
*/
typedef enum
typedef enum e_node_type
{
T_IF,
T_FOR,
......@@ -140,7 +139,7 @@ typedef enum
T_BANG,
T_PIPE,
T_SEP_AND,
T_SEP_SEMICOMMA,
T_SEP,
T_CASE,
T_CASE_LIST,
......@@ -156,22 +155,22 @@ typedef enum
/*
** This is a type for a node item
*/
typedef union
typedef union u_node_item
{
ts_if_node node_if;
ts_for_node node_for;
ts_case_node node_case;
ts_while_node node_while;
ts_while_node node_until;
ts_cmd_node node_cmd;
ts_bin_node node_and;
ts_bin_node node_or;
ts_subshell_node node_subshell;
ts_funcdec_node node_funcdec;
ts_bin_node node_bang;
ts_bin_node node_pipe;
ts_bin_node node_sep_semicomma;
ts_bin_node node_sep_and;
ts_if_node child_if;
ts_for_node child_for;
ts_case_node child_case;
ts_while_node child_while;
ts_while_node child_until;
ts_cmd_node child_cmd;
ts_bin_node child_and;
ts_bin_node child_or;
ts_subshell_node child_subshell;
ts_funcdec_node child_funcdec;
ts_bin_node child_bang;
ts_bin_node child_pipe;
ts_bin_node child_sep;
ts_bin_node child_sep_and;
/* ts_case_item node_case_item; */
......@@ -185,12 +184,14 @@ typedef union
struct s_ast
{
te_node_type type;
tu_node_item node;
tu_node_item body;
};
void ast_destruct(ts_ast_node *ast);
ts_ast_node *ast_create_sep(ts_ast_node *lhs, ts_ast_node *rhs);
void ast_destruct_sep(ts_ast_node *node);
/* /\** */
/* ** structure wordlist ex : for var in wordlist do */
......@@ -310,7 +311,7 @@ struct s_ast
/* ** create shell structure */
/* *\/ */
/* struct s_42sh *ast_create_ast(struct s_42sh *shell, */
/* struct s_ast *ast); */
/* struct s_ast *ast; */
/* struct s_ast *ast_create_patterns(char *word, struct s_ast *case_item); */
/* struct s_ast *ast_create_case_list(struct s_ast *item, */
......
/*
** ast_destruct.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Sat Mar 25 23:11:01 2006 Seblu
** Last update Thu Aug 3 07:00:17 2006 Seblu
*/
#include "ast.h"
void ast_destruct(ts_ast_node *ast)
{
if (ast == NULL)
return;
//fixme
}
/*
** ast_sep.c for 42sh
**
** Made by Seblu
** Login <luttri_s@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"
/*!
** 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;
secmalloc(node, sizeof (ts_ast_node));
node->type = T_SEP;
node->body.child_sep.lhs = lhs;
node->body.child_sep.rhs = 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_destruct(node);
return;
}
ast_destruct(node->body.child_sep.lhs);
ast_destruct(node->body.child_sep.rhs);
free(node);
}
/*
** basename.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 05:29:46 2006 Seblu
** Last update Thu Aug 3 10:36:04 2006 Seblu
*/
#include <string.h>
#include "common.h"
char *basename(const char *path)
{
size_t start = 0, end = 0, len;
register size_t i;
if ((len = strlen(path)) == 0)
return strdup("");
//search first char without '/' from end string
for (i = len - 1; ; --i) {
if (path[i] != '/') {
end = i;
break;
}
if (i == 0)
break;
}
if (end == 0)
return strdup("");
//search first char '/' from end string
for (i = end - 1; ; --i) {
if (path[i] == '/') {
start = i + 1;
break;
}
if (i == 0)
break;
}
return strndup(path + start, (start >= end) ? 0 : end - start);
}
......@@ -5,13 +5,51 @@
** Login <seblu@epita.fr>
**
** Started on Sun Jul 30 03:59:48 2006 Seblu
** Last update Sun Jul 30 04:33:18 2006 Seblu
** Last update Thu Aug 3 06:01:23 2006 Seblu
*/
#ifndef COMMON_H_
# define COMMON_H_
/*!
** Merge strings
**
** @param n number of string to merge
** @param s1 First string to merge
**
** @return malloced string merged
** @warning the returned string must be freed by the caller
*/
char *strmerge(int n, const char *s1, ...);
/*!
** Merge a vector of string
**
** @param vtable strings to merge
**
** @return a string merged from @arg vtable
*/
char *strvmerge(const char * const *vtable);
/*!
** Return a malloc copy of the given, conserving only the basename
**
** @param path path where basename will be extracted
**
** @return malloced basename
** @warning Not use the standard function for reason of vicious
** definition in manuel.
*/
char *basename(const char *path);
/*!
** Duplicate a string for @arg n characteres
**
** @param str string to duplicate
** @param n number of caractere to duplicate
**
** @return a new malloced string
*/
char *strndup(const char *str, size_t n);
#endif
......@@ -5,22 +5,13 @@
** Login <seblu@epita.fr>
**
** Started on Tue May 16 21:23:02 2006 Seblu
** Last update Sun Jul 30 04:15:36 2006 Seblu
** Last update Thu Aug 3 05:29:21 2006 Seblu
*/
#include <stdarg.h>
#include <string.h>
#include "macro.h"
#include "mem.h"
/*!
** Merge strings
**
** @param n number of string to merge
** @param s1 First string to merge
**
** @return malloced string merged
** @warning the returned string must be freed by the caller
*/
char *strmerge(int n, const char *s1, ...)
{
va_list param;
......
/*
** strndup.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 05:56:28 2006 Seblu
** Last update Thu Aug 3 05:58:42 2006 Seblu
*/
#include <string.h>
#include <stdlib.h>
char *strndup(const char *str, size_t n)
{
size_t length;
size_t max_length;
size_t i;
char *new;
max_length = n;
if ((length = strlen(str)) > max_length)
length = max_length;
if ((new = malloc((length + 1) * sizeof (char))) == NULL)
return NULL;
for (i = 0; i < length; ++i)
new[i] = str[i];
new[length] = 0;
return new;
}
......@@ -5,19 +5,12 @@
** Login <seblu@epita.fr>
**
** Started on Sun Jul 30 04:03:35 2006 Seblu
** Last update Sun Jul 30 04:36:05 2006 Seblu
** Last update Thu Aug 3 05:29:38 2006 Seblu
*/
#include <string.h>
#include "macro.h"
#include "mem.h"
/*!
** Merge a vector of string
**
** @param vtable strings to merge
**
** @return a string merged from @arg vtable
*/
char *strvmerge(const char *const *vtable)
{
size_t string_sz = 0;
......
/*
** execution.h for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Sun Mar 30 16:02:07 2006 Seblu
** Last update Thu Aug 3 01:20:18 2006 Seblu
*/
#ifndef EXEC_H_
# define EXEC_H_
# include <assert.h>
# include <stdio.h>
# include "../ast/ast.h"
void exec_ast(ts_ast_node *node);
/* void exec_node(struct s_ast *node, struct s_42sh *sh); */
/* void exec_list(struct s_list *node, struct s_42sh *sh); */
/* void exec_if(struct s_if *node, struct s_42sh *sh); */
/* void exec_while(struct s_while *node, struct s_42sh *sh); */
/* void exec_until(struct s_while *node, struct s_42sh *sh); */
/* void exec_and(struct s_op *node, struct s_42sh *sh); */
/* void exec_or(struct s_op *node, struct s_42sh *sh); */
/* void exec_cmd(struct s_cmd *node, struct s_42sh *sh); */
/* void exec_pipe(struct s_op *node, struct s_42sh *sh); */
/* void exec_bang(struct s_op *node, struct s_42sh *sh); */
/* void exec_sepand(struct s_op *node, struct s_42sh *sh); */
/* void exec_sepsemicolon(struct s_op *node, struct s_42sh *sh); */
/* void exec_line(struct s_op *node, struct s_42sh *sh); */
/* void exec_subshell(struct s_subshell *node, struct s_42sh *sh); */
/* /\* FIXME *\/ */
/* void exec_for(struct s_for *node, struct s_42sh *sh); */
/* void exec_case(struct s_case *node, struct s_42sh *sh); */
/* void exec_funcdec(struct s_funcdec *node, struct s_42sh *sh); */
#endif
/*
** exec_node.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Sat Mar 25 14:51:09 2006 Seblu
** Last update Sat Apr 15 09:12:38 2006 Seblu
*/
#include "exec.h"
/*!
** Execute a node of ast by calling the good function
**
** @param node node to execute
** @param sh shell struct
*/
void exec_ast(ts_ast_node *node)
{
node = node;
}
/* { */
/* if (node == NULL) */
/* return; */
/* else if (node->type == T_CMD) */
/* exec_cmd(&node->data.node_cmd, sh); */
/* else if (node->type == T_PIPE) */
/* exec_pipe(&node->data.node_op, sh); */
/* else if (node->type == T_LINE) */
/* exec_line(&node->data.node_op, sh); */
/* else if (node->type == T_SEP_AND) */
/* exec_sepand(&node->data.node_op, sh); */
/* else if (node->type == T_SEP_SEMICOMMA) */
/* exec_sepsemicolon(&node->data.node_op, sh); */
/* else if (node->type == T_IF) */
/* exec_if(&node->data.node_if, sh); */
/* else if (node->type == T_FOR) */
/* exec_for(&node->data.node_for, sh); */
/* else if (node->type == T_AND) */
/* exec_and(&node->data.node_op, sh); */
/* else if (node->type == T_OR) */
/* exec_or(&node->data.node_op, sh); */
/* else if (node->type == T_WHILE) */
/* exec_while(&node->data.node_while, sh); */
/* else if (node->type == T_UNTIL) */
/* exec_until(&node->data.node_while, sh); */
/* else if (node->type == T_BANG) */
/* exec_bang(&node->data.node_op, sh); */
/* else if (node->type == T_SUBSHELL) */
/* exec_subshell(&node->data.node_subshell, sh); */
/* else */
/* assert(0); */
/* } */
/*
** exec_node.c for 42sh in /home/seblu
** exec_node.c for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
......@@ -8,9 +8,7 @@
** Last update Sat Apr 15 09:12:38 2006 Seblu
*/
#include "execution.h"
#include "mem.h"
#include "exec.h"
/*!
** Execute a node of ast by calling the good function
......@@ -18,37 +16,40 @@
** @param node node to execute
** @param sh shell struct
*/
void exec_node(struct s_ast *node, struct s_42sh *sh)
void exec_ast(ts_ast_node *node)
{
assert(sh);
if (node == NULL)
return;
else if (node->type == T_CMD)
exec_cmd(&node->data.node_cmd, sh);
else if (node->type == T_PIPE)
exec_pipe(&node->data.node_op, sh);
else if (node->type == T_LINE)
exec_line(&node->data.node_op, sh);
else if (node->type == T_SEP_AND)
exec_sepand(&node->data.node_op, sh);
else if (node->type == T_SEP_SEMICOMMA)
exec_sepsemicolon(&node->data.node_op, sh);
else if (node->type == T_IF)
exec_if(&node->data.node_if, sh);
else if (node->type == T_FOR)
exec_for(&node->data.node_for, sh);
else if (node->type == T_AND)
exec_and(&node->data.node_op, sh);
else if (node->type == T_OR)
exec_or(&node->data.node_op, sh);
else if (node->type == T_WHILE)
exec_while(&node->data.node_while, sh);
else if (node->type == T_UNTIL)
exec_until(&node->data.node_while, sh);
else if (node->type == T_BANG)
exec_bang(&node->data.node_op, sh);
else if (node->type == T_SUBSHELL)
exec_subshell(&node->data.node_subshell, sh);
else
assert(0);
node = node;
}
/* { */
/* if (node == NULL) */
/* return; */
/* else if (node->type == T_CMD) */
/* exec_cmd(&node->data.node_cmd, sh); */
/* else if (node->type == T_PIPE) */
/* exec_pipe(&node->data.node_op, sh); */
/* else if (node->type == T_LINE) */
/* exec_line(&node->data.node_op, sh); */
/* else if (node->type == T_SEP_AND) */
/* exec_sepand(&node->data.node_op, sh); */
/* else if (node->type == T_SEP_SEMICOMMA) */
/* exec_sepsemicolon(&node->data.node_op, sh); */
/* else if (node->type == T_IF) */
/* exec_if(&node->data.node_if, sh); */
/* else if (node->type == T_FOR) */
/* exec_for(&node->data.node_for, sh); */
/* else if (node->type == T_AND) */
/* exec_and(&node->data.node_op, sh); */
/* else if (node->type == T_OR) */
/* exec_or(&node->data.node_op, sh); */
/* else if (node->type == T_WHILE) */
/* exec_while(&node->data.node_while, sh); */
/* else if (node->type == T_UNTIL) */
/* exec_until(&node->data.node_while, sh); */
/* else if (node->type == T_BANG) */
/* exec_bang(&node->data.node_op, sh); */
/* else if (node->type == T_SUBSHELL) */
/* exec_subshell(&node->data.node_subshell, sh); */
/* else */
/* assert(0); */
/* } */
/*
** lexer.h for 42sh
**
** Made by Seblu
** Login <seblu@epita.fr>
**
** Started on Sun Jul 30 04:36:53 2006 Seblu
** Last update Sun Jul 30 04:37:57 2006 Seblu
*/
#ifndef LEXER_H_
# define LEXER_H_
#endif
......@@ -5,11 +5,11 @@
** Login <seblu@epita.fr>
**
** Started on Sun Jul 30 03:33:09 2006 Seblu
** Last update Sun Jul 30 03:57:27 2006 Seblu
** Last update Thu Aug 3 02:45:51 2006 Seblu
*/
#include "opt.h"
#include "../common/macro.h"
#include "../common/mem.h"
/*!
** Create a new option structure
......
......@@ -5,7 +5,7 @@
** Login <seblu@epita.fr>
**
** Started on Sun Jul 30 03:28:26 2006 Seblu
** Last update Sun Jul 30 04:37:35 2006 Seblu
** Last update Thu Aug 3 05:22:32 2006 Seblu
*/
#include <stdio.h>
......