*** empty log message ***

This commit is contained in:
hyung-hwan 2006-01-09 12:51:47 +00:00
parent 4b2bfa9257
commit 35990d18e5
4 changed files with 266 additions and 23 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.c,v 1.5 2005-12-29 12:04:51 bacon Exp $
* $Id: awk.c,v 1.6 2006-01-09 12:51:46 bacon Exp $
*/
#include <xp/awk/awk.h>
@ -20,6 +20,7 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk)
return XP_NULL;
}
awk->tree = XP_NULL;
awk->errnum = XP_AWK_ENOERR;
awk->src_func = XP_NULL;
@ -38,6 +39,10 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk)
int xp_awk_close (xp_awk_t* awk)
{
/* TODO: collapse the tree */
if (awk->tree != XP_NULL) __collapse_tree (awk->tree);
if (xp_awk_detsrc(awk) == -1) return -1;
xp_str_close (&awk->token.name);
if (awk->__dynamic) xp_free (awk);

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.h,v 1.6 2005-12-29 12:04:51 bacon Exp $
* $Id: awk.h,v 1.7 2006-01-09 12:51:47 bacon Exp $
*/
#ifndef _XP_AWK_AWK_H_
@ -8,6 +8,7 @@
#include <xp/types.h>
#include <xp/macros.h>
#include <xp/bas/str.h>
#include <xp/awk/tree.h>
enum
{
@ -16,8 +17,11 @@ enum
XP_AWK_ESRCOP,
XP_AWK_ESRCCL,
XP_AWK_ESRCDT, /* error in reading source */
XP_AWK_ELXCHR, /* lexer came accross an wrong character */
XP_AWK_ELXUNG /* lexer failed to unget a character */
XP_AWK_ELXUNG, /* lexer failed to unget a character */
XP_AWK_ELBRACE /* left brace expected */
};
/*
@ -40,6 +44,9 @@ enum
struct xp_awk_t
{
/* parse tree */
xp_awk_node_t* tree;
/* io functions */
xp_awk_io_t src_func;
xp_awk_io_t inp_func;

View File

@ -1,8 +1,10 @@
/*
* $Id: parse.c,v 1.9 2005-12-29 12:04:51 bacon Exp $
* $Id: parse.c,v 1.10 2006-01-09 12:51:47 bacon Exp $
*/
#include <xp/awk/awk.h>
#include <xp/awk/tree.h>
#include <xp/awk/tree.h>
#include <xp/bas/memory.h>
#include <xp/bas/ctype.h>
#include <xp/bas/string.h>
@ -26,8 +28,8 @@ enum
TOKEN_RPAREN,
TOKEN_LBRACE,
TOKEN_RBRACE,
TOKEN_LBRAKET,
TOKEN_RBRAKET,
TOKEN_LBRACKET,
TOKEN_RBRACKET,
TOKEN_STRING,
TOKEN_REGEX,
@ -37,15 +39,29 @@ enum
TOKEN_END,
TOKEN_FUNCTION,
TOKEN_IF,
TOKEN_DO,
TOKEN_WHILE,
TOKEN_FOR,
TOKEN_DO,
TOKEN_BREAK,
TOKEN_CONTINUE,
TOKEN_BREAK
TOKEN_RETURN,
TOKEN_EXIT,
TOKEN_DELETE,
TOKEN_NEXT,
TOKEN_NEXTFILE
};
static int __parse (xp_awk_t* awk);
static int __parse_program (xp_awk_t* awk);
static xp_awk_node_t* __parse_program (xp_awk_t* awk);
static xp_awk_node_t* __parse_block (xp_awk_t* awk);
static xp_awk_node_t* __parse_if (xp_awk_t* awk);
static xp_awk_node_t* __parse_while (xp_awk_t* awk);
static xp_awk_node_t* __parse_for (xp_awk_t* awk);
static xp_awk_node_t* __parse_do (xp_awk_t* awk);
static xp_awk_node_t* __parse_break (xp_awk_t* awk);
static xp_awk_node_t* __parse_continue (xp_awk_t* awk);
static int __get_token (xp_awk_t* awk);
static int __get_char (xp_awk_t* awk);
static int __unget_char (xp_awk_t* awk, xp_cint_t c);
@ -65,11 +81,16 @@ static struct __kwent __kwtab[] =
{ XP_TEXT("END"), TOKEN_END },
{ XP_TEXT("function"), TOKEN_FUNCTION },
{ XP_TEXT("if"), TOKEN_IF },
{ XP_TEXT("do"), TOKEN_DO },
{ XP_TEXT("while"), TOKEN_WHILE },
{ XP_TEXT("for"), TOKEN_FOR },
{ XP_TEXT("continue"), TOKEN_CONTINUE },
{ XP_TEXT("do"), TOKEN_DO },
{ XP_TEXT("break"), TOKEN_BREAK },
{ XP_TEXT("continue"), TOKEN_CONTINUE },
{ XP_TEXT("return"), TOKEN_RETURN },
{ XP_TEXT("exit"), TOKEN_EXIT },
{ XP_TEXT("delete"), TOKEN_DELETE },
{ XP_TEXT("next"), TOKEN_NEXT },
{ XP_TEXT("nextfile"), TOKEN_NEXTFILE },
{ XP_NULL, 0 },
};
@ -98,20 +119,36 @@ static struct __kwent __kwtab[] =
#define GET_TOKEN(awk) \
do { if (__get_token(awk) == -1) return -1; } while(0)
#define MATCH(awk,token_type) ((awk)->token.type == (token_type))
#define CONSUME(awk) \
do { if (__get_token(awk) == -1) return XP_NULL; } while(0)
#define PANIC(awk,code) do { (awk)->errnum = (code); return XP_NULL; } while (0);
int xp_awk_parse (xp_awk_t* awk)
{
xp_awk_node_t* node;
GET_CHAR (awk);
GET_TOKEN (awk);
return __parse_program (awk);
node = __parse_program(awk);
if (node == XP_NULL) return -1;
awk->tree = node;
return 0;
}
static int __parse_program (xp_awk_t* awk)
static xp_awk_node_t* __parse_program (xp_awk_t* awk)
{
/*
pattern { action }
function name (parameter-list) { statement }
*/
xp_awk_node_t* node;
/*
while (1) {
if (awk->token.type == TOKEN_FUNCTION) {
if (__parse_function_declaration(awk) == -1) return -1;
@ -120,16 +157,18 @@ static int __parse_program (xp_awk_t* awk)
if (__parse_pattern_action(awk) == -1) return -1;
}
}
*/
return 0;
return node;
}
static int __parse_function_declaration (xp_awk_t* awk)
static xp_awk_node_t* __parse_function_declaration (xp_awk_t* awk)
{
return -1;
return XP_NULL;
}
static int __parse_pattern_action (xp_awk_t* awk)
static xp_awk_node_t* __parse_pattern_action (xp_awk_t* awk)
{
/*
BEGIN
@ -143,12 +182,147 @@ static int __parse_pattern_action (xp_awk_t* awk)
pattern, pattern
*/
if (awk->token.type == TOKEN_BEGIN) {
xp_awk_node_t* node;
if (MATCH(awk,TOKEN_BEGIN)) {
CONSUME (awk);
}
else if (awk->token.type == TOKEN_END) {
else if (MATCH(awk,TOKEN_END)) {
CONSUME (awk);
}
/* patterns ...
* etc */
if (!MATCH(awk,TOKEN_LBRACE)) {
PANIC (awk, XP_AWK_ELBRACE);
}
return -1;
CONSUME (awk);
node = __parse_block(awk);
if (node == XP_NULL) return XP_NULL;
return node;
}
/* TODO: what is the best name for the parsing routine for the outermost block? */
static xp_awk_node_t* __parse_block (xp_awk_t* awk)
{
xp_awk_node_block_t* node;
node = (xp_awk_node_block_t*) xp_malloc (xp_sizeof(xp_awk_node_block_t));
if (node == XP_NULL) {
/* TODO: do some clean-up */
PANIC (awk, XP_AWK_ENOMEM);
}
node->type = XP_AWK_NODE_BLOCK;
node->sbls = XP_NULL;
node->body = XP_NULL;
while (1) {
if (MATCH(awk,TOKEN_RBRACE)) {
/* TODO: should finalize a block */
CONSUME (awk);
break;
}
if (MATCH(awk,TOKEN_LBRACE)) {
/* nested block */
CONSUME (awk);
if (__parse_block(awk) == XP_NULL) return XP_NULL;
}
else if (MATCH(awk,TOKEN_IF)) {
CONSUME (awk);
if (__parse_if(awk) == XP_NULL) return XP_NULL;
}
else if (MATCH(awk,TOKEN_WHILE)) {
CONSUME (awk);
if (__parse_while(awk) == XP_NULL) return XP_NULL;
}
else if (MATCH(awk,TOKEN_FOR)) {
CONSUME (awk);
if (__parse_for(awk) == XP_NULL) return XP_NULL;
}
else if (MATCH(awk,TOKEN_DO)) {
CONSUME (awk);
if (__parse_do(awk) == XP_NULL) return XP_NULL;
}
else if (MATCH(awk,TOKEN_BREAK)) {
CONSUME (awk);
node->body = __parse_break(awk);
}
else if (MATCH(awk,TOKEN_CONTINUE)) {
CONSUME (awk);
node->body = __parse_continue(awk);
}
else if (MATCH(awk,TOKEN_RETURN)) {
CONSUME (awk);
/* TOOD: */
}
else if (MATCH(awk, TOKEN_EXIT)) {
CONSUME (awk);
/* TOOD: */
}
else if (MATCH(awk, TOKEN_DELETE)) {
CONSUME (awk);
/* TOOD: */
}
else if (MATCH(awk, TOKEN_NEXT)) {
CONSUME (awk);
/* TOOD: */
}
else if (MATCH(awk, TOKEN_NEXTFILE)) {
CONSUME (awk);
/* TOOD: */
}
}
return 0;
}
static xp_awk_node_t* __parse_if (xp_awk_t* awk)
{
return XP_NULL;
}
static xp_awk_node_t* __parse_while (xp_awk_t* awk)
{
return XP_NULL;
}
static xp_awk_node_t* __parse_for (xp_awk_t* awk)
{
return XP_NULL;
}
static xp_awk_node_t* __parse_do (xp_awk_t* awk)
{
return XP_NULL;
}
static xp_awk_node_t* __parse_break (xp_awk_t* awk)
{
xp_awk_node_t* node;
node = (xp_awk_node_t*) xp_malloc (xp_sizeof(xp_awk_node_t));
if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
node->type = XP_AWK_NODE_BREAK;
/* TODO: do i have to consume a semicolon here???? */
return node;
}
static xp_awk_node_t* __parse_continue (xp_awk_t* awk)
{
xp_awk_node_t* node;
node = (xp_awk_node_t*) xp_malloc (xp_sizeof(xp_awk_node_t));
if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
node->type = XP_AWK_NODE_CONTINUE;
/* TODO: do i have to consume a semicolon here???? */
return node;
}
static int __get_token (xp_awk_t* awk)
@ -266,11 +440,11 @@ static int __get_token (xp_awk_t* awk)
ADD_TOKEN_CHAR (awk, c);
}
else if (c == XP_CHAR('[')) {
SET_TOKEN_TYPE (awk, TOKEN_LBRAKET);
SET_TOKEN_TYPE (awk, TOKEN_LBRACKET);
ADD_TOKEN_CHAR (awk, c);
}
else if (c == XP_CHAR(']')) {
SET_TOKEN_TYPE (awk, TOKEN_RBRAKET);
SET_TOKEN_TYPE (awk, TOKEN_RBRACKET);
ADD_TOKEN_CHAR (awk, c);
}
else {

View File

@ -1,7 +1,14 @@
/*
* $Id: tree.h,v 1.2 2006-01-09 12:51:47 bacon Exp $
*/
#ifndef _XP_AWK_TREE_H_
#define _XP_AWK_TREE_H_
/*
enum TokenType
{
IF, END, ID, NUM, READ, WrITE, UNTIL, ....
IF, END, ID, NUM, READ, WRITE, UNTIL, ....
}
@ -30,3 +37,53 @@ struct treenode
exptype type; <- for type checking...
};
struct node_t
{
int type;
};
*/
enum
{
XP_AWK_NODE_BLOCK,
XP_AWK_NODE_BREAK,
XP_AWK_NODE_CONTINUE
};
typedef struct xp_awk_node_t xp_awk_node_t;
typedef struct xp_awk_node_block_t xp_awk_node_block_t;
typedef struct xp_awk_node_if_t xp_awk_node_if_t;
#define XP_AWK_NODE_HDR \
int type; \
xp_awk_node_t* sbls
struct xp_awk_node_t
{
XP_AWK_NODE_HDR;
};
/*
struct xp_awk_node_plain_t
{
XP_AWK_NODE_HDR;
};
*/
struct xp_awk_node_block_t
{
XP_AWK_NODE_HDR;
xp_awk_node_t* body;
};
struct xp_awk_node_if_t
{
XP_AWK_NODE_HDR;
xp_awk_node_t* cond;
xp_awk_node_t* if_part;
xp_awk_node_t* else_part;
};
#endif