parent
91cec2a12e
commit
7b9a23a53a
|
@ -53,6 +53,7 @@ typedef enum {
|
|||
EXPRESSION_STR,
|
||||
|
||||
EXPRESSION_INDEX,
|
||||
EXPRESSION_MULTI_INDEX,
|
||||
EXPRESSION_FIELD,
|
||||
EXPRESSION_CALL,
|
||||
|
||||
|
@ -62,6 +63,12 @@ typedef enum {
|
|||
|
||||
} npl_expression_type_t;
|
||||
|
||||
typedef struct _npl_expression_list {
|
||||
struct _npl_expression_list *next;
|
||||
|
||||
struct _npl_expression *expr;
|
||||
} npl_expression_list_t;
|
||||
|
||||
typedef struct _npl_expression {
|
||||
union {
|
||||
struct {
|
||||
|
@ -90,6 +97,13 @@ union {
|
|||
struct _npl_expression *index;
|
||||
} arr;
|
||||
|
||||
struct {
|
||||
npl_expression_type_t type; /* EXPRESSION_MULTI_INDEX */
|
||||
|
||||
struct _npl_expression *base;
|
||||
npl_expression_list_t *indexes;
|
||||
} aarr;
|
||||
|
||||
struct {
|
||||
npl_expression_type_t type; /* EXPRESSION_FIELD */
|
||||
|
||||
|
@ -118,13 +132,7 @@ union {
|
|||
npl_expression_type_t type; /* EXPRESSION_CALL */
|
||||
|
||||
struct _npl_expression *fn;
|
||||
|
||||
struct _npl_expression_list {
|
||||
struct _npl_expression_list *next;
|
||||
|
||||
struct _npl_expression *expr;
|
||||
|
||||
} *args;
|
||||
npl_expression_list_t *args;
|
||||
|
||||
} call;
|
||||
|
||||
|
@ -222,7 +230,7 @@ typedef struct _npl_statement {
|
|||
} w;
|
||||
|
||||
struct {
|
||||
npl_statement_type_t type; /* STATEMTN_TABLE */
|
||||
npl_statement_type_t type; /* STATEMENT_TABLE */
|
||||
|
||||
npl_table_t data;
|
||||
} t;
|
||||
|
@ -251,7 +259,8 @@ typedef struct _npl_statement {
|
|||
npl_expression_t *format;
|
||||
struct _npl_statements *sts;
|
||||
|
||||
struct hfinfo *hfi; /* set by code gen */
|
||||
/* after 1st pass of code generator */
|
||||
struct hfinfo *hfi;
|
||||
} f;
|
||||
|
||||
};
|
||||
|
@ -292,12 +301,16 @@ typedef struct {
|
|||
npl_expression_t *display_format;
|
||||
npl_expression_t *size;
|
||||
|
||||
/* after 1st pass of code generator */
|
||||
const char *hf_type;
|
||||
|
||||
} npl_type_t;
|
||||
|
||||
typedef enum {
|
||||
DECL_INVALID = 0,
|
||||
|
||||
DECL_ATTR,
|
||||
DECL_INCLUDE,
|
||||
DECL_STRUCT,
|
||||
DECL_TABLE,
|
||||
DECL_CONST,
|
||||
|
@ -306,8 +319,8 @@ typedef enum {
|
|||
|
||||
} npl_decl_type_t;
|
||||
|
||||
typedef struct _npl_attr {
|
||||
npl_expression_t expr;
|
||||
typedef struct {
|
||||
npl_expression_list_t *expr_list;
|
||||
} npl_attr_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -322,6 +335,12 @@ typedef struct {
|
|||
npl_attr_t data;
|
||||
} a;
|
||||
|
||||
struct {
|
||||
npl_decl_type_t type; /* DECL_INCLUDE */
|
||||
|
||||
char *file;
|
||||
} i;
|
||||
|
||||
struct {
|
||||
npl_decl_type_t type; /* DECL_STRUCT */
|
||||
|
||||
|
@ -362,6 +381,4 @@ typedef struct {
|
|||
|
||||
} *decls;
|
||||
|
||||
int parse_ok;
|
||||
|
||||
} npl_code_t;
|
||||
|
|
351
tools/npl/npl.c
351
tools/npl/npl.c
|
@ -25,7 +25,7 @@
|
|||
#include "ast.h"
|
||||
#include "xmem.h"
|
||||
|
||||
void npl_parse_file(npl_code_t *code, FILE *f, const char *filename); /* parser.l */
|
||||
int npl_parse_file(npl_code_t *code, FILE *f, const char *filename); /* parser.l */
|
||||
|
||||
static void gen_expr(FILE *f, npl_expression_t *e);
|
||||
static void gen_statements(FILE *f, struct _npl_statements *sts);
|
||||
|
@ -39,6 +39,16 @@ struct hfinfo {
|
|||
|
||||
struct hfinfo *hfs;
|
||||
|
||||
static void _fail(const char *file, int line, const char *msg) {
|
||||
fprintf(stderr, "!!! %s:%d fail(%s)\n", file, line, msg);
|
||||
abort();
|
||||
}
|
||||
|
||||
#define fail(msg) _fail(__FILE__, __LINE__, msg)
|
||||
|
||||
#define xassert(expr) \
|
||||
do { if (!(expr)) fail("Assertion failed: " #expr); } while(0);
|
||||
|
||||
|
||||
static struct hfinfo *
|
||||
add_hfi(npl_statement_t *st)
|
||||
|
@ -57,8 +67,9 @@ add_hfi(npl_statement_t *st)
|
|||
}
|
||||
|
||||
static const char *
|
||||
hfi_name(const struct hfinfo *hfi)
|
||||
hfi_var(const struct hfinfo *hfi)
|
||||
{
|
||||
/* XXX nicer name */
|
||||
static char hf_name[64];
|
||||
|
||||
snprintf(hf_name, sizeof(hf_name), "hf_field_%u", hfi->id);
|
||||
|
@ -66,6 +77,127 @@ hfi_name(const struct hfinfo *hfi)
|
|||
return hf_name;
|
||||
}
|
||||
|
||||
static const char *
|
||||
hfi_name(const struct hfinfo *hfi)
|
||||
{
|
||||
return hfi->st->f.id;
|
||||
}
|
||||
|
||||
static const char *
|
||||
hfi_filter(const struct hfinfo *hfi)
|
||||
{
|
||||
/* TODO stub */
|
||||
return "";
|
||||
}
|
||||
|
||||
static const char *
|
||||
hfi_type(const struct hfinfo *hfi)
|
||||
{
|
||||
/* TODO stub */
|
||||
return "FT_BYTES";
|
||||
}
|
||||
|
||||
static const char *
|
||||
hfi_display(const struct hfinfo *hfi)
|
||||
{
|
||||
/* TODO stub */
|
||||
return "BASE_NONE";
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
hfi_mask(const struct hfinfo *hfi)
|
||||
{
|
||||
/* TODO stub */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
expr_to_int(const npl_expression_t *npl, int *val)
|
||||
{
|
||||
if (npl->type == EXPRESSION_INT) {
|
||||
*val = npl->num.digit;
|
||||
return 1;
|
||||
}
|
||||
if (npl->type == EXPRESSION_UNARY) {
|
||||
if (!expr_to_int(npl->u.operand, val))
|
||||
return 0;
|
||||
|
||||
switch (npl->u.operator) {
|
||||
case OP1_MINUS:
|
||||
*val = -(*val);
|
||||
return 1;
|
||||
case OP1_NEG:
|
||||
*val = ~(*val);
|
||||
return 1;
|
||||
case OP1_NOT:
|
||||
*val = !(*val);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
expr_to_str(const npl_expression_t *npl, const char **val)
|
||||
{
|
||||
if (npl->type == EXPRESSION_STR) {
|
||||
*val = npl->str.str;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *
|
||||
type_to_ft(const npl_type_t *t, int size)
|
||||
{
|
||||
switch (t->type) {
|
||||
case FIELD_DECIMAL:
|
||||
if (size == 4)
|
||||
return "FT_FLOAT";
|
||||
if (size == 8)
|
||||
return "FT_DOUBLE";
|
||||
|
||||
fprintf(stderr, "!!! decimal, size: %d\n", size);
|
||||
return NULL;
|
||||
|
||||
case FIELD_NUMBER:
|
||||
if (size == 1)
|
||||
return "FT_INT8";
|
||||
if (size == 2)
|
||||
return "FT_INT16";
|
||||
if (size == 3)
|
||||
return "FT_INT24";
|
||||
if (size == 4)
|
||||
return "FT_INT32";
|
||||
if (size <= 8)
|
||||
return "FT_INT64";
|
||||
|
||||
fprintf(stderr, "!!! number, size: %d\n", size);
|
||||
return NULL;
|
||||
|
||||
case FIELD_UNSIGNED_NUMBER:
|
||||
if (size == 1)
|
||||
return "FT_UINT8";
|
||||
if (size == 2)
|
||||
return "FT_UINT16";
|
||||
if (size == 3)
|
||||
return "FT_UINT24";
|
||||
if (size == 4)
|
||||
return "FT_UINT32";
|
||||
if (size <= 8)
|
||||
return "FT_UINT64";
|
||||
|
||||
fprintf(stderr, "!!! number, size: %d\n", size);
|
||||
return NULL;
|
||||
|
||||
case FIELD_TIME:
|
||||
/* XXX, FT_ABSOLUTE_TIME or FT_RELATIVE_TIME? */
|
||||
fprintf(stderr, "!!! time, size: %d\n", size);
|
||||
return "FT_ABSOLUTE_TIME";
|
||||
}
|
||||
fprintf(stderr, "!!! not handled, type: %d, size: %d\n", t->type, size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define gen_fprintf(f, args...) \
|
||||
do { \
|
||||
|
@ -160,7 +292,7 @@ gen_expr(FILE *f, npl_expression_t *e)
|
|||
|
||||
case EXPRESSION_CALL:
|
||||
{
|
||||
struct _npl_expression_list *arg;
|
||||
npl_expression_list_t *arg;
|
||||
char *ind = "";
|
||||
|
||||
gen_expr(f, e->call.fn);
|
||||
|
@ -173,12 +305,101 @@ gen_expr(FILE *f, npl_expression_t *e)
|
|||
gen_fprintf(f, ")");
|
||||
return;
|
||||
}
|
||||
|
||||
case EXPRESSION_FIELD:
|
||||
gen_expr(f, e->fld.base);
|
||||
gen_fprintf(f, ".%s ", e->fld.field);
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "XXXX expr->type: %d\n", e->type);
|
||||
}
|
||||
|
||||
static int
|
||||
gen_table_struct(FILE *f, npl_table_t *t)
|
||||
{
|
||||
enum { CANT, VALUE_STRING, STRING_STRING } type;
|
||||
struct npl_table_case *c;
|
||||
|
||||
int all_int = 1;
|
||||
int all_str = 1;
|
||||
|
||||
if (t->params.count || !t->switch_expr || t->default_expr)
|
||||
return 0;
|
||||
|
||||
for (c = t->cases; c; c = c->next) {
|
||||
const char *str;
|
||||
int val;
|
||||
|
||||
if (!c->return_expr || !expr_to_str(c->return_expr, &str))
|
||||
return 0;
|
||||
|
||||
if (all_int && !expr_to_int(&c->e, &val))
|
||||
all_int = 0;
|
||||
if (all_str && !expr_to_str(&c->e, &str))
|
||||
all_str = 0;
|
||||
|
||||
if (!all_int && !all_str)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (all_int)
|
||||
type = VALUE_STRING;
|
||||
else if (all_str)
|
||||
type = STRING_STRING;
|
||||
else
|
||||
type = CANT;
|
||||
|
||||
/* table can be converted to value_string, generate one */
|
||||
if (f && type == VALUE_STRING) {
|
||||
gen_fprintf(f,
|
||||
"static const value_string %s[] = {\n",
|
||||
t->id);
|
||||
|
||||
for (c = t->cases; c; c = c->next) {
|
||||
const char *str;
|
||||
int val;
|
||||
|
||||
/* checked above, should not fail now */
|
||||
if (!expr_to_str(c->return_expr, &str))
|
||||
fail("expr_to_str(str)");
|
||||
if (!expr_to_int(&c->e, &val))
|
||||
fail("expr_to_int(val)");
|
||||
|
||||
gen_fprintf(f, "\t{ %x, \"%s\" },\n", val, str);
|
||||
}
|
||||
gen_fprintf(f, "\t{ 0, NULL }\n");
|
||||
gen_fprintf(f, "};\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* table can be converted to string_string, generate one */
|
||||
if (f && type == STRING_STRING) {
|
||||
gen_fprintf(f,
|
||||
"static const string_string %s[] = {\n",
|
||||
t->id);
|
||||
|
||||
for (c = t->cases; c; c = c->next) {
|
||||
const char *str;
|
||||
const char *val;
|
||||
|
||||
/* checked above, should not fail now */
|
||||
if (!expr_to_str(c->return_expr, &str))
|
||||
fail("expr_to_str(str)");
|
||||
if (!expr_to_str(&c->e, &val))
|
||||
fail("expr_to_str(val)");
|
||||
|
||||
gen_fprintf(f, "\t{ \"%s\", \"%s\" },\n", val, str);
|
||||
}
|
||||
gen_fprintf(f, "\t{ NULL, NULL }\n");
|
||||
gen_fprintf(f, "};\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gen_table(FILE *f, npl_table_t *t)
|
||||
gen_table_func(FILE *f, npl_table_t *t)
|
||||
{
|
||||
struct npl_table_case *c;
|
||||
|
||||
|
@ -215,8 +436,7 @@ again1:
|
|||
|
||||
if (!c->return_expr) {
|
||||
c = c->next;
|
||||
if (!c)
|
||||
abort();
|
||||
xassert(c != NULL);
|
||||
gen_fprintf(f, "\n");
|
||||
goto again1;
|
||||
} else {
|
||||
|
@ -244,8 +464,7 @@ again2:
|
|||
if (!c->return_expr) {
|
||||
gen_fprintf(f, " || ");
|
||||
c = c->next;
|
||||
if (!c)
|
||||
abort();
|
||||
xassert(c != NULL);
|
||||
goto again2;
|
||||
} else {
|
||||
gen_fprintf(f, ")\n");
|
||||
|
@ -265,6 +484,14 @@ again2:
|
|||
gen_fprintf(f, "\treturn \"\";\n");
|
||||
|
||||
gen_fprintf(f, "}\n");
|
||||
}
|
||||
|
||||
static void
|
||||
gen_table(FILE *f, npl_table_t *t)
|
||||
{
|
||||
if (!gen_table_struct(f, t))
|
||||
gen_table_func(f, t);
|
||||
|
||||
gen_fprintf(f, "\n");
|
||||
}
|
||||
|
||||
|
@ -297,7 +524,7 @@ gen_statement(FILE *f, npl_statement_t *st)
|
|||
|
||||
if (f) {
|
||||
// XXX, search for st->f.t_id in table.
|
||||
gen_fprintf(f, "\toffset = dissect_%s(tvb, tree, %s, offset);\n", st->f.t_id, hfi_name(st->f.hfi));
|
||||
gen_fprintf(f, "\toffset = dissect_%s(tvb, tree, %s, offset);\n", st->f.t_id, hfi_var(st->f.hfi));
|
||||
}
|
||||
// XXX st->f.bits, st->f.arr, st->f.format, st->f.sts
|
||||
return;
|
||||
|
@ -336,7 +563,6 @@ gen_statement(FILE *f, npl_statement_t *st)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
if (c) {
|
||||
npl_statement_t *default_st = st->sw.data.default_st;
|
||||
|
||||
|
@ -413,6 +639,8 @@ gen_protocol(FILE *f, npl_protocol_t *p)
|
|||
gen_fprintf(f, "{\n");
|
||||
gen_fprintf(f,
|
||||
"\tint offset = 0;\n"
|
||||
"\tproto_tree *tree = NULL;\n"
|
||||
"\tproto_item *ti = NULL;\n"
|
||||
"\n"
|
||||
);
|
||||
|
||||
|
@ -439,8 +667,7 @@ gen_struct(FILE *f, npl_struct_t *s)
|
|||
snprintf(id, sizeof(id), "_noname%u", ++_id);
|
||||
s->id = xstrdup(id);
|
||||
|
||||
if (f != NULL)
|
||||
abort();
|
||||
xassert(f == NULL);
|
||||
}
|
||||
|
||||
if (s->count_expr) {
|
||||
|
@ -498,25 +725,40 @@ gen_struct(FILE *f, npl_struct_t *s)
|
|||
static void
|
||||
gen_const(FILE *f, npl_const_t *c)
|
||||
{
|
||||
// TODO
|
||||
fprintf(stderr, "gen_const() TODO\n");
|
||||
// TODO, later don't do #define, only add to id table with given value.
|
||||
|
||||
gen_fprintf(f, "#define %s", c->id);
|
||||
gen_expr(f, &c->expr);
|
||||
gen_fprintf(f, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
gen_type(FILE *f, npl_type_t *t)
|
||||
{
|
||||
int size = -1;
|
||||
int byte_order = -1;
|
||||
const char *hf_type = NULL;
|
||||
|
||||
gen_fprintf(f,
|
||||
"static int\n"
|
||||
"dissect_type_%s(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)\n"
|
||||
"dissect_type_%s(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int hf, int offset)\n"
|
||||
"{\n", t->name);
|
||||
|
||||
#if 0
|
||||
npl_params_t params;
|
||||
if (t->params.count) {
|
||||
/* XXX */
|
||||
fprintf(stderr, "XXX, t->params.count\n");
|
||||
}
|
||||
|
||||
npl_expression_t *byte_order;
|
||||
npl_expression_t *display_format;
|
||||
npl_expression_t *size;
|
||||
#endif
|
||||
if (t->size && !expr_to_int(t->size, &size))
|
||||
fprintf(stderr, "!!! expr_to_int(size) failed for type: %s\n", t->name);
|
||||
|
||||
if (t->byte_order && !expr_to_int(t->byte_order, &byte_order))
|
||||
fprintf(stderr, "!!! expr_to_int(byte_order) failed for type: %s\n", t->name);
|
||||
|
||||
hf_type = type_to_ft(t, size);
|
||||
/* npl_expression_t *display_format; */
|
||||
|
||||
t->hf_type = hf_type ? hf_type : "FT_BYTES";
|
||||
|
||||
gen_fprintf(f, "\treturn offset;\n");
|
||||
gen_fprintf(f, "}\n");
|
||||
|
@ -526,8 +768,7 @@ gen_type(FILE *f, npl_type_t *t)
|
|||
static void
|
||||
gen_attr(FILE *f, npl_attr_t *a)
|
||||
{
|
||||
// TODO
|
||||
fprintf(stderr, "gen_attr() TODO");
|
||||
fprintf(stderr, "gen_attr() TODO\n");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -571,13 +812,11 @@ gen_hf(FILE *f)
|
|||
struct hfinfo *hfi;
|
||||
|
||||
for (hfi = hfs; hfi; hfi = hfi->next)
|
||||
gen_fprintf(f, "static int %s = -1;\n", hfi_name(hfi));
|
||||
gen_fprintf(f, "static int %s = -1;\n", hfi_var(hfi));
|
||||
}
|
||||
|
||||
static const char proto_name[] = "foo"; /* TODO, hardcoded */
|
||||
|
||||
static void
|
||||
gen_proto_register(FILE *f)
|
||||
gen_proto_register(FILE *f, const char *proto_name)
|
||||
{
|
||||
struct hfinfo *hfi;
|
||||
|
||||
|
@ -589,15 +828,14 @@ gen_proto_register(FILE *f)
|
|||
/* hf array */
|
||||
gen_fprintf(f, "\tstatic hf_register_info hf[] = {\n");
|
||||
for (hfi = hfs; hfi; hfi = hfi->next) {
|
||||
npl_statement_t *st = hfi->st;
|
||||
|
||||
gen_fprintf(f,
|
||||
gen_fprintf(f,
|
||||
"\t\t{ &%s,\n"
|
||||
"\t\t\t{ \"%s\", \"%s\", %s, %s, NULL, 0x%.2x, NULL, HFILL }\n"
|
||||
"\t\t},\n", hfi_name(hfi), st->f.id, "filtr", "typ", "dec", 0x00 );
|
||||
"\t\t},\n", hfi_var(hfi), hfi_name(hfi), hfi_filter(hfi), hfi_type(hfi), hfi_display(hfi), hfi_mask(hfi) );
|
||||
}
|
||||
gen_fprintf(f, "\t}\n\n");
|
||||
|
||||
/* ett array */
|
||||
gen_fprintf(f, "\tstatic gint *ett[] = {\n");
|
||||
#if 0
|
||||
&ett_foo,
|
||||
|
@ -615,14 +853,14 @@ gen_proto_register(FILE *f)
|
|||
}
|
||||
|
||||
static void
|
||||
gen_proto_handoff(FILE *f)
|
||||
gen_proto_handoff(FILE *f, const char *proto_name)
|
||||
{
|
||||
gen_fprintf(f,
|
||||
"void\n"
|
||||
"proto_reg_handoff_%s(void)\n"
|
||||
"{", proto_name);
|
||||
"{\n", proto_name);
|
||||
|
||||
gen_fprintf(f, "dissector_handle_t %s_handle = new_create_dissector_handle(dissect_%s, proto_%s);\n", proto_name, proto_name, proto_name);
|
||||
gen_fprintf(f, "\tdissector_handle_t %s_handle = new_create_dissector_handle(dissect_%s, proto_%s);\n", proto_name, proto_name, proto_name);
|
||||
|
||||
#if 0
|
||||
dissector_add_uint("REG", XXX, %s_handle);
|
||||
|
@ -632,10 +870,24 @@ gen_proto_handoff(FILE *f)
|
|||
gen_fprintf(f, "}\n");
|
||||
}
|
||||
|
||||
static const npl_protocol_t *
|
||||
get_protocol(npl_code_t *code)
|
||||
{
|
||||
struct _npl_decl_list *decl;
|
||||
|
||||
for (decl = code->decls; decl; decl = decl->next) {
|
||||
/* XXX, for now return first */
|
||||
if (decl->d.type == DECL_PROTOCOL)
|
||||
return &decl->d.p.data;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
FILE *f;
|
||||
npl_code_t code;
|
||||
|
||||
int parse_ok;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s filename\n", argv[0]);
|
||||
return 1;
|
||||
|
@ -647,25 +899,36 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
memset(&code, 0, sizeof(code));
|
||||
printf("%s:\n", argv[1]);
|
||||
npl_parse_file(&code, f, argv[1]);
|
||||
|
||||
if (code.parse_ok) {
|
||||
parse_ok = npl_parse_file(&code, f, argv[1]);
|
||||
// parse_ok = 0;
|
||||
if (parse_ok) {
|
||||
const npl_protocol_t *proto = get_protocol(&code);
|
||||
const char *proto_name = (proto) ? proto->id : "noname";
|
||||
FILE *out;
|
||||
|
||||
gen_code(NULL, &code);
|
||||
|
||||
out = fopen("/tmp/npl.c", "w");
|
||||
|
||||
/* TODO declare ett_ */
|
||||
gen_hf(out);
|
||||
/* includes */
|
||||
gen_fprintf(out, "#include \"config.h\"\n");
|
||||
gen_fprintf(out, "#include <glib.h>\n");
|
||||
gen_fprintf(out, "#include <epan/packet.h>\n");
|
||||
gen_fprintf(out, "\n");
|
||||
|
||||
gen_fprintf(out, "\n\n");
|
||||
/* TODO declare forward */
|
||||
|
||||
gen_fprintf(out, "static int proto_%s = -1;\n", proto_name);
|
||||
gen_hf(out);
|
||||
gen_fprintf(out, "\n");
|
||||
|
||||
/* TODO declare ett_ */
|
||||
gen_fprintf(out, "\n");
|
||||
|
||||
gen_code(out, &code);
|
||||
|
||||
gen_proto_register(out);
|
||||
gen_proto_handoff(out);
|
||||
gen_proto_register(out, proto_name);
|
||||
gen_proto_handoff(out, proto_name);
|
||||
|
||||
fclose(out);
|
||||
}
|
||||
|
|
|
@ -485,7 +485,6 @@ parse_params(npl_params_t *p)
|
|||
|
||||
static void parse_expression(npl_expression_t *expr);
|
||||
static npl_expression_t *xparse_expression(void);
|
||||
static npl_expression_t g_e;
|
||||
|
||||
static void
|
||||
parse_primary(npl_expression_t *expr)
|
||||
|
@ -531,6 +530,22 @@ parse_primary(npl_expression_t *expr)
|
|||
nomatch();
|
||||
}
|
||||
|
||||
/* ExpressionList = Expression, { ",", Expression } ; */
|
||||
static void
|
||||
parse_expression_list(npl_expression_list_t **ptr)
|
||||
{
|
||||
do {
|
||||
npl_expression_list_t *cur = xnew(npl_expression_list_t);
|
||||
|
||||
*ptr = cur;
|
||||
ptr = &(cur->next);
|
||||
cur->expr = xparse_expression();
|
||||
|
||||
} while (is_token_accept(TOKEN_COMMA));
|
||||
|
||||
*ptr = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_expression1(npl_expression_t *expr)
|
||||
{
|
||||
|
@ -539,44 +554,33 @@ parse_expression1(npl_expression_t *expr)
|
|||
do {
|
||||
if (is_token_accept(TOKEN_LPAREN)) { /* foo() */
|
||||
npl_expression_t *fun = xdup(npl_expression_t, expr);
|
||||
struct _npl_expression_list **ptr = &(expr->call.args);
|
||||
|
||||
if (!is_token(TOKEN_RPAREN)) {
|
||||
do {
|
||||
struct _npl_expression_list *cur = xnew(struct _npl_expression_list);
|
||||
|
||||
*ptr = cur;
|
||||
ptr = &(cur->next);
|
||||
cur->expr = xparse_expression();
|
||||
|
||||
} while (is_token_accept(TOKEN_COMMA));
|
||||
}
|
||||
*ptr = NULL;
|
||||
npl_expression_list_t *args = NULL;
|
||||
|
||||
if (!is_token(TOKEN_RPAREN))
|
||||
parse_expression_list(&args);
|
||||
accept(TOKEN_RPAREN);
|
||||
expr->call.fn = fun;
|
||||
expr->type = EXPRESSION_CALL;
|
||||
|
||||
} else if (is_token(TOKEN_DOLLAR) || is_token(TOKEN_LBRACKET)) { /* arr$[field1, field2, ...], arr[10] */
|
||||
expr->type = EXPRESSION_CALL;
|
||||
expr->call.fn = fun;
|
||||
expr->call.args = args;
|
||||
|
||||
} else if (is_token_accept(TOKEN_DOLLAR)) { /* arr$[field1, field2, ...] */
|
||||
npl_expression_t *base = xdup(npl_expression_t, expr);
|
||||
npl_expression_list_t *indexes;
|
||||
|
||||
accept(TOKEN_LBRACKET);
|
||||
parse_expression_list(&indexes);
|
||||
accept(TOKEN_RBRACKET);
|
||||
|
||||
expr->type = EXPRESSION_MULTI_INDEX;
|
||||
expr->aarr.base = base;
|
||||
expr->aarr.indexes = indexes;
|
||||
|
||||
} else if (is_token_accept(TOKEN_LBRACKET)) { /* arr[10] */
|
||||
npl_expression_t *base = xdup(npl_expression_t, expr);
|
||||
npl_expression_t *idx;
|
||||
int aa;
|
||||
|
||||
aa = is_token_accept(TOKEN_DOLLAR);
|
||||
accept(TOKEN_LBRACKET);
|
||||
|
||||
idx = xparse_expression();
|
||||
|
||||
if (aa) {
|
||||
while (is_token_accept(TOKEN_COMMA)) {
|
||||
// XXX ast
|
||||
|
||||
npl_expression_t *idx2;
|
||||
|
||||
idx2 = xparse_expression();
|
||||
}
|
||||
}
|
||||
|
||||
accept(TOKEN_RBRACKET);
|
||||
|
||||
expr->type = EXPRESSION_INDEX;
|
||||
|
@ -921,21 +925,27 @@ static int is_attribute(void) { return is_token(TOKEN_LBRACKET); }
|
|||
static void
|
||||
parse_attributes(npl_attr_t *attr)
|
||||
{
|
||||
npl_expression_list_t **ptr = &attr->expr_list;
|
||||
|
||||
accept(TOKEN_LBRACKET);
|
||||
|
||||
do {
|
||||
parse_expression(&attr->expr);
|
||||
npl_expression_list_t *cur = xnew(npl_expression_list_t);
|
||||
|
||||
*ptr = cur;
|
||||
ptr = &(cur->next);
|
||||
cur->expr = xparse_expression();
|
||||
|
||||
if (is_token_accept(TOKEN_SEMICOLON))
|
||||
{ }
|
||||
else if (is_token_accept(TOKEN_COMMA))
|
||||
{ }
|
||||
|
||||
}
|
||||
while (!is_token(TOKEN_RBRACKET));
|
||||
// while (is_token_accept(TOKEN_COMMA));
|
||||
|
||||
accept(TOKEN_RBRACKET);
|
||||
*ptr = NULL;
|
||||
}
|
||||
|
||||
static void parse_statement(npl_statement_t *st);
|
||||
|
@ -1007,8 +1017,6 @@ parse_dynamic_switch(npl_switch_t *sw)
|
|||
is_token_accept(TOKEN_SEMICOLON);
|
||||
}
|
||||
|
||||
static void parse_table(npl_table_t *);
|
||||
|
||||
static int is_statement(void) {
|
||||
return
|
||||
is_token(TOKEN_WHILE) ||
|
||||
|
@ -1076,6 +1084,7 @@ xparse_formatting(void)
|
|||
return format;
|
||||
}
|
||||
|
||||
static void parse_table(npl_table_t *);
|
||||
static void parse_struct(npl_struct_t *s, int statement);
|
||||
|
||||
static void
|
||||
|
@ -1128,12 +1137,12 @@ parse_statement(npl_statement_t *st)
|
|||
|
||||
if (is_token_accept(TOKEN_LPAREN)) {
|
||||
/* XXX, WTF: StringTerm(Property.XMLEncoding, "<", true, false, false) Reason; */
|
||||
npl_expression_list_t *type_params;
|
||||
|
||||
do {
|
||||
/* XXX, ast */
|
||||
parse_expression(&g_e);
|
||||
} while (is_token_accept(TOKEN_COMMA));
|
||||
parse_expression_list(&type_params);
|
||||
accept(TOKEN_RPAREN);
|
||||
|
||||
/* XXX, store type_params in ast */
|
||||
}
|
||||
|
||||
st->f.id = accept_id();
|
||||
|
@ -1375,13 +1384,12 @@ parse_decl(npl_decl_t *d)
|
|||
parse_protocol(&d->p.data);
|
||||
|
||||
} else if (is_type()) {
|
||||
parse_type(&d->ty.data);
|
||||
d->type = DECL_TYPE;
|
||||
parse_type(&d->ty.data);
|
||||
|
||||
} else if (is_token_accept(TOKEN_INCLUDE)) {
|
||||
/* XXX, ast */
|
||||
char *file = accept_str();
|
||||
free(file);
|
||||
d->type = DECL_INCLUDE;
|
||||
d->i.file = accept_str(); /* XXX, it's C-escaped */ /* XXX, unix / vs dos \\ */
|
||||
|
||||
} else
|
||||
nomatch();
|
||||
|
@ -1404,16 +1412,19 @@ parse_npl(npl_code_t *code)
|
|||
*ptr = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
npl_parse_file(npl_code_t *code, FILE *f, const char *filename)
|
||||
{
|
||||
int parse_ok = 0;
|
||||
yyfilename = filename;
|
||||
yyin = f;
|
||||
|
||||
next_token();
|
||||
parse_npl(code);
|
||||
code->parse_ok = 1;
|
||||
parse_ok = 1;
|
||||
|
||||
yylex_destroy();
|
||||
|
||||
return parse_ok;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ static inline void *xmalloc(size_t s) { void *ptr = malloc(s); if (!ptr) oom_kil
|
|||
static inline void *xrealloc(void *p, size_t s) { void *ptr = realloc(p, s); if (!ptr) oom_killer(); return ptr; }
|
||||
|
||||
static inline void *xmemdup(void *p, size_t s) { void *ptr = malloc(s); if (!ptr) oom_killer(); return memcpy(ptr, p, s); }
|
||||
static inline void *xstrdup(const char *s) { void *ptr = strdup(s); if (!ptr) oom_killer(); return ptr; }
|
||||
static inline char *xstrdup(const char *s) { void *ptr = strdup(s); if (!ptr) oom_killer(); return ptr; }
|
||||
|
||||
#define xnew(x) (x *) xmalloc(sizeof(x))
|
||||
#define xdup(x, y) (x *) xmemdup(y, sizeof(x))
|
||||
|
|
Loading…
Reference in New Issue