From a61ad1cef9ef77f9afd67230df5470b6b55525be Mon Sep 17 00:00:00 2001 From: FreeArtMan <=> Date: Thu, 17 Dec 2015 20:59:18 +0000 Subject: Initial commit --- .gitignore | 4 + Makefile | 20 ++ ast.c | 0 ast.h | 0 darray.c | 335 ++++++++++++++++++++++++++++++++ darray.h | 53 +++++ debug.h | 69 +++++++ dm.c | 259 +++++++++++++++++++++++++ dm.h | 16 ++ dm_parser.c | 323 +++++++++++++++++++++++++++++++ dm_parser.ragel | 95 +++++++++ exper.c | 15 ++ mtable.c | 107 ++++++++++ mtable.h | 36 ++++ syntax.c | 559 +++++++++++++++++++++++++++++++++++++++++++++++++++++ syntax.h | 123 ++++++++++++ test.h | 19 ++ test/alleatures.dm | 10 + test/elf32.bin | 1 + test/elf32.md | 13 ++ test/manyifs.md | 12 ++ test/one_byte.dm | 3 + test/range.md | 3 + test/rangeif.md | 3 + test/simpleif.md | 2 + test/test.bin | 1 + test/two_byte.md | 13 ++ tokenizer.c | 141 ++++++++++++++ tokenizer.h | 53 +++++ 29 files changed, 2288 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 ast.c create mode 100644 ast.h create mode 100644 darray.c create mode 100644 darray.h create mode 100644 debug.h create mode 100644 dm.c create mode 100644 dm.h create mode 100644 dm_parser.c create mode 100644 dm_parser.ragel create mode 100644 exper.c create mode 100644 mtable.c create mode 100644 mtable.h create mode 100644 syntax.c create mode 100644 syntax.h create mode 100644 test.h create mode 100644 test/alleatures.dm create mode 100644 test/elf32.bin create mode 100644 test/elf32.md create mode 100644 test/manyifs.md create mode 100644 test/one_byte.dm create mode 100644 test/range.md create mode 100644 test/rangeif.md create mode 100644 test/simpleif.md create mode 100644 test/test.bin create mode 100644 test/two_byte.md create mode 100644 tokenizer.c create mode 100644 tokenizer.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..af4e307 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.o +dm +*.txt +*.cc diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..11b00bd --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +PROJECT=dm +CC=gcc +CFLAGS=-std=c1x +SOURCES=$(PROJECT)_parser.c darray.c tokenizer.c syntax.c mtable.c +OBJECTS=$(SOURCES:.c=.o) + +all: clean ragel $(OBJECTS) $(PROJECT) + +$(PROJECT): + $(CC) $(CFLAGS) $(OBJECTS) $(PROJECT).c -o $(PROJECT) + +ragel: + ragel $(PROJECT)_parser.ragel + +%.o: %.c + $(CC) $(CFLAGS) -c $< + +clean: + rm -f $(PROJECT) + rm -f *.o diff --git a/ast.c b/ast.c new file mode 100644 index 0000000..e69de29 diff --git a/ast.h b/ast.h new file mode 100644 index 0000000..e69de29 diff --git a/darray.c b/darray.c new file mode 100644 index 0000000..eb9886f --- /dev/null +++ b/darray.c @@ -0,0 +1,335 @@ +#include "darray.h" + +/*****************************************************************************/ +darray* darr_create(ssize_t data_size, ssize_t init_size) +{ + //PRINT("\n"); + int i = 0; + darray *arr = NULL; + + if ( init_size <= 0 ) + { + printf("initial darray size should be >0\n"); + goto error; + } + + arr = malloc(sizeof(darray)); + if ( arr == NULL ) + { + printf("cannot allocalte mem\n"); + goto error; + } + arr->max = init_size; + + arr->data = malloc(init_size*sizeof(uint8_t *)); + if (arr->data == NULL) + { + printf("Cannot allocate mem for data\n"); + goto error; + } + + for (i=0;idata[i] = NULL; + } + + arr->end = 0; + arr->size = data_size; + arr->expand = DEFAULT_EXPAND_RATE; + + return arr; + +error: + if ( arr != NULL ) + { + free( arr ); + arr = NULL; + } + //ERROR("\n"); + return NULL; +} + + +/*****************************************************************************/ +void darr_destroy(darray *da) +{ + //PRINT("\n"); + if(da) + { + if(da->data) + { + free(da->data); + } + free(da); + da = NULL; + } +} + + +/*****************************************************************************/ +void darr_clear(darray *da) +{ + //PRINT("\n"); + int i = 0; + if(da->size > 0) + { + for(i = 0; i < da->max; i++) + { + if(da->data[i] != NULL) + { + free(da->data[i]); + } + } + } +} + +/*****************************************************************************/ +void darr_clear_idx(darray *da, int idx) +{ + if ( idx > da->max ) + { + return; + } + if (idx > da->end ) + { + return; + } + if (da->data[idx] != NULL) + { + //PRINT("free=0x%08x\n", da->data[idx]); + free( da->data[idx] ); + da->data[idx] = NULL; + } +} + +/*****************************************************************************/ +int darr_expand(darray *da) +{ + //PRINT("\n"); + size_t old_max = da->max; + + if ( darr_resize(da, da->max + da->expand ) != 0 ) + { + printf("Couldnt resize\n"); + goto error; + } + + memset(da->data + old_max, 0, da->expand + 1); + return 0; + +error: + //ERROR("\n"); + return -1; +} + + +/*****************************************************************************/ +int darr_resize(darray *da, ssize_t size) +{ + //PRINT("\n"); + int i = 0; + void *data = NULL; + + if (size < 1) + { + printf("new size smaller then 1\n"); + goto error; + } + + //PRINT("max-0x%08x=new-0x%08x\n",da->max, size); + + if (size < da->max) + { + i = da->max; + do + { + if ( da->data[i-1] != NULL ) + { + free(da->data[i-1]); + da->data[i-1] = NULL; + } + i -= 1; + } while ( i-1 == size ); + } + + da->max = size; + + + + + data = realloc(da->data, da->max * sizeof(void *)); + // check contents and assume realloc doesn't harm the original on error + + if ( data == NULL ) + { + printf("Cannot relocate data\n"); + goto error; + } + + da->data = data; + + return 0; +error: + //ERROR("\n"); + return -1; +} + + +/*****************************************************************************/ +int darr_contract(darray *da) +{ + //PRINT("\n"); + int sz = -1; + + if ( da->end < da->expand ) + { + sz = da->expand; + } else { + sz = da->end; + } + + return darr_resize(da, sz + 1); +} + + +/*****************************************************************************/ +int darr_push(darray *da, void *val) +{ + //PRINT("\n"); + if (da->data[da->end] != NULL) + { + //ERROR("\n"); + + } + + da->data[da->end] = val; + da->end++; + + if(darr_end(da) >= darr_max(da)) + { + return darr_expand(da); + } + + return 0; +} + + +/*****************************************************************************/ +void* darr_pop(darray *da) +{ + //PRINT("\n"); + void *val = NULL; + + if ( da->end-1 < 0 ) + { + printf("Cannot pop value empty stack\n"); + goto error; + } + + val = darr_remove(da, da->end - 1); + da->end--; + + if((darr_end(da) > (int)da->expand) && + (darr_end(da) % da->expand)) + { + darr_contract(da); + } + + return val; + +error: + //ERROR("\n"); + return NULL; +} + + +/*****************************************************************************/ +void darr_clear_destroy(darray *da) +{ + //PRINT("\n"); + darr_clear(da); + darr_destroy(da); +} + + +/*****************************************************************************/ +int darr_set(darray *da, int idx, void *val) +{ + //PRINT("\n"); + if ( idx >= da->max ) + { + printf("setting param out of range\n"); + goto error; + } + if(idx > da->end) + { + da->end = idx; + } + + //PRINT("idx=%d ptr=%x\n",idx,val); + + da->data[idx] = val; + return 0; +error: + //ERROR("\n"); + return -1; +} + + +/*****************************************************************************/ +void* darr_get(darray *da, int idx) +{ + //PRINT("\n"); + if ( idx >= da->end ) + { + printf("gettin value out of range\n"); + goto error; + } + //PRINT("idx=%d\n",idx); + //PRINT("end=%d\n",da->end); + //PRINT("max=%d\n",da->max); + //PRINT("data=0x%x\n",da->data); + return da->data[idx]; +error: + //ERROR("\n"); + return NULL; +} + + +/*****************************************************************************/ +void* darr_remove(darray *da, int idx) +{ + //PRINT("\n"); + void *val = NULL; + val = da->data[idx]; + da->data[idx] = NULL; + return val; +} + + +/*****************************************************************************/ +void* darr_new(darray *da) +{ + //PRINT("\n"); + if ( da->size < 1 ) + { + printf("data element size <1\n"); + goto error; + } + + return calloc(1, da->size); + +error: + //ERROR("\n"); + return NULL; +} + +/*****************************************************************************/ +int darr_isidx(darray *da, int idx) +{ + if ( idx < 0) + return 0; + if ( idx < da->end ) + return 1; + return 0; +} diff --git a/darray.h b/darray.h new file mode 100644 index 0000000..8d8f9e9 --- /dev/null +++ b/darray.h @@ -0,0 +1,53 @@ +/* Some thx goes to http://c.learncodethehardway.org/book/ex34.html */ +#ifndef __LIBADT_DARRAY_H +#define __LIBADT_DARRAY_H + +#include +#include +#include +#include +#include + +//#include "debug.h" +//#include "mmm.h" + +#define DEFAULT_EXPAND_RATE 10 + +typedef struct darray { + int end; //element amount. end <= max + int max; //maximal element number + size_t size; //single element size + size_t expand; //expand size + void **data; +} darray; + +darray* darr_create(ssize_t data_size, ssize_t init_size); +void darr_destroy(darray *da); +void darr_clear(darray *da); +void darr_clear_idx(darray *da, int idx); +int darr_expand(darray *da); +int darr_resize(darray *da, ssize_t size); +int darr_contract(darray *da); +int darr_push(darray *da, void *val); +void* darr_pop(darray *da); +void darr_clear_destroy(darray *da); +int darr_set(darray *da, int idx, void *val); +void* darr_get(darray *da, int idx); +void* darr_remove(darray *da, int idx); +void* darr_new(darray *da); +int darr_isidx(darray *da, int idx); + +#define darr_last(A) ((A)->data[(A)->end - 1]) +#define darr_first(A) ((A)->data[0]) +#define darr_end(A) ((A)->end) +#define darr_count(A) darr_end(A) +#define darr_max(A) ((A)->max) +#define darr_free(E) free((E)) + +/* +when do set it just overwrite data without checking if there is some or not +if set more then max then no error and no resize happens +when get element if error then NULL if value NULL then NULL how distinguish +*/ + +#endif diff --git a/debug.h b/debug.h new file mode 100644 index 0000000..fdcaf86 --- /dev/null +++ b/debug.h @@ -0,0 +1,69 @@ +#ifndef __RB_DEBUG_UTILS_H +#define __RB_DEBUG_UTILS_H + +//what about kprintf? + +//config options +#define PRINTF printf +#define COLORIZE +#define PRINT_LINENUM +#define PRINT_FILENAME +#define PRINT_DEBUG + + +//use color +#ifdef COLORIZE + #define D_COLOR "1;32m" + #define D_COLOR_S "\033[" D_COLOR + #define D_COLOR_E "\033[0m" + #define E_COLOR "1;31m" + #define E_COLOR_S "\033[" E_COLOR + #define E_COLOR_E "\033[0m" +#else + #define D_COLOR + #define D_COLOR_S + #define D_COLOR_E + #define E_COLOR + #define E_COLOR_S + #define E_COLOR_E +#endif + +//print debug line +#ifdef PRINT_LINENUM + #define PRINT_LINE_F ":%03d " + #define PRINT_LINE_D __LINE__ +#else + #define PRINT_LINE_F "" + #define PRINT_LINE_D "" +#endif + +//print +#ifdef PRINT_FILENAME + #define PRINT_FILE_F "FILE:%s" + #define PRINT_FILE_D __FILE__ +#else + #define PRINT_FILE_F "" + #define PRINT_FILE_D "" +#endif + +//print debug string +#ifdef PRINT_DEBUG + #define PRINT_DEBUG_F "Debug: " +#else + #define PRINT_DEBUG_F "" +#endif + +#define PRINT( format, args ... ) PRINTF( D_COLOR_S PRINT_DEBUG_F \ + PRINT_FILE_F PRINT_LINE_F format D_COLOR_E, PRINT_FILE_D, \ + PRINT_LINE_D, ##args); + +#define ERROR( format, args ... ) PRINTF( E_COLOR_S PRINT_DEBUG_F \ + PRINT_FILE_F PRINT_LINE_F format E_COLOR_E, PRINT_FILE_D, \ + PRINT_LINE_D, ##args); + +#define PNL() PRINT("\n"); + +#define ENL() ERROR("\n"); + + +#endif diff --git a/dm.c b/dm.c new file mode 100644 index 0000000..95a5763 --- /dev/null +++ b/dm.c @@ -0,0 +1,259 @@ +#include +#include +#include +#include + +#include + +#include "dm.h" +#include "syntax.h" +#include "mtable.h" + + +/*****************************************************************************/ +int ast2tb( ast_root *ast, mt_table *mt ) +{ + int i,j,k; + ast_range *arng = NULL; + mt_range *mrng = NULL; + + for (i=0;itotal_tokens;i++) + { + arng = ast->range[i]; + + if ((arng->val != NULL) && (arng->iff == NULL)) + { + mrng = malloc(sizeof(mt_range)); + memset(mrng,0,sizeof(mt_range)); + + mrng->start = arng->start; + mrng->end = arng->end; + mrng->val = arng->val->note; + mrng->val_sz = arng->val->size; + + mt_add( mt, mrng ); + } + + if (arng->iff == NULL) continue; + + for (j=0;jsize_iff;j++) + { + unsigned char *cmp=NULL; + + if (arng->iff[j]->expr->size_cmp > 0) + { + mrng = malloc(sizeof(mt_range)); + memset(mrng,0,sizeof(mt_range)); + + //set start end positions + mrng->start = arng->start; + mrng->end = arng->end; + + cmp = malloc(arng->iff[j]->expr->size_cmp); + for (k=0;kiff[j]->expr->size_cmp;k++) + cmp[k] = arng->iff[j]->expr->cmp[k]->val; + mrng->cmp = cmp; + mrng->cmp_sz = arng->iff[j]->expr->size_cmp; + + if (arng->iff[j]->val != NULL) + { + mrng->val = arng->iff[j]->val->note; + mrng->val_sz = arng->iff[j]->val->size; + } + + mt_add( mt, mrng ); + } + } + } + + return 0; +} + +/*****************************************************************************/ +/* primitive matchin for loop, get table sorted then more advanced solution + * maycome */ +int match( mt_table *mt, unsigned char *buf, size_t size ) +{ + //anonymouse function + int pr(char *str, int sz) + { + int i; + for (i=0;istart >= 0 && rng->start < size) + { + if ( rng->cmp_sz == 0) + { + printf("Byte %d match ", rng->start); + pr(rng->val,rng->val_sz); + printf("\n"); + } else if (rng->cmp_sz == 1) + { + if (buf[rng->start] == ((unsigned char*)rng->cmp)[0]) + { + printf("Byte %d match ", rng->start); + pr(rng->val,rng->val_sz); + printf("\n"); + } + } else + { + printf("Cmp %d size not yet supported\n",rng->cmp_sz); + } + } + } + + return 0; +} + +/*****************************************************************************/ +void helper( char *progname ) +{ + printf("Usage: %s [OPTS] \n\n" + "-f [BINFILE]\n" + "-m [DATAMACHFILE]\n" + "Version: %s \n" + "Example: %s -f bin.bin -m test/one_byte.md\n" + , progname, __VER__, progname); +} + + +/*****************************************************************************/ +void version() +{ + printf("Datamatch Version: %s \n", __VER__); +} + + +/*****************************************************************************/ +int main(int argc, char **argv) +{ + FILE *fin = NULL; + FILE *fdm = NULL; + struct stat st; + token_list *tl = NULL; + mt_table *mt = NULL; + ast_root *ast = NULL; + int c; + char *input_file = NULL; + char *datamach_file = NULL; + char *buf = NULL; + char *binbuf = NULL; + ssize_t binbuf_size = 0; + + /*get cmd args and set options */ + while ( (c = getopt(argc, argv, "f:m:v")) != -1 ) + { + switch(c) + { + case 'f': + input_file = optarg; + break; + case 'm': + datamach_file = optarg; + break; + case 'v': + version(); + exit(1); + break; + default: + helper( argv[0] ); + exit(1); + } + } + + if ((datamach_file == NULL) || (input_file == NULL)) + { + printf("Should be set -f and -m\n"); + return -1; + } + + if ( stat( datamach_file, &st) ) + { + printf("Cannot stat file %s\n", datamach_file ); + return -1; + } + + if ( stat( input_file, &st) ) + { + printf("Cannot stat file %s\n", input_file ); + return -1; + } + + + tl = tl_create(); + mt = mt_create(); + if (mt == NULL) + { + printf("Cannot create table\n"); + return -1; + } + + + fdm = fopen( datamach_file, "r+" ); + if ( fdm ) + { + fseek( fdm, 0, SEEK_SET ); + stat( datamach_file, &st ); + buf = malloc( st.st_size+1 ); memset( buf, 0, st.st_size+1 ); + size_t r_size = fread( buf, 1, st.st_size, fdm ); + if ( r_size > 0 ) + { + int ret = parse_dm( tl, buf ); + //printf("Datamatch %d %d bytes\n", ret, r_size ); + } else + { + printf("ERR: while reading file %s [%d]\n", argv[1], r_size); + } + fclose( fdm ); + } else + { + printf("ERR: Cannot open file\n"); + return -1; + } + + fin = fopen( input_file, "r+" ); + if (fin) + { + fseek( fin, 0, SEEK_SET ); + stat( input_file, &st ); + binbuf = malloc( st.st_size ); + memset( binbuf, 0, st.st_size ); + binbuf_size = fread( binbuf, 1, st.st_size, fin ); + + fclose( fin ); + } else + { + printf("ERR:Cannot open binary file\n\n"); + return -1; + } + + /* print tokens */ + //printf("print token_list\n"); + //tl_str( tl ); + //printf("end token_list\n"); + ast = ast_syntax( tl ); + //printf("ast = 0x%08x\n", ast); + + //print_ast( ast ); + ast2tb( ast, mt ); + //mt_print( mt ); + + match( mt, binbuf, binbuf_size ); + + tl_destroy( tl ); + mt_destroy( mt ); + + if ( buf ) free( buf ); + if ( binbuf ) free( binbuf ); + + return 0; +} \ No newline at end of file diff --git a/dm.h b/dm.h new file mode 100644 index 0000000..1f27e57 --- /dev/null +++ b/dm.h @@ -0,0 +1,16 @@ +#ifndef __DM_H +#define __DM_H + +#include +#include +#include + +#include "darray.h" +#include "tokenizer.h" + +#define __VER__ "0.3 beta" + + +int parse_dm( token_list *tl, const char* ); + +#endif \ No newline at end of file diff --git a/dm_parser.c b/dm_parser.c new file mode 100644 index 0000000..bfd829f --- /dev/null +++ b/dm_parser.c @@ -0,0 +1,323 @@ + +#line 1 "dm_parser.ragel" +#include +#include +#include +#include + +#include "dm.h" + + + + +#define CTS(X) {if (!dm_current_tok)token_s = p; printf("%s ",#X);if (!dm_current_tok) dm_current_tok = TOK_##X;} +#define CTE() {token_e = p;} +#define TADD(T,S,E) {tl_add_tok(tl,T,S,E);} + +char *new_string( const char *start, const char *end ) +{ + int str_s = end-start+1; + char *new_str=malloc( str_s+1 ); + memcpy( new_str, start, str_s ); + if ( new_str != NULL ) + new_str[str_s]=0x0; + return new_str; +} + +int print_token( char *s, char *e, int tok) +{ + char *p = new_string( s, e ); + printf("t=%d,p=%s\n",tok,p); + free( p ); + return 0; +} + + + +#line 38 "dm_parser.c" +static const char _dm_actions[] = { + 0, 1, 0, 1, 1, 1, 2, 1, + 3, 1, 4, 1, 5, 1, 6, 1, + 7, 1, 8, 1, 9, 1, 10, 1, + 11, 1, 12 +}; + +static const char _dm_key_offsets[] = { + 0, 0, 8, 17, 23, 24, 36, 39, + 41 +}; + +static const char _dm_trans_keys[] = { + 32, 39, 48, 57, 65, 90, 97, 122, + 32, 34, 39, 48, 57, 65, 90, 97, + 122, 48, 57, 65, 70, 97, 102, 102, + 32, 34, 38, 40, 41, 45, 48, 105, + 9, 10, 49, 57, 120, 48, 57, 48, + 57, 48, 57, 65, 70, 97, 102, 0 +}; + +static const char _dm_single_lengths[] = { + 0, 2, 3, 0, 1, 8, 1, 0, + 0 +}; + +static const char _dm_range_lengths[] = { + 0, 3, 3, 3, 0, 2, 1, 1, + 3 +}; + +static const char _dm_index_offsets[] = { + 0, 0, 6, 13, 17, 19, 30, 33, + 35 +}; + +static const char _dm_indicies[] = { + 0, 0, 0, 0, 0, 1, 0, 2, + 0, 0, 0, 0, 1, 4, 4, 4, + 3, 5, 1, 6, 7, 8, 9, 10, + 11, 12, 14, 6, 13, 1, 16, 13, + 15, 13, 15, 4, 4, 4, 17, 0 +}; + +static const char _dm_trans_targs[] = { + 2, 0, 5, 5, 8, 5, 5, 1, + 5, 5, 5, 5, 6, 7, 4, 5, + 3, 5 +}; + +static const char _dm_trans_actions[] = { + 0, 0, 9, 25, 0, 11, 7, 0, + 17, 13, 15, 19, 5, 0, 0, 23, + 0, 21 +}; + +static const char _dm_to_state_actions[] = { + 0, 0, 0, 0, 0, 1, 0, 0, + 0 +}; + +static const char _dm_from_state_actions[] = { + 0, 0, 0, 0, 0, 3, 0, 0, + 0 +}; + +static const char _dm_eof_trans[] = { + 0, 0, 0, 4, 0, 0, 16, 16, + 18 +}; + +static const int dm_start = 5; +static const int dm_first_final = 5; +static const int dm_error = 0; + +static const int dm_en_main = 5; + + +#line 63 "dm_parser.ragel" + + +int parse_dm( token_list *tl, const char *str ) +{ + static uint8_t cs; + const int stacksize = 10; + int res=0, *top=0, *stack=NULL, act=0; + stack = malloc( sizeof(stack)*stacksize ); + char *p=(char *)str, *pe = (char *)str + strlen( str ), *eof=NULL; + char *ts, *te = 0; + + /* + variables used in state machine + */ + char *token_s=NULL, *token_e=NULL; + char *value_s=NULL, *value_e=NULL; + int token_type=0; + int dm_current_tok = TOK_NONE; + + +#line 138 "dm_parser.c" + { + cs = dm_start; + ts = 0; + te = 0; + act = 0; + } + +#line 83 "dm_parser.ragel" + +#line 148 "dm_parser.c" + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _acts = _dm_actions + _dm_from_state_actions[cs]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { + switch ( *_acts++ ) { + case 1: +#line 1 "NONE" + {ts = p;} + break; +#line 169 "dm_parser.c" + } + } + + _keys = _dm_trans_keys + _dm_key_offsets[cs]; + _trans = _dm_index_offsets[cs]; + + _klen = _dm_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _dm_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _dm_indicies[_trans]; +_eof_trans: + cs = _dm_trans_targs[_trans]; + + if ( _dm_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _dm_actions + _dm_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 2: +#line 1 "NONE" + {te = p+1;} + break; + case 3: +#line 52 "dm_parser.ragel" + {te = p+1;} + break; + case 4: +#line 53 "dm_parser.ragel" + {te = p+1;{/*printf("str = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_STR,ts,te);}} + break; + case 5: +#line 55 "dm_parser.ragel" + {te = p+1;{/*printf("if = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_IF,ts,te);}} + break; + case 6: +#line 56 "dm_parser.ragel" + {te = p+1;{/*printf("lbr = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_LBR,ts,te);}} + break; + case 7: +#line 57 "dm_parser.ragel" + {te = p+1;{/*printf("rbr = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_RBR,ts,te);}} + break; + case 8: +#line 58 "dm_parser.ragel" + {te = p+1;{/*printf("and = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_EAND,ts,te);}} + break; + case 9: +#line 59 "dm_parser.ragel" + {te = p+1;{/*printf("range = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_RANGE,ts,te);}} + break; + case 10: +#line 51 "dm_parser.ragel" + {te = p;p--;{/*printf("hex = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_HEX,ts,te);}} + break; + case 11: +#line 54 "dm_parser.ragel" + {te = p;p--;{/*printf("int = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_INT,ts,te);}} + break; + case 12: +#line 54 "dm_parser.ragel" + {{p = ((te))-1;}{/*printf("int = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_INT,ts,te);}} + break; +#line 279 "dm_parser.c" + } + } + +_again: + _acts = _dm_actions + _dm_to_state_actions[cs]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { + switch ( *_acts++ ) { + case 0: +#line 1 "NONE" + {ts = 0;} + break; +#line 292 "dm_parser.c" + } + } + + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + if ( _dm_eof_trans[cs] > 0 ) { + _trans = _dm_eof_trans[cs] - 1; + goto _eof_trans; + } + } + + _out: {} + } + +#line 84 "dm_parser.ragel" + + if ( cs == dm_error ) + { + printf("ERR state [%d] pos[%d]:[%s]\n", res, p-str, p); + res = -1; + } + + return res; +} + + + diff --git a/dm_parser.ragel b/dm_parser.ragel new file mode 100644 index 0000000..80c873b --- /dev/null +++ b/dm_parser.ragel @@ -0,0 +1,95 @@ +#include +#include +#include +#include + +#include "dm.h" + + + + +#define CTS(X) {if (!dm_current_tok)token_s = p; printf("%s ",#X);if (!dm_current_tok) dm_current_tok = TOK_##X;} +#define CTE() {token_e = p;} +#define TADD(T,S,E) {tl_add_tok(tl,T,S,E);} + +char *new_string( const char *start, const char *end ) +{ + int str_s = end-start+1; + char *new_str=malloc( str_s+1 ); + memcpy( new_str, start, str_s ); + if ( new_str != NULL ) + new_str[str_s]=0x0; + return new_str; +} + +int print_token( char *s, char *e, int tok) +{ + char *p = new_string( s, e ); + printf("t=%d,p=%s\n",tok,p); + free( p ); + return 0; +} + + +%%{ + machine dm; + + + hex = '0x' [a-fA-F0-9]+; + int = [0-9]+; + newline = '\n' >{CTS(NL)} @{CTE()}; + if = 'if'; + lbracket = '('; + rbracket = ')'; + and = '&'; + range = '-'; + string = ('"' ([a-zA-Z0-9' '])+ '"'); + + sp = (' ' | '\t' | '\n'); + + main := |* + hex {/*printf("hex = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_HEX,ts,te);}; + sp {}; + string {/*printf("str = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_STR,ts,te);}; + int {/*printf("int = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_INT,ts,te);}; + if {/*printf("if = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_IF,ts,te);}; + lbracket {/*printf("lbr = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_LBR,ts,te);}; + rbracket {/*printf("rbr = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_RBR,ts,te);}; + and {/*printf("and = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_EAND,ts,te);}; + range {/*printf("range = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_RANGE,ts,te);}; + *|; + + write data; +}%% + +int parse_dm( token_list *tl, const char *str ) +{ + static uint8_t cs; + const int stacksize = 10; + int res=0, *top=0, *stack=NULL, act=0; + stack = malloc( sizeof(stack)*stacksize ); + char *p=(char *)str, *pe = (char *)str + strlen( str ), *eof=NULL; + char *ts, *te = 0; + + /* + variables used in state machine + */ + char *token_s=NULL, *token_e=NULL; + char *value_s=NULL, *value_e=NULL; + int token_type=0; + int dm_current_tok = TOK_NONE; + + %%write init; + %%write exec; + + if ( cs == dm_error ) + { + printf("ERR state [%d] pos[%d]:[%s]\n", res, p-str, p); + res = -1; + } + + return res; +} + + + diff --git a/exper.c b/exper.c new file mode 100644 index 0000000..1bcf65d --- /dev/null +++ b/exper.c @@ -0,0 +1,15 @@ +#define TOK_NONE 0 +#define TOK_HEX 1 +#define TOK_INT 2 +#define TOK_NL 3 +#define TOK_IF 4 +#define TOK_LBR 5 +#define TOK_RBR 6 +#define TOK_STR 7 + +int dm_current_tok = TOK_NONE; + +#define CT(X) (dm_current_tok = TOK_##X;) + +CT(IF) +CT(STR) diff --git a/mtable.c b/mtable.c new file mode 100644 index 0000000..7d705e8 --- /dev/null +++ b/mtable.c @@ -0,0 +1,107 @@ +#include "mtable.h" + + +/*****************************************************************************/ +mt_table* mt_create() +{ + mt_table *mt = NULL; + + mt = malloc( sizeof(mt_table) ); + if (mt == NULL) + { + printf("Cannot allocate mem for mt_table\n"); + return NULL; + } + memset(mt,0,sizeof(mt)); + + mt->table = darr_create( sizeof(mt_range), 100 ); + if (mt->table == NULL) + { + printf("Cannot allocate ->table\n"); + goto error; + } + + return mt; + +error: + free( mt ); + return NULL; + +} + + +/*****************************************************************************/ +int mt_add( mt_table *mt, mt_range *rng ) +{ + if (rng == NULL) + { + return -1; + } + + if ( darr_push( mt->table, rng ) != 0 ) + { + printf("Cannot add new table row\n"); + return -1; + } + + return 0; +} + +/*****************************************************************************/ +mt_range* mt_search( mt_table *mt, int pos ) +{ + int i; + mt_range *el = NULL; + + for (i=0; itable); i++) + { + el = darr_get( mt->table, i ); + if ((pos >= el->start) && (pos <= el->end)) + { + return el; + } + } + + return NULL; +} + + +/*****************************************************************************/ +int mt_print( mt_table *mt ) +{ + int i; + mt_range *rng = NULL; + + printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + printf("+ START + END + CMP + SIZE + VAL + SIZE +\n"); + printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + for (i=0; itable); i++) + { + rng = mt_get(mt,i); + if (rng == NULL) + continue; + printf("+ %8d + %8d + %08x + %8d + %08x + %8d +\n", + rng->start, rng->end, rng->cmp, rng->cmp_sz, + rng->val, rng->val_sz); + } + printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + + return 0; +} + + +/*****************************************************************************/ +void mt_destroy( mt_table *mt ) +{ + if ( mt == NULL ) + { + return; + } + + if ( mt->table != NULL) + { + darr_destroy( mt->table ); + } + + free( mt ); +} diff --git a/mtable.h b/mtable.h new file mode 100644 index 0000000..573f3e2 --- /dev/null +++ b/mtable.h @@ -0,0 +1,36 @@ +#ifndef __MTABLE_H +#define __MTABLE_H + +#include +#include +#include + +#include "darray.h" +#include "debug.h" + +typedef struct mt_range { + //range postiont start end + unsigned long start; + unsigned long end; + //cmp array start end + void *cmp; + int cmp_sz; + //note string + void *val; + int val_sz; +} mt_range; + +typedef struct mt_table { + darray *table; +} mt_table; + +mt_table* mt_create(); +int mt_add( mt_table *mt, mt_range *rng ); +mt_range* mt_search( mt_table *mt, int pos ); +int mt_print( mt_table *mt ); +void mt_destroy( mt_table *mt ); + +#define mt_size(MT_TABLE) (darr_end((MT_TABLE)->table)) +#define mt_get(MT_TABLE,X) (darr_get((MT_TABLE)->table,X)) + +#endif \ No newline at end of file diff --git a/syntax.c b/syntax.c new file mode 100644 index 0000000..510d735 --- /dev/null +++ b/syntax.c @@ -0,0 +1,559 @@ +#include "syntax.h" + +//token postion/type +#define TP(POS) tl_tok_type(tl,(POS)) +#define TP_EQ(POS,TYPE) (tl_tok_type(tl,(POS)) == TYPE) +#define TP_EQ2(POS,TYPE1,TYPE2) ((tl_tok_type(tl,(POS))==TYPE1)||(tl_tok_type(tl,(POS))==TYPE2)) +#define TP_NEQ(POS,TYPE) (tl_tok_type(tl,(POS)) != TYPE) +#define TP_NEQ2(POS,TYPE1,TYPE2) ((tl_tok_type(tl,(POS))!=TYPE1)&&(tl_tok_type(tl,(POS))!=TYPE2)) + +//check if enought tokens to parse +#define TE(POS) (tl_size(tl) > (POS)) + + +/*****************************************************************************/ +ast_root* ast_syntax( token_list *tl ) +{ + ast_root *ast_tree = NULL; + ast_range *rng = NULL; + tk_pos=0; + + ast_tree = atrt_i(); + + while ( tk_pos < tl_size(tl) ) + { + //current - INT|HEX next not RANGE + if (TP_EQ2(tk_pos,TOK_INT,TOK_HEX) + && TP_NEQ(tk_pos+1,TOK_RANGE)) + { + rng = att_range( tl, tk_pos ); + if (rng == NULL ) break; + atrt_a_range( &ast_tree, rng, 0 ); + // current - INT|HEX next RANGE + } else if ( TP_EQ2(tk_pos,TOK_INT,TOK_HEX) + && TP_EQ(tk_pos+1,TOK_RANGE) ) + { + rng = att_range( tl, tk_pos ); + if (rng == NULL ) break; + atrt_a_range( &ast_tree, rng, 0 ); + } else + { + printf("ERR:%d\n",tl_tok_type(tl,tk_pos)); + printf("Syntax error\n"); + break; + } + } + + return ast_tree; +} + + +/*****************************************************************************/ +ast_if* att_if( token_list *tl, int pos ) +{ + //PRINT("IF:pos->%d %d\n",tk_pos,pos); + + + ast_if *ret = NULL; + ast_expr *expr = NULL; + ast_value *val = NULL; + + if ( TP_NEQ(pos,TOK_IF) ) + { + printf("not if syntax error\n"); + return NULL; + } + // SHOULD BE first LBR (INT|HEX) third RBR + if ((TP_EQ(pos+1,TOK_LBR)) && + (TP_EQ2(pos+2,TOK_HEX,TOK_INT)) && + (TP_EQ(pos+3,TOK_RBR)) ) + { + expr = att_expr( tl, pos+1 ); + pos = tk_pos; + val = att_value( tl, pos ); + ret = ati_i(); + ati_s_expr( &ret, expr ); + ati_s_val( &ret, val ); + } else + { + printf("invalid range\n"); + return NULL; + } + + + return ret; +} + + +/*****************************************************************************/ +ast_range* att_range( token_list *tl, int pos ) +{ + //PRINT("RNG:pos->%d %d\n",tk_pos,pos); + ast_range *ret = NULL; + ast_value *val = NULL; + ast_if *iff = NULL; + + + if ( TP_NEQ2(pos,TOK_HEX,TOK_INT) ) + { + printf("range incorrect syntax\n"); + return NULL; + } + + //current HEX STR + if ( TP_EQ(pos+1,TOK_STR) ) + { + ret = atrn_i(); + atrn_s_rng0( &ret, tok2int(tl_get_tok(tl,pos)) ); + val = att_value( tl, pos+1 ); + if (val==NULL) return NULL; + atrn_s_val( &ret, val ); + tk_pos = pos+2; + //current HEX IF ... + } else if ( TP_EQ(pos+1,TOK_IF) ) + { + ret = atrn_i(); + atrn_s_rng0( &ret, tok2int(tl_get_tok(tl,pos))); + iff = att_if( tl, pos+1 ); + if (iff==NULL) return NULL; + atrn_a_if( &ret, iff ); + //current HEX RNG HEX + } else if (TP_EQ(pos+1,TOK_RANGE) && + (TP_EQ2(pos+2,TOK_HEX,TOK_INT))) + { + ret = atrn_i(); + atrn_s_rng1( &ret, tok2int(tl_get_tok(tl,pos)), tok2int(tl_get_tok(tl,pos+2))); + if (TP_EQ(pos+3,TOK_STR)) + { + val = att_value(tl,pos+3); + if (val==NULL) return NULL; + atrn_s_val( &ret, val ); + tk_pos = pos+4; + } else if (TP_EQ(pos+3,TOK_IF)) + { + iff = att_if( tl, pos+3 ); + if (iff==NULL) return NULL; + atrn_a_if( &ret, iff ); + } + } else + { + printf("wrong range syntax TOK=%d\n",tl_tok_type(tl,pos+1)); + return NULL; + } + + while (TE(tk_pos) && TP_EQ(tk_pos,TOK_IF) && (ret != NULL)) + { + //PNL(); + pos = tk_pos; + //PRINT("There is more ifs\n"); + iff = att_if( tl, pos ); + if (iff==NULL) return NULL; + atrn_a_if( &ret, iff ); + //PNL(); + } + + return ret; +} + + +/*****************************************************************************/ +ast_expr* att_expr( token_list *tl, int pos ) +{ + //PRINT("EXPR:pos->%d %d\n",tk_pos,pos); + + ast_expr *ret = NULL; + ast_expr_cmp *cmp = NULL; + + // SHOULD BE first LBR (INT|HEX) third RBR + if ( TP_NEQ(pos,TOK_LBR) ) + { + printf("Missing ( syntax error\n"); + return NULL; + } + + if ( TP_NEQ(pos+2,TOK_RBR) ) + { + printf("Missing ) syntax error\n"); + return NULL; + } + + ret = ate_i(); + cmp = att_expr_cmp( tl, pos+1 ); + if (cmp==NULL) return NULL; + ate_a_cmp( &ret, cmp ); + tk_pos += 1; + + return ret; +} + + +/*****************************************************************************/ +ast_expr_cmp* att_expr_cmp( token_list *tl, int pos ) +{ + //PRINT("CMP:pos->%d %d\n",tk_pos,pos); + ast_expr_cmp *ret = NULL; + + //current should be one HEX|INT + if (TP_EQ2(pos,TOK_HEX,TOK_INT)) + { + ret = atec_i(); + atec_s_val( &ret, tok2int(tl_get_tok(tl,pos))); + tk_pos = pos + 1; + } else + { + printf("Expression not INT not HEX\n"); + return NULL; + } + + return ret; +} + + +/*****************************************************************************/ +ast_expr_bit* att_expr_bit( token_list *tl, int pos ) +{ + +} + +/*****************************************************************************/ +ast_value* att_value( token_list *tl, int pos ) +{ + //PRINT("VAL:pos->%d %d\n", tk_pos, pos); + ast_value *val = NULL; + token *tok = NULL; + + //current should be one STR + if (TP_NEQ(pos,TOK_STR)) + { + printf("value incorrect syntax\n"); + return NULL; + } + + val = atv_i(); + tok = tl_get_tok(tl,pos); + atv_s_note( &val, tok->s, (tok->e)-(tok->s) ); + //PRINT("VAL[%.10s]\n",tok->s); + tk_pos = pos + 1; + + return val; +} + + +/*****************************************************************************/ +ast_root* atrt_i() +{ + ast_root *ret = NULL; + + ret = malloc( sizeof(ast_root) ); + if (ret == NULL) + { + printf("Cannot alloc ast_root\n"); + return NULL; + } + memset( ret, 0, sizeof(ast_root) ); + + return ret; +} + + +/*****************************************************************************/ +int atrt_a_range( ast_root **rt, ast_range *rng, int idx) +{ + //PNL(); + (*rt)->range = realloc( (*rt)->range, sizeof(void*)*(*rt)->total_tokens+1 ); + (*rt)->range[(*rt)->total_tokens] = rng; + (*rt)->total_tokens += 1; + + return 0; +} + + +/*****************************************************************************/ +ast_range* atrn_i() +{ + ast_range *ret = NULL; + + ret = malloc( sizeof(ast_range) ); + if (ret == NULL) + { + printf("Cannot alloc ast_range\n"); + return NULL; + } + memset( ret, 0, sizeof(ast_range) ); + + return ret; +} + + +/*****************************************************************************/ +int atrn_a_if( ast_range **rng, ast_if *iff ) +{ + //PNL(); + (*rng)->iff = realloc( (*rng)->iff, sizeof(void*)*(*rng)->size_iff+1 ); + (*rng)->iff[(*rng)->size_iff] = iff; + (*rng)->size_iff += 1; + return 0; +} + + +/*****************************************************************************/ +int atrn_a_val( ast_range **rng, ast_value *val ) +{ + (*rng)->val = val; + + return 0; +} + + +/*****************************************************************************/ +int atrn_s_rng0( ast_range **rng, int value ) +{ + (*rng)->range_type = 0; + (*rng)->start = value; + (*rng)->end = value; + + return 0; +} + + +/*****************************************************************************/ +int atrn_s_rng1( ast_range **rng, unsigned long start, unsigned long end) +{ + (*rng)->range_type = 1; + (*rng)->start = start; + (*rng)->end = end; + + return 0; +} + + +/*****************************************************************************/ +int atrn_s_val( ast_range **rng, ast_value *val ) +{ + (*rng)->val = val; + + return 0; +} + + +/*****************************************************************************/ +ast_if* ati_i() +{ + ast_if *ret = NULL; + + ret = malloc( sizeof(ast_if) ); + if (ret == NULL) + { + printf("Cannot alloc ast_if\n"); + return NULL; + } + memset( ret, 0, sizeof(ast_if) ); + + return ret; +} + + +/*****************************************************************************/ +int ati_s_expr( ast_if **iff, ast_expr *expr ) +{ + (*iff)->expr = expr; + return -1; +} + + +/*****************************************************************************/ +int ati_s_val( ast_if **iff, ast_value *val ) +{ + (*iff)->val = val; + return -1; +} + + +/*****************************************************************************/ +ast_expr* ate_i() +{ + ast_expr *ret = NULL; + + ret = malloc( sizeof(ast_expr) ); + if (ret == NULL) + { + printf("Cannot alloc ast_expr\n"); + return NULL; + } + memset( ret, 0, sizeof(ast_expr) ); + + return ret; +} + + +/*****************************************************************************/ +int ate_a_bit( ast_expr **expr, ast_expr_bit *bit ) +{ + //PNL(); + if ((*expr)->bit == NULL) + { + (*expr)->bit = malloc(sizeof(void *)); + (*expr)->bit[0] = bit; + (*expr)->size_bit = 1; + } else + { + (*expr)->bit = realloc( (*expr)->bit, sizeof(void*)*((*expr)->size_bit+1) ); + (*expr)->bit[(*expr)->size_bit] = bit; + (*expr)->size_bit += 1; + } + + return 0; +} + + +/*****************************************************************************/ +int ate_a_cmp( ast_expr **expr, ast_expr_cmp *cmp ) +{ + //PNL(); + if ((*expr)->cmp == NULL) + { + (*expr)->cmp = malloc(sizeof(void *)); + (*expr)->cmp[0] = cmp; + (*expr)->size_cmp = 1; + } else + { + (*expr)->cmp = realloc( (*expr)->cmp, sizeof(void*)*((*expr)->size_cmp+1) ); + (*expr)->cmp[(*expr)->size_cmp] = cmp; + (*expr)->size_cmp += 1; + } + + return 0; +} + + +/*****************************************************************************/ +int ate_eval( ast_expr *expr ) +{ + +} + + +/*****************************************************************************/ +ast_expr_bit* ateb_i() +{ + ast_expr_bit *ret = NULL; + + ret = malloc( sizeof(ast_expr_bit) ); + if (ret == NULL) + { + printf("Cannot alloc ast_expr_bit\n"); + return NULL; + } + memset( ret, 0, sizeof(ast_expr_bit) ); + + return ret; +} + + +/*****************************************************************************/ +int ateb_s_mask( ast_expr_bit **expr, unsigned char mask ) +{ + (*expr)->mask = mask; + + return 0; +} + + +/*****************************************************************************/ +ast_expr_cmp* atec_i() +{ + ast_expr_cmp *ret = NULL; + + ret = malloc( sizeof(ast_expr_cmp) ); + if (ret == NULL) + { + printf("Cannot alloc ast_expr_cmp\n"); + return NULL; + } + memset( ret, 0, sizeof(ast_expr_cmp) ); + + return ret; +} + + +/*****************************************************************************/ +int atec_s_val( ast_expr_cmp **expr, unsigned char val ) +{ + (*expr)->val = val; + return 0; +} + + +/*****************************************************************************/ +ast_value* atv_i() +{ + ast_value *ret = NULL; + + ret = malloc( sizeof(ast_value) ); + if (ret == NULL) + { + printf("Cannot alloc ast_value\n"); + return NULL; + } + memset( ret, 0, sizeof(ast_value) ); + + return ret; +} + + +/*****************************************************************************/ +int atv_s_note( ast_value **val, char *note, int size) +{ + (*val)->note = note; + (*val)->size = size; + + return 0; +} + +/*****************************************************************************/ +int print_ast( ast_root *root ) +{ + int i,j,k; + ast_range *rng = NULL; + + if ( root == NULL ) + { + printf("Empty ast_root\n"); + return -1; + } + + for (i=0;itotal_tokens;i++) + { + printf("RANGE:%d\n",i ); + rng = root->range[i]; + if ( rng->range_type == 0 || rng->range_type == 1 ) + { + printf("%d-%d:\n",rng->start, rng->end); + if (rng->val != NULL) + { + printf("\t[%.12s]\n",rng->val->note); + } + if (rng->iff != NULL) + { + printf("\tIF\n"); + for (j=0;jsize_iff;j++) + { + if (rng->iff[j]->expr != NULL) + { + printf("\t\tCMP:"); + for (k=0;kiff[j]->expr->size_cmp;k++) + { + printf("0x%02x ",rng->iff[j]->expr->cmp[k]->val); + } + printf("\n"); + } + if (rng->iff[j]->val != NULL) + { + printf("\t\tVAL:%.7s\n",rng->iff[j]->val->note); + } + } + } + } + } + return 0; +} \ No newline at end of file diff --git a/syntax.h b/syntax.h new file mode 100644 index 0000000..9f2d224 --- /dev/null +++ b/syntax.h @@ -0,0 +1,123 @@ +#ifndef __SYNTAX_H +#define __SYNTAX_H + +#include +#include +#include +#include + + +#include "debug.h" +#include "tokenizer.h" + +#define ALLOC_MEMSET(T,VAL) {VAL=malloc(sizeof(T));memset(VAL,0,sizeof(T));} + + +typedef struct ast_range ast_range; +typedef struct ast_if ast_if; +typedef struct ast_value ast_value; +typedef struct ast_expr ast_expr; +typedef struct ast_expr_bit ast_expr_bit; +typedef struct ast_expr_cmp ast_expr_cmp; + +//welcome to 90's +//[TYPE]_[SET/GET/ADD/INIT]_[VALUE] +//G -get +//S -set +//A - add +//I - init +//SZ-size +//S - start +//E - end + +//ATRT +typedef struct ast_root +{ + int size; + int total_tokens; + ast_range **range; +} ast_root; + +//ATRN +typedef struct ast_range +{ + int range_type; + unsigned long start; + unsigned long end; + int next_type; + int size_iff; + ast_if **iff; + ast_value *val; +} ast_range; + +//ATI +typedef struct ast_if +{ + int eval; + ast_expr *expr; + ast_value *val; +} ast_if; + +//ATEB +typedef struct ast_expr_bit +{ + unsigned char mask; +} ast_expr_bit; + +//ATEC +typedef struct ast_expr_cmp +{ + unsigned char val; +} ast_expr_cmp; + +//ATE +typedef struct ast_expr +{ + int type; + int size_cmp; + int size_bit; + ast_expr_cmp **cmp; + ast_expr_bit **bit; +} ast_expr; + +//ATV +typedef struct ast_value +{ + int size; + char *note; + +} ast_value; + +static int tk_pos = 0; + +ast_root* ast_syntax( token_list *tl ); +ast_if* att_if( token_list *tl, int pos ); +ast_range* att_range( token_list *tl, int pos ); +ast_expr* att_expr( token_list *tl, int pos ); +ast_expr_cmp* att_expr_cmp( token_list *tl, int pos ); +ast_expr_bit* att_expr_bit( token_list *tl, int pos ); +ast_value* att_value( token_list *tl, int pos ); +ast_root* atrt_i(); +int atrt_a_range( ast_root **rt, ast_range *rng, int idx); +ast_range* atrn_i(); +int atrn_a_if( ast_range **rng, ast_if *iff ); +int atrn_a_val( ast_range **rng, ast_value *val ); +int atrn_s_rng0( ast_range **rng, int value ); +int atrn_s_rng1( ast_range **rng, unsigned long start, unsigned long end); +int atrn_s_val( ast_range **rng, ast_value *val ); +ast_if* ati_i(); +int ati_s_expr( ast_if **iff, ast_expr *expr ); +int ati_s_val( ast_if **iff, ast_value *val ); +ast_expr* ate_i(); +int ate_a_bit( ast_expr **expr, ast_expr_bit *bit ); +int ate_a_cmp( ast_expr **expr, ast_expr_cmp *cmp ); +int ate_eval( ast_expr *expr ); +ast_expr_bit* ateb_i(); +int ateb_s_mask( ast_expr_bit **expr, unsigned char mask ); +ast_expr_cmp* atec_i(); +int atec_s_val( ast_expr_cmp **expr, unsigned char val ); +ast_value* atv_i(); +int atv_s_note( ast_value **val, char *note, int size); +int print_ast( ast_root *root ); + +#endif \ No newline at end of file diff --git a/test.h b/test.h new file mode 100644 index 0000000..9364452 --- /dev/null +++ b/test.h @@ -0,0 +1,19 @@ +#define M(T) _Generic((T),int:12); + +typedef struct ast_range {int i;} ast_range; +typedef struct ast_if ast_if; +typedef struct ast_value ast_value; +typedef struct ast_expr ast_expr; +typedef struct ast_root ast_root; +typedef struct ast_expr_cmp ast_expr_cmp; +typedef struct ast_expr_bitwise ast_expr_bitwise; + +#define ALLOC_MEMSET(T,VAL) {VAL=malloc(sizeof(T));memset(VAL,0,sizeof(T));} + + + +int fun() +{ + char *root; + ALLOC_MEMSET(ast_range,root); +} \ No newline at end of file diff --git a/test/alleatures.dm b/test/alleatures.dm new file mode 100644 index 0000000..ea3bda7 --- /dev/null +++ b/test/alleatures.dm @@ -0,0 +1,10 @@ +0x01-0x2 "Hello" + +0x010 + if (0x01) "One" + if (0x02) "Two" + if (0x03) "Three" + if (0x40) "Forty" +0x0aaa + if (&0x0001) "bit one" + if (&0x0112) "some more bits" \ No newline at end of file diff --git a/test/elf32.bin b/test/elf32.bin new file mode 100644 index 0000000..1c0b9f2 --- /dev/null +++ b/test/elf32.bin @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/elf32.md b/test/elf32.md new file mode 100644 index 0000000..d5ab688 --- /dev/null +++ b/test/elf32.md @@ -0,0 +1,13 @@ +0x0-0x3 + "magic number" +0x4 + if (0x01) "32 bit elf" + if (0x02) "64 bit elf" +0x5 + if (0x01) "little endian" + if (0x02) "big endian" +0x10 + if (0x1) "relocatable ELF" + if (0x2) "executable ELF" + if (0x3) "shared ELF" + if (0x4) "Core ELF what that" \ No newline at end of file diff --git a/test/manyifs.md b/test/manyifs.md new file mode 100644 index 0000000..745d5ab --- /dev/null +++ b/test/manyifs.md @@ -0,0 +1,12 @@ +0x01-0x2 "Hello" + +0x010 + if (0x01) "One" + if (0x02) "Two" + if (0x03) "Three" + if (0x40) "Forty" +0x012 + if (0x01) "One" + if (0x02) "Two" + if (0x03) "Three" + if (0x40) "Forty" \ No newline at end of file diff --git a/test/one_byte.dm b/test/one_byte.dm new file mode 100644 index 0000000..deb59d8 --- /dev/null +++ b/test/one_byte.dm @@ -0,0 +1,3 @@ +0x000001 "first byte" + 0xa10f "second byte" + 3 "third byte" \ No newline at end of file diff --git a/test/range.md b/test/range.md new file mode 100644 index 0000000..fa0310f --- /dev/null +++ b/test/range.md @@ -0,0 +1,3 @@ +0x1-0x2 "Header" +0x3-0x4 "General info" +0x3-0x5 "Hola" \ No newline at end of file diff --git a/test/rangeif.md b/test/rangeif.md new file mode 100644 index 0000000..82b03bd --- /dev/null +++ b/test/rangeif.md @@ -0,0 +1,3 @@ +0x1-0x2 if (0x00) "Header" +0x3-0x4 if (0x01) "General info" +0x3-0x5 if (0x02) "Hola" \ No newline at end of file diff --git a/test/simpleif.md b/test/simpleif.md new file mode 100644 index 0000000..1a617c6 --- /dev/null +++ b/test/simpleif.md @@ -0,0 +1,2 @@ +0x12 if (0x01) "asdinfo" +0x14 if (0x02) "hello" \ No newline at end of file diff --git a/test/test.bin b/test/test.bin new file mode 100644 index 0000000..8de8f43 --- /dev/null +++ b/test/test.bin @@ -0,0 +1 @@ + diff --git a/test/two_byte.md b/test/two_byte.md new file mode 100644 index 0000000..ad71609 --- /dev/null +++ b/test/two_byte.md @@ -0,0 +1,13 @@ +0x00 "zero byte" +0x01 if ( 0x00 ) + "first byte" +0x0a "second byte" +0x3 "third byte" +0x04 if (0x01) + "array" + +0x2 - 0x3 if ( 0x12 ) +"if array" + +0x2 if ( & 0x12 ) +"if array" \ No newline at end of file diff --git a/tokenizer.c b/tokenizer.c new file mode 100644 index 0000000..a7c73e2 --- /dev/null +++ b/tokenizer.c @@ -0,0 +1,141 @@ +#include "tokenizer.h" + + +/*****************************************************************************/ +token* token_create() +{ + token *t = NULL; + t = malloc(sizeof(token)); + memset(t,0,sizeof(token)); + return t; +} + + +/*****************************************************************************/ +int token_set( token **tok, int val, char *s, char *e ) +{ + if ( tok == NULL ) + { + printf("token is NULL\n"); + return -1; + } + + if ( !(TOK_IN_RANGE(val)) ) + { + printf("Token value not in range\n"); + return -1; + } + + (*tok)->token = val; + (*tok)->s = s; + (*tok)->e = e; + + return 0; +} + + +/*****************************************************************************/ +token_list* tl_create() +{ + token_list *tl = NULL; + + tl = malloc( sizeof(token_list) ); + if (tl == NULL) + { + printf("Cannot alloc mem\n"); + goto error; + } + memset(tl, 0, sizeof(token_list)); + + tl->list = darr_create( sizeof(token), 100 ); + if (tl->list == NULL) + { + printf("cannot create ->list\n"); + goto error; + } + + return tl; + +error: + return NULL; +} + + +/*****************************************************************************/ +int tl_add_tok( token_list *tl, int t, char *s, char *e ) +{ + token *tok = NULL; + tok = token_create(); + if (tok == NULL) + { + printf("Cannot add token\n"); + return -1; + } + token_set( &tok, t, s, e ); + darr_push( tl->list, (void *)tok ); + return 0; +} + + +/*****************************************************************************/ +char* tl_str( token_list *tl ) +{ + int len = 128; + int p = 0; + char *s = NULL; + int i = 0; + //s = malloc( len ); + //s[p] = 0; + + + for (i=0; ilist); i++) + { + token *t = (token *)darr_get(tl->list, i); + //printf("t=0x%x\n",t); + if ( t != NULL ) + { + printf("%02d:TOK:0x%x s:0x%08x e:0x%08x\n",i,t->token,t->s,t->e); + } + } + + return s; +error: + return NULL; +} + + +/*****************************************************************************/ +void tl_destroy( token_list *tl ) +{ + if ( tl == NULL ) + return; + if ( tl->list != NULL ) + { + darr_clear_destroy( tl->list ); + } +} + + +/*****************************************************************************/ +int tl_size( token_list *tl ) +{ + return darr_end( tl->list ); +} + + +int tok2int( token *tok ) +{ + char str[128]; + int sz = tok->e - tok->s; + memcpy(str,tok->s,sz); + str[sz] = 0; + //printf("!%s %d\n",str,strtol(str,NULL,16)); + return strtol(str,NULL,16); +} + + +char *tok2str( token *tok ) +{ + +} + diff --git a/tokenizer.h b/tokenizer.h new file mode 100644 index 0000000..1d3acdb --- /dev/null +++ b/tokenizer.h @@ -0,0 +1,53 @@ +#ifndef __TOKENIZER_H +#define __TOKENIZER_H + +#include +#include +#include +#include + +#include "darray.h" + +#define TOK_NONE 0 +#define TOK_HEX 1 +#define TOK_INT 2 +#define TOK_NL 3 +#define TOK_IF 4 +#define TOK_LBR 5 +#define TOK_RBR 6 +#define TOK_STR 7 +#define TOK_EAND 8 +#define TOK_RANGE 9 + +#define TOK2STR(X) TOK_#X + +/*not best way how to define*/ +#define TOK_IN_RANGE(TOK) ((TOK_HEX>=0)&&(TOK_RANGE<=TOK_RANGE)) + +typedef struct token +{ + int token; + char *s, *e; +} token; + +typedef struct token_list +{ + darray *list; +} token_list; + +token* token_create(); +int token_set( token **tok, int val, char *s, char *e ); + +token_list* tl_create(); +int tl_add_tok( token_list *tl, int t, char *s, char *e ); +char* tl_str( token_list *tl ); +void tl_destroy( token_list *tl ); +int tl_size( token_list *tl ); + +#define tl_tok_type(TL,IDX) (((token *)(darr_get((TL)->list,IDX)))->token) +#define tl_get_tok(TL,IDX) ((token *)(darr_get((TL)->list,IDX))) + +int tok2int( token *tok ); +char *tok2str( token *tok ); + +#endif \ No newline at end of file -- cgit v1.2.3