diff options
author | FreeArtMan <=> | 2015-12-17 20:59:18 +0000 |
---|---|---|
committer | FreeArtMan <=> | 2015-12-17 20:59:18 +0000 |
commit | a61ad1cef9ef77f9afd67230df5470b6b55525be (patch) | |
tree | d8bae5fc932865e769e4965ce0817b6d107badf2 | |
download | dm-a61ad1cef9ef77f9afd67230df5470b6b55525be.tar.gz dm-a61ad1cef9ef77f9afd67230df5470b6b55525be.zip |
Initial commit
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | Makefile | 20 | ||||
-rw-r--r-- | ast.c | 0 | ||||
-rw-r--r-- | ast.h | 0 | ||||
-rw-r--r-- | darray.c | 335 | ||||
-rw-r--r-- | darray.h | 53 | ||||
-rw-r--r-- | debug.h | 69 | ||||
-rw-r--r-- | dm.c | 259 | ||||
-rw-r--r-- | dm.h | 16 | ||||
-rw-r--r-- | dm_parser.c | 323 | ||||
-rw-r--r-- | dm_parser.ragel | 95 | ||||
-rw-r--r-- | exper.c | 15 | ||||
-rw-r--r-- | mtable.c | 107 | ||||
-rw-r--r-- | mtable.h | 36 | ||||
-rw-r--r-- | syntax.c | 559 | ||||
-rw-r--r-- | syntax.h | 123 | ||||
-rw-r--r-- | test.h | 19 | ||||
-rw-r--r-- | test/alleatures.dm | 10 | ||||
-rw-r--r-- | test/elf32.bin | 1 | ||||
-rw-r--r-- | test/elf32.md | 13 | ||||
-rw-r--r-- | test/manyifs.md | 12 | ||||
-rw-r--r-- | test/one_byte.dm | 3 | ||||
-rw-r--r-- | test/range.md | 3 | ||||
-rw-r--r-- | test/rangeif.md | 3 | ||||
-rw-r--r-- | test/simpleif.md | 2 | ||||
-rw-r--r-- | test/test.bin | 1 | ||||
-rw-r--r-- | test/two_byte.md | 13 | ||||
-rw-r--r-- | tokenizer.c | 141 | ||||
-rw-r--r-- | tokenizer.h | 53 |
29 files changed, 2288 insertions, 0 deletions
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/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;i<init_size;i++) + { + arr->data[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 <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <sys/types.h> + +//#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 @@ -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 @@ -0,0 +1,259 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <getopt.h> + +#include <sys/stat.h> + +#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;i<ast->total_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;j<arng->size_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;k<arng->iff[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;i<sz;i++) + printf("%c", str[i]); + } + + int i; + mt_range *rng = NULL; + + for ( i=0; i<mt_size(mt); i++ ) + { + rng = mt_get(mt,i); + if (rng == NULL) continue; + if (rng->start >= 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] <filename>\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 @@ -0,0 +1,16 @@ +#ifndef __DM_H +#define __DM_H + +#include <stdint.h> +#include <string.h> +#include <sys/types.h> + +#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 <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> + +#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 <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> + +#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; +} + + + @@ -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; i<darr_end(mt->table); 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; i<darr_end(mt->table); 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 <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +#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;i<root->total_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;j<rng->size_iff;j++) + { + if (rng->iff[j]->expr != NULL) + { + printf("\t\tCMP:"); + for (k=0;k<rng->iff[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 <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <string.h> + + +#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 @@ -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; i<darr_end(tl->list); 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 <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> + +#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 |