Commit 08f97490 authored by Seblu's avatar Seblu

----

ast printer est completement ecrit.
Il ne reste plus qu'a tester pour les noeuds qui ne sont pas encore parser.
----
PARSER:
pipeline OK
and/or OK
list OK
----
GRAMMAR
Changement pour coller a la xsi!
----
beaucoup d'autre truc
parent 6ede8e78
Sebastien Luttringer
\ No newline at end of file
......@@ -11,7 +11,7 @@ pipeline: ['!'] command ('|' ('\n')* command)*
command: simple_command
| shell_command (redirection)*
| funcdec
| funcdec (redirection)*
simple_command: (prefix)+
| (prefix)* (element)+
......@@ -24,7 +24,7 @@ shell_command: '{' compound_list '}'
| rule_case
| rule_if
funcdec: ['function'] WORD '(' ')' ('\n')* shell_command (redirection)*
funcdec: ['function'] WORD '(' ')' ('\n')* shell_command
redirection: [IONUMBER] '>' WORD
| [IONUMBER] '<' WORD
......@@ -61,5 +61,4 @@ do_group: 'do' compound_list 'done'
case_clause: case_item (';;' (\n)* case_item)* [;;]
case_item: ['('] WORD ('|' WORD)* ')' ( ('\n')* | compound_list )
case_item: ['('] WORD ('|' WORD)* ')' ( ('\n')* | compound_list )
\ No newline at end of file
----
Revoir les free dans le parser a cause de ast_destruct qui rentre dans les fils.
il faudrait ecrire des fonctions qui ne le fasse pas! Voir aussi au niveau de la
boucle general si ast_destruct est appele alors qu'une erreur de parse est surevenur
(le cas echeant, le supprimer)
----
Voir probleme de syntax que j'accepte lorsque un EOF apparait avant une quote
fermante. Le token est valide alors que sous bash non
----
ajotuer le prompt PS3 lorsque l'on parse sur plusieurs ligne
----
parse du case
----
parse du funcdec
----
corriger le bug
./42sh </etc/bash/bashrc
\ No newline at end of file
......@@ -10,23 +10,22 @@ AC_CONFIG_AUX_DIR([build])
# Auto Make init
AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip])
echo "Checking locale CFLAGS"
echo "checking CFLAGS..."
# Check platform
AC_CANONICAL_HOST
case $host_os in
*netbsd*)
AC_SUBST([CFLAGS], ['-Wall -Werror -W -ansi -pedantic'])
CFLAGS='-Wall -Werror -W -ansi -pedantic'
;;
*osf*)
AC_SUBST([CFLAGS], ['-Wall -Werror -W -ansi -pedantic -D_XOPEN_SOURCE=600'])
CFLAGS='-Wall -Werror -W -ansi -pedantic -D_XOPEN_SOURCE=600'
;;
*solaris*)
AC_SUBST([CFLAGS], ['-Wall -Werror -W -ansi -pedantic -D_XOPEN_SOURCE=600'])
CFLAGS='-Wall -Werror -W -ansi -pedantic -D_XOPEN_SOURCE=600'
;;
*linux*)
AC_SUBST([CFLAGS], ['-Wall -Werror -W -std=c99 -pedantic -D_XOPEN_SOURCE=600'])
AC_SUBST([LDFLAGS], ['-static'])
CFLAGS='-Wall -Werror -W -std=c99 -pedantic -D_XOPEN_SOURCE=600'
;;
*)
pl="`uname -s`"
......@@ -77,36 +76,41 @@ AC_TYPE_SIZE_T
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_HEADER_STDBOOL
AC_STRUCT_TM
# Check for headers
AC_CHECK_HEADERS([sys/param.h unistd.h])
AC_CHECK_HEADERS([fcntl.h])
AC_CHECK_HEADERS([libintl.h])
AC_CHECK_HEADERS([stddef.h])
AC_CHECK_HEADERS([limits.h])
dnl Memo:
dnl AC ARG WITH(package, help-string, [action-if-given], [action-if-not-given])
AC_ARG_WITH([debug],
[AS_HELP_STRING([--with-debug], [use -g and don't use -DNDEBUG -O3])],
[dnl action-if-given: --with-debug => -g || --without-debug => -DNDEBUG
if test x$withval = xyes; then
CFLAGS="$CFLAGS -g"
else
CFLAGS="$CFLAGS -DNDEBUG -O3"
fi
[dnl action-if-given
CFLAGS="$CFLAGS -g"
],
[dnl action-if-not-given: MAINTAINER_MODE => -g || !MAINTAINER_MODE => -DNDEBUG
# If we are in maintainer mode, we want to have DEBUG (NDEBUG==NO DEBUG)
# So we simply replace -DNDEBUG by -g
if test x$MAINTAINER_MODE = xyes; then
CFLAGS="$CFLAGS -g"
else
[dnl action-if-not-given
CFLAGS="$CFLAGS -DNDEBUG -O3"
fi
]
)
AC_ARG_WITH([efence],
[AS_HELP_STRING([--with-efence], [link with lib efence])],
[dnl action-if-given
LDFLAGS="$LDFLAGS -lefence"
],
[dnl action-if-not-given
LDFLAGS="$LDFLAGS -static"
]
)
AC_SUBST([CFLAGS])
AC_SUBST([LDFLAGS])
# define Autoconf config header
AC_CONFIG_HEADERS([config.h])
......@@ -117,4 +121,4 @@ AC_CONFIG_FILES([
src/Makefile
])
AC_OUTPUT
AC_OUTPUT
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -16,10 +16,10 @@ bin_PROGRAMS=42sh
ast/ast_or.c \
ast/ast_pipe.c \
ast/ast_print.c \
ast/ast_red.c \
ast/ast_sep.c \
ast/ast_sepand.c \
ast/ast_subshell.c \
ast/ast_until.c \
ast/ast_while.c \
common/basename.c \
common/common.h \
......@@ -27,6 +27,7 @@ bin_PROGRAMS=42sh
common/isdigitstr.c \
common/macro.h \
common/strmerge.c \
common/strvectoradd.c \
common/strvmerge.c \
common/strndup.c \
exec/exec.h \
......
......@@ -5,7 +5,7 @@
** Login <seblu@epita.fr>
**
** Started on Sun Jul 30 04:40:03 2006 Seblu
** Last update Tue Sep 26 17:49:18 2006 Seblu
** Last update Wed Oct 11 14:58:42 2006 seblu
*/
#ifndef AST_H_
......@@ -68,7 +68,7 @@ typedef struct while_node
/*
** Enumerate different type of redirection
*/
typedef enum redir_type
typedef enum red_type
{
R_LESS, /* < */
R_LESSAND, /* <& */
......@@ -79,19 +79,19 @@ typedef enum redir_type
R_CLOBBER, /* >| */
R_DLESS, /* << */
R_DLESSDASH /* <<- */
} e_redir_type;
} e_red_type;
/*
** Redirection ast node
*/
typedef struct redir s_redir;
struct redir
typedef struct red_node
{
e_redir_type type;
int fd;
char *word;
s_redir *next;
};
size_t size;
e_red_type *type;
int *fd;
char **word;
s_ast_node *mhs;
} s_red_node;
/*
** Command ast node
......@@ -99,7 +99,6 @@ struct redir
typedef struct cmd_node
{
char **argv;
s_redir *redirs;
char **prefix;
} s_cmd_node;
......@@ -133,7 +132,6 @@ typedef enum node_type
T_FOR,
T_CASE,
T_WHILE,
T_UNTIL,
T_CMD,
T_AND,
T_OR,
......@@ -143,8 +141,14 @@ typedef enum node_type
T_PIPE,
T_SEPAND,
T_SEP,
T_RED,
} e_node_type;
/*
** Global constant of total count of node type
*/
enum { NODE_TYPE_COUNT = 14 };
/*
** This is a type for a node item
*/
......@@ -154,7 +158,6 @@ typedef union node_item
s_for_node child_for;
s_case_node child_case;
s_while_node child_while;
s_while_node child_until;
s_cmd_node child_cmd;
s_bin_node child_and;
s_bin_node child_or;
......@@ -164,6 +167,7 @@ typedef union node_item
s_bin_node child_pipe;
s_bin_node child_sep;
s_bin_node child_sepand;
s_red_node child_red;
} u_node_item;
/*
......@@ -213,6 +217,14 @@ void ast_destruct(s_ast_node *ast);
s_ast_node *ast_if_create(s_ast_node *cond,
s_ast_node *cond_true,
s_ast_node *cond_false);
/*!
** Print an if ast node
**
** @param ast ast node to add to file
** @param fs file stream where print ast
** @param node_id first free node id
*/
void ast_if_print(s_ast_node *node, FILE *fs, unsigned int *node_id);
/*!
** Destruct an if ast node
......@@ -235,6 +247,15 @@ s_ast_node *ast_for_create(char *varname,
char **values,
s_ast_node *exec);
/*!
** Print a for ast node
**
** @param ast ast node to add to file
** @param fs file stream where print ast
** @param node_id first free node id
*/
void ast_for_print(s_ast_node *node, FILE *fs, unsigned *node_id);
/*!
** Destruct a for ast node
**
......@@ -263,6 +284,15 @@ void ast_case_add_item(s_ast_node *node,
char **pattern,
s_ast_node *exec);
/*!
** Print a case ast node
**
** @param ast ast node to add to file
** @param fs file stream where print ast
** @param node_id first free node id
*/
void ast_case_print(s_ast_node *node, FILE *fs, unsigned *node_id);
/*!
** Destruct a case ast node
**
......@@ -296,32 +326,6 @@ void ast_while_print(s_ast_node *node, FILE *fs, unsigned int *node_id);
*/
void ast_while_destruct(s_ast_node *node);
/*!
** Create a until ast node
**
** @param cond poursuit condition
** @param exec tree to execute if cond is false
**
** @return the node
*/
s_ast_node *ast_until_create(s_ast_node *cond, s_ast_node *exec);
/*!
** Print an ast until (until) node
**
** @param ast ast node to add to file
** @param fs file stream where print ast
** @param node_id first free node id
*/
void ast_until_print(s_ast_node *node, FILE *fs, unsigned int *node_id);
/*!
** Destruct a until ast node
**
** @param node node to destroy
*/
void ast_until_destruct(s_ast_node *node);
/*!
** Create a cmd ast node
**
......@@ -329,19 +333,6 @@ void ast_until_destruct(s_ast_node *node);
*/
s_ast_node *ast_cmd_create(void);
/*!
** Add a redirection to a cmd node
**
** @param node node where add
** @param type type of redirection
** @param fd fd parameter of redirection
** @param word file or word parameter of redirection
*/
void ast_cmd_add_redir(s_ast_node *node,
e_redir_type type,
int fd,
char *word);
/*!
** Add a arg vector to a cmd node
**
......@@ -459,7 +450,16 @@ void ast_subshell_destruct(s_ast_node *node);
**
** @return the node
*/
s_ast_node *ast_fundec_create(char *name, s_ast_node *body);
s_ast_node *ast_funcdec_create(char *name, s_ast_node *body);
/*!
** Print an function declaration node
**
** @param ast ast node to add to file
** @param fs file stream where print ast
** @param node_id first free node id
*/
void ast_funcdec_print(s_ast_node *node, FILE *fs, unsigned *node_id);
/*!
** Destruct a funcdec ast node
......@@ -571,4 +571,40 @@ void ast_sepand_print(s_ast_node *node, FILE *fs, unsigned int *node_id);
*/
void ast_sepand_destruct(s_ast_node *node);
/*!
** Create a redirection ast node
**
** @return the node
*/
s_ast_node *ast_red_create(void);
/*!
** Add a redirection to a redirection node
**
** @param node node where add
** @param type type of redirection
** @param fd fd parameter of redirection
** @param word file or word parameter of redirection
*/
void ast_red_add(s_ast_node *node,
e_red_type type,
int fd,
char *word);
/*!
** Print an ast red node
**
** @param ast ast node to add to file
** @param fs file stream where print ast
** @param node_id first free node id
*/
void ast_red_print(s_ast_node *node, FILE *fs, unsigned int *node_id);
/*!
** Destruct a red node
**
** @param node node to destroy
*/
void ast_red_destruct(s_ast_node *node);
#endif /* !AST_H_ */
......@@ -5,7 +5,7 @@
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Mon Aug 28 23:57:38 2006 Seblu
** Last update Wed Oct 11 13:07:50 2006 seblu
*/
#include "ast.h"
......@@ -39,6 +39,34 @@ void ast_case_add_item(s_ast_node *node,
*this = item;
}
void ast_case_print(s_ast_node *node, FILE *fs, unsigned *node_id)
{
unsigned cur_node;
s_case_item *item;
unsigned item_id;
if (node->type != T_CASE)
return;
fprintf(fs, "%u [label = \"CASE\\nword: %s\"];\n",
cur_node = *node_id, node->body.child_case.word);
++*node_id;
for (item = node->body.child_case.items, item_id = 0;
item;
item = item->next, ++item_id) {
fprintf(fs, "%u -> %u\n", cur_node, *node_id);
fprintf(fs, "%u [ label = \"Item %u\\n", *node_id, item_id);
++*node_id;
//print pattern
if (item->pattern)
for (int i = 0; item->pattern[i]; ++i)
fprintf(fs, "%s\\n", item->pattern[i]);
fprintf(fs, "\"];\n");
//print exec
if (item->exec)
ast_print_node(item->exec, fs, node_id);
}
}
void ast_case_destruct(s_ast_node *node)
{
s_case_item *this, *buf;
......
......@@ -5,7 +5,7 @@
** Login <seblu@epita.fr>
**
** Started on Fri Aug 18 22:13:51 2006 Seblu
** Last update Tue Sep 26 17:25:05 2006 Seblu
** Last update Tue Oct 10 14:27:02 2006 seblu
*/
#include "ast.h"
......@@ -18,30 +18,9 @@ s_ast_node *ast_cmd_create(void)
node->type = T_CMD;
node->body.child_cmd.argv = NULL;
node->body.child_cmd.prefix = NULL;
node->body.child_cmd.redirs = NULL;
return node;
}
void ast_cmd_add_redir(s_ast_node *node,
e_redir_type type,
int fd,
char *word)
{
s_redir *red;
s_redir **this;
if (node->type != T_CMD)
return;
secmalloc(red, sizeof (s_redir));
red->type = type;
red->fd = fd;
red->word = word;
red->next = NULL;
for (this = &node->body.child_cmd.redirs; (*this) != NULL; this = &(*this)->next)
; //do nothing
*this = red;
}
void ast_cmd_add_prefix(s_ast_node *node, char *assignment_word)
{
if (node->type != T_CMD)
......@@ -72,16 +51,13 @@ void ast_cmd_add_argv(s_ast_node *node, char *argv)
void ast_cmd_print(s_ast_node *node, FILE *fs, unsigned int *node_id)
{
unsigned cur_id = *node_id;
if (node->type != T_CMD)
return;
fprintf(fs, "%u [label = \"Command\"];\n", *node_id);
fprintf(fs, "%u [label = \"Command\\n", *node_id);
++*node_id;
//prefix
char **prefix = node->body.child_cmd.prefix;
if (prefix && prefix[0]) {
fprintf(fs, "%u [label = \"", *node_id);
for (int i = 0; prefix && prefix[i]; ++i) {
fprintf(fs, "prefix[%d]:", i);
size_t last = 0, p = 0;
......@@ -91,14 +67,10 @@ void ast_cmd_print(s_ast_node *node, FILE *fs, unsigned int *node_id)
fprintf(fs, "%*s", p - last, prefix[i] + last), last = p;
fprintf(fs, "\\n");
}
fprintf(fs, "\"];\n");
fprintf(fs, "%u -> %u\n", cur_id, *node_id);
++*node_id;
}
//arguments
char **argv = node->body.child_cmd.argv;
if (argv && argv[0]) {
fprintf(fs, "%u [label = \"", *node_id);
if (argv && argv[0])
for (int i = 0; argv && argv[i]; ++i) {
fprintf(fs, "argv[%d]:", i);
size_t last = 0, p = 0;
......@@ -108,33 +80,11 @@ void ast_cmd_print(s_ast_node *node, FILE *fs, unsigned int *node_id)
fprintf(fs, "%*s", p - last, argv[i] + last), last = p;
fprintf(fs, "\\n");
}
fprintf(fs, "\"];\n");
fprintf(fs, "%u -> %u\n", cur_id, *node_id);
++*node_id;
}
//redirs
if (node->body.child_cmd.redirs) {
int i = 0;
fprintf(fs, "%u [label = \"", *node_id);
for (s_redir *this = node->body.child_cmd.redirs; this; this = this->next, ++i) {
fprintf(fs, "redirs[%d]: fd=%d, type=%d, word=", i, this->fd, this->type);
size_t last = 0, p = 0;
for (; this->word[p]; ++p)
if (this->word[p] == '"')
fprintf(fs, "%.*s\\", p - last, this->word + last), last = p;
fprintf(fs, "%*s", p - last, this->word + last), last = p;
fprintf(fs, "\\n");
++*node_id;
}
fprintf(fs, "\"];\n");
fprintf(fs, "%u -> %u\n", cur_id, *node_id);
}
fprintf(fs, "\"];\n");
}
void ast_cmd_destruct(s_ast_node *node)
{
s_redir *this, *buf;
if (node->type != T_CMD)
return;
if (node->body.child_cmd.argv) {
......@@ -147,10 +97,5 @@ void ast_cmd_destruct(s_ast_node *node)
free(node->body.child_cmd.prefix[i]);
free(node->body.child_cmd.prefix);
}
for (this = node->body.child_cmd.redirs; this; this = buf) {
free(this->word);
buf = this->next;
free(this);
}
free(node);
}
......@@ -5,13 +5,11 @@
** Login <seblu@epita.fr>
**
** Started on Sat Mar 25 23:11:01 2006 Seblu
** Last update Tue Aug 29 00:06:45 2006 Seblu
** Last update Mon Oct 16 18:10:35 2006 seblu
*/
#include "ast.h"
#define NODE_TYPE_COUNT 14
typedef void (*destruct_fct)(s_ast_node *);
struct ast_destruct_switch
......@@ -25,7 +23,6 @@ struct ast_destruct_switch destruction_table[NODE_TYPE_COUNT] =
{T_IF, ast_if_destruct},
{T_FOR, ast_for_destruct},
{T_WHILE, ast_while_destruct},
{T_UNTIL, ast_until_destruct},
{T_CMD, ast_cmd_destruct},
{T_AND, ast_and_destruct},
{T_OR, ast_or_destruct},
......@@ -35,7 +32,8 @@ struct ast_destruct_switch destruction_table[NODE_TYPE_COUNT] =
{T_PIPE, ast_pipe_destruct},
{T_SEPAND, ast_sepand_destruct},
{T_SEP, ast_sep_destruct},
{T_CASE, ast_sepand_destruct}
{T_CASE, ast_sepand_destruct},
{T_RED, ast_red_destruct}
};
void ast_destruct(s_ast_node *ast)
......@@ -43,6 +41,8 @@ void ast_destruct(s_ast_node *ast)
if (ast == NULL)
return;
for (register int i = 0; i < NODE_TYPE_COUNT; ++i)
if (destruction_table[i].type == ast->type)
if (destruction_table[i].type == ast->type) {
(destruction_table[i].fct)(ast);
return;
}
}
......@@ -5,13 +5,13 @@
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Mon Aug 28 23:58:56 2006 Seblu
** Last update Thu Oct 12 16:01:04 2006 seblu
*/
#include "ast.h"
s_ast_node *ast_for_create(char *varname,
char **values,
char **values,
s_ast_node *exec)
{
s_ast_node *node;
......@@ -24,6 +24,31 @@ s_ast_node *ast_for_create(char *varname,
return node;
}
void ast_for_print(s_ast_node *node, FILE *fs, unsigned *node_id)
{
unsigned cur_node;
if (node->type != T_FOR)
return;
fprintf(fs, "%u [label = \"FOR\\nvariable: %s\"];\n",
cur_node = *node_id, node->body.child_for.varname);
++*node_id;
//values
if (node->body.child_for.values) {
fprintf(fs, "%u -> %u\n", cur_node, *node_id);
fprintf(fs, "%u [ label = \"Values\\n", *node_id);
++*node_id;
for (register size_t i = 0; node->body.child_for.values[i]; ++i)
fprintf(fs, "id=%u %s\\n", i, node->body.child_for.values[i]);
fprintf(fs, "\"];");
}
//execution
if (node->body.child_for.exec) {
fprintf(fs, "%u -> %u\n", cur_node, *node_id);
ast_print_node(node->body.child_for.exec, fs, node_id);
}
}
void ast_for_destruct(s_ast_node *node)
{
if (node->type != T_FOR)
......
......@@ -5,7 +5,7 @@
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Mon Aug 28 23:59:05 2006 Seblu
** Last update Tue Oct 10 14:40:44 2006 seblu
*/
#include "ast.h"
......@@ -21,6 +21,19 @@ s_ast_node *ast_funcdec_create(char *name, s_ast_node *body)
return node;
}
void ast_funcdec_print(s_ast_node *node, FILE *fs, unsigned *node_id)
{
unsigned int lhs_id, cur_id;
if (node->type != T_FUNCDEC)
return;
fprintf(fs, "%u [label = \"FuncDec\\nName: %s\"];\n",
cur_id = *node_id, node->body.child_funcdec.name);
lhs_id = ++*node_id;
ast_print_node(node->body.child_funcdec.body, fs, node_id);
fprintf(fs, "%u -> %u\n", cur_id, lhs_id);
}
void ast_funcdec_destruct(s_ast_node *node)
{
if (node->type != T_FUNCDEC)
......
......@@ -5,7 +5,7 @@
** Login <seblu@epita.fr>
**
** Started on Thu Aug 3 02:41:37 2006 Seblu
** Last update Mon Aug 28 23:59:17 2006 Seblu
** Last update Tue Oct 10 17:15:53 2006 seblu
*/
#include "ast.h"
......@@ -24,6 +24,31 @@ s_ast_node *ast_if_create(s_ast_node *cond,
return node;
}
void ast_if_print(s_ast_node *node, FILE *fs, unsigned *node_id)
{
unsigned cur_node;
if (node->type != T_IF)
return;
fprintf(fs, "%u [label = \"IF\"];\n", cur_node = *node_id);
++*node_id;
//if
if (node->body.child_if.cond) {
fprintf(fs, "%u -> %u\n", cur_node, *node_id);
ast_print_node(node->body.child_if.cond, fs, node_id);
}
//then
if (node->body.child_if.cond_true) {
fprintf(fs, "%u -> %u\n", cur_node, *node_id);
ast_print_node(node->body.child_if.cond_true, fs, node_id);
}
//else
if (node->body.child_if.cond_false) {
fprintf(fs, "%u -> %u\n", cur_node, *node_id);
ast_print_node(node->body.child_if.cond_false, fs, node_id);
}
}
void ast_if_destruct(s_ast_node *node)
{
if (node->type != T_IF)
......
......@@ -5,7 +5,7 @@
** Login <seblu@epita.fr>
**
** Started on Sat Mar 25 23:11:01 2006 Seblu
** Last update Tue Sep 26 17:47:33 2006 Seblu
** Last update Thu Oct 12 13:12:31 2006 seblu
*/
#include <string.h>
......@@ -15,11 +15,10 @@
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
#include "ast.h"
enum { NODE_TYPE_COUNT = 14 };
typedef void (*f_print)(s_ast_node *, FILE *, unsigned int *);
typedef void (*f_print)(s_ast_node *, FILE *, unsigned int *);
struct ast_print_switch
{
......@@ -29,20 +28,20 @@ struct ast_print_switch
struct ast_print_switch print_table[NODE_TYPE_COUNT] =
{
{T_IF, NULL}, // ast_if_print},
{T_FOR, NULL}, //ast_for_print},
{T_IF, ast_if_print},
{T_FOR, ast_for_print},
{T_WHILE, ast_while_print},
{T_UNTIL, ast_until_print},
{T_CMD, ast_cmd_print},
{T_AND, ast_and_print},
{T_OR, ast_or_print},
{T_SUBSHELL, ast_subshell_print},
{T_FUNCDEC, NULL}, //ast_funcdec_print},
{T_BANG, ast_bang_print},
{T_PIPE, ast_pipe_print},
{T_SEPAND, ast_sepand_print},