*** empty log message ***
This commit is contained in:
parent
4b2bfa9257
commit
35990d18e5
@ -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>
|
#include <xp/awk/awk.h>
|
||||||
@ -20,6 +20,7 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk)
|
|||||||
return XP_NULL;
|
return XP_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
awk->tree = XP_NULL;
|
||||||
awk->errnum = XP_AWK_ENOERR;
|
awk->errnum = XP_AWK_ENOERR;
|
||||||
|
|
||||||
awk->src_func = XP_NULL;
|
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)
|
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;
|
if (xp_awk_detsrc(awk) == -1) return -1;
|
||||||
xp_str_close (&awk->token.name);
|
xp_str_close (&awk->token.name);
|
||||||
if (awk->__dynamic) xp_free (awk);
|
if (awk->__dynamic) xp_free (awk);
|
||||||
|
@ -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_
|
#ifndef _XP_AWK_AWK_H_
|
||||||
@ -8,6 +8,7 @@
|
|||||||
#include <xp/types.h>
|
#include <xp/types.h>
|
||||||
#include <xp/macros.h>
|
#include <xp/macros.h>
|
||||||
#include <xp/bas/str.h>
|
#include <xp/bas/str.h>
|
||||||
|
#include <xp/awk/tree.h>
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -16,8 +17,11 @@ enum
|
|||||||
XP_AWK_ESRCOP,
|
XP_AWK_ESRCOP,
|
||||||
XP_AWK_ESRCCL,
|
XP_AWK_ESRCCL,
|
||||||
XP_AWK_ESRCDT, /* error in reading source */
|
XP_AWK_ESRCDT, /* error in reading source */
|
||||||
|
|
||||||
XP_AWK_ELXCHR, /* lexer came accross an wrong character */
|
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
|
struct xp_awk_t
|
||||||
{
|
{
|
||||||
|
/* parse tree */
|
||||||
|
xp_awk_node_t* tree;
|
||||||
|
|
||||||
/* io functions */
|
/* io functions */
|
||||||
xp_awk_io_t src_func;
|
xp_awk_io_t src_func;
|
||||||
xp_awk_io_t inp_func;
|
xp_awk_io_t inp_func;
|
||||||
|
212
ase/awk/parse.c
212
ase/awk/parse.c
@ -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/awk.h>
|
||||||
|
#include <xp/awk/tree.h>
|
||||||
|
#include <xp/awk/tree.h>
|
||||||
#include <xp/bas/memory.h>
|
#include <xp/bas/memory.h>
|
||||||
#include <xp/bas/ctype.h>
|
#include <xp/bas/ctype.h>
|
||||||
#include <xp/bas/string.h>
|
#include <xp/bas/string.h>
|
||||||
@ -26,8 +28,8 @@ enum
|
|||||||
TOKEN_RPAREN,
|
TOKEN_RPAREN,
|
||||||
TOKEN_LBRACE,
|
TOKEN_LBRACE,
|
||||||
TOKEN_RBRACE,
|
TOKEN_RBRACE,
|
||||||
TOKEN_LBRAKET,
|
TOKEN_LBRACKET,
|
||||||
TOKEN_RBRAKET,
|
TOKEN_RBRACKET,
|
||||||
|
|
||||||
TOKEN_STRING,
|
TOKEN_STRING,
|
||||||
TOKEN_REGEX,
|
TOKEN_REGEX,
|
||||||
@ -37,15 +39,29 @@ enum
|
|||||||
TOKEN_END,
|
TOKEN_END,
|
||||||
TOKEN_FUNCTION,
|
TOKEN_FUNCTION,
|
||||||
TOKEN_IF,
|
TOKEN_IF,
|
||||||
TOKEN_DO,
|
|
||||||
TOKEN_WHILE,
|
TOKEN_WHILE,
|
||||||
TOKEN_FOR,
|
TOKEN_FOR,
|
||||||
|
TOKEN_DO,
|
||||||
|
TOKEN_BREAK,
|
||||||
TOKEN_CONTINUE,
|
TOKEN_CONTINUE,
|
||||||
TOKEN_BREAK
|
TOKEN_RETURN,
|
||||||
|
TOKEN_EXIT,
|
||||||
|
TOKEN_DELETE,
|
||||||
|
TOKEN_NEXT,
|
||||||
|
TOKEN_NEXTFILE
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __parse (xp_awk_t* awk);
|
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_token (xp_awk_t* awk);
|
||||||
static int __get_char (xp_awk_t* awk);
|
static int __get_char (xp_awk_t* awk);
|
||||||
static int __unget_char (xp_awk_t* awk, xp_cint_t c);
|
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("END"), TOKEN_END },
|
||||||
{ XP_TEXT("function"), TOKEN_FUNCTION },
|
{ XP_TEXT("function"), TOKEN_FUNCTION },
|
||||||
{ XP_TEXT("if"), TOKEN_IF },
|
{ XP_TEXT("if"), TOKEN_IF },
|
||||||
{ XP_TEXT("do"), TOKEN_DO },
|
|
||||||
{ XP_TEXT("while"), TOKEN_WHILE },
|
{ XP_TEXT("while"), TOKEN_WHILE },
|
||||||
{ XP_TEXT("for"), TOKEN_FOR },
|
{ XP_TEXT("for"), TOKEN_FOR },
|
||||||
{ XP_TEXT("continue"), TOKEN_CONTINUE },
|
{ XP_TEXT("do"), TOKEN_DO },
|
||||||
{ XP_TEXT("break"), TOKEN_BREAK },
|
{ 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 },
|
{ XP_NULL, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -98,20 +119,36 @@ static struct __kwent __kwtab[] =
|
|||||||
#define GET_TOKEN(awk) \
|
#define GET_TOKEN(awk) \
|
||||||
do { if (__get_token(awk) == -1) return -1; } while(0)
|
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)
|
int xp_awk_parse (xp_awk_t* awk)
|
||||||
{
|
{
|
||||||
|
xp_awk_node_t* node;
|
||||||
|
|
||||||
GET_CHAR (awk);
|
GET_CHAR (awk);
|
||||||
GET_TOKEN (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 }
|
pattern { action }
|
||||||
function name (parameter-list) { statement }
|
function name (parameter-list) { statement }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
xp_awk_node_t* node;
|
||||||
|
|
||||||
|
/*
|
||||||
while (1) {
|
while (1) {
|
||||||
if (awk->token.type == TOKEN_FUNCTION) {
|
if (awk->token.type == TOKEN_FUNCTION) {
|
||||||
if (__parse_function_declaration(awk) == -1) return -1;
|
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;
|
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
|
BEGIN
|
||||||
@ -143,12 +182,147 @@ static int __parse_pattern_action (xp_awk_t* awk)
|
|||||||
pattern, pattern
|
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)
|
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);
|
ADD_TOKEN_CHAR (awk, c);
|
||||||
}
|
}
|
||||||
else if (c == XP_CHAR('[')) {
|
else if (c == XP_CHAR('[')) {
|
||||||
SET_TOKEN_TYPE (awk, TOKEN_LBRAKET);
|
SET_TOKEN_TYPE (awk, TOKEN_LBRACKET);
|
||||||
ADD_TOKEN_CHAR (awk, c);
|
ADD_TOKEN_CHAR (awk, c);
|
||||||
}
|
}
|
||||||
else if (c == XP_CHAR(']')) {
|
else if (c == XP_CHAR(']')) {
|
||||||
SET_TOKEN_TYPE (awk, TOKEN_RBRAKET);
|
SET_TOKEN_TYPE (awk, TOKEN_RBRACKET);
|
||||||
ADD_TOKEN_CHAR (awk, c);
|
ADD_TOKEN_CHAR (awk, c);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -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
|
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...
|
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user