#include #include #include #include #include #include #include "big_endian.h" #include "helper.h" int main(int argc, char **argv) { unsigned char error_vec_len[8] = { 0 }; unsigned char error_vec_cap[8] = { 0 }; struct SignedVec error_vec = { 0 }; error_vec.len = error_vec_len; error_vec.capacity = error_vec_cap; char *grammar_string = "document = 1*( item )\n" "\n" "item = header [ price ] *1( note )\n" "\n" "item =/ header [ note ] *1( price )\n" "\n" "header = *1star \"SP\" title %xA *( \"SP\" / %xA )\n" "\n" "title = 1*\"TEXT\"\n" "\n" "star = %x2A\n" "\n" "note = \"note:\" \"SP\" note-content %xA *( \"SP\" / %xA )\n" "\n" "note-content = 1*\"TEXT\"\n" "\n" "price = \"price:\" \"SP\" 1*\"DIGIT\" %xA *( \"SP\" / %xA )\n"; struct parser *parser = new_parser(grammar_string, &error_vec); /* struct parser *parser = new_parser("start = \"a\"\"b\"\n", &error_vec); */ uint64_t error_length = from_big_endian(error_vec.len); if (error_length) { printf("error: "); char *error_str = error_vec.data; for (int i = 0; i < error_length; i++) { printf("%c", *(error_str+i)); } printf("\n"); clean_signed(&error_vec, 4); return 1; } /* int input_unenc[] = { 3, 0, 2, 1, 5, 0, 6, 1 }; */ /* int input_unenc[] = { 3, 0, 2, 2, 2, 2, 1, 5, 0, * 6, 6, 6, 1, 3, 0, 2, 2, 2, * 2, 1, 5, 0, 6, 6, 6, 1, 3, * 0, 2, 2, 2, 2, 1, 5, 0, 6, * 6, 6, 1, 4, 2, 2, 2, 2, 2, * 2, 2, 2, 2, 2, 2, 2, 2, 2, * 2, 2, 1 }; */ int input_unenc[] = { 3, 0, 2, 1, 5, 0, 6, 1, 3, 0, 2, 1, 5, 0, 6, 1, 3, 0, 2, 1, 5, 0, 6, 1, 4, 0, 2, 1 }; int input_unenc_len = (int) (sizeof (input_unenc) / sizeof(input_unenc[0])); printf("input length = %d\n", input_unenc_len); unsigned char *input = malloc (sizeof(unsigned char) * input_unenc_len * 8); if (input == NULL) { clean_parser(parser); clean_signed(&error_vec, 4); printf("malloc fails at %s:%d\n", __FILE__, __LINE__); return EXIT_FAILURE; } for (int i = 0; i < input_unenc_len; i++) to_big_endian(input_unenc[i], input + (8 * i)); unsigned char input_len[8] = { 0 }; /* input_len[7] = 8*10; */ to_big_endian((uint64_t) (8 * input_unenc_len), input_len); struct UnsignedVec input_vec = (struct UnsignedVec) { input_len, NULL, input }; int result = parser_recognize (parser, &input_vec, &error_vec, (unsigned char) 0); error_length = from_big_endian(error_vec.len); if (error_length) { clean_parser((void *) parser); free(input); printf("error: "); char *error_str = error_vec.data; for (uint64_t i = 0; i < error_length; i++) { printf("%c", *(error_str + (unsigned long) i)); } printf("\n"); clean_signed(&error_vec, 4); return 1; } if (result) printf("result = true\n"); else printf("result = false\n"); for (int i = 0; i < 8; i++) { error_vec.len[i] = 0; error_vec.capacity[i] = 0; } struct UnsignedVec *forest_ptr = parser_parse (parser, &input_vec, &error_vec, (unsigned char) 1); error_length = from_big_endian(error_vec.len); if (error_length) { clean_parser((void *) parser); free(input); printf("error: "); char *error_str = error_vec.data; for (uint64_t i = 0; i < error_length; i++) { printf("%c", *(error_str + (unsigned long) i)); } printf("\n"); clean_signed(&error_vec, 4); return 1; } free(input); clean_parser((void *) parser); if (forest_ptr) { uint64_t forest_len = from_big_endian(forest_ptr->len); /* forest_len++; */ printf("a non-empty forest of length %llu\n", forest_len); unsigned char *forest = forest_ptr->data; uint64_t forest_real_len = from_big_endian(forest); if (forest_real_len != forest_len) { fprintf(stderr, "wrong length: %llu\n", forest_real_len); clean_unsigned(forest_ptr, 15); return 1; } if (forest_len < 27) { fprintf(stderr, "length too small: %llu\n", forest_len); clean_unsigned(forest_ptr, 15); return 1; } printf("the lengths match\n"); if (*(forest+8) != 114 || *(forest+9) != 101 || *(forest+10) != 112) { fprintf(stderr, "the forest does not begin with the special mark\n"); fprintf(stderr, "the first bytes are: "); fprintf(stderr, "%c", *(forest+8)); fprintf(stderr, "%c", *(forest+9)); fprintf(stderr, "%c\n", *(forest+10)); clean_unsigned(forest_ptr, 15); return 1; } printf("the special mark is correct.\n"); uint64_t nodes_len = from_big_endian(forest+11); printf("forest has %llu nodes\n", nodes_len); uint64_t labels_offset = from_big_endian(forest+19); printf("the offset of labels is %llu\n", labels_offset); if (forest_len < labels_offset || forest_len < (27 + 16 * nodes_len)) { fprintf(stderr, "length too small: %llu\n", forest_len); clean_unsigned(forest_ptr, 15); return 1; } uint64_t total_degree = 0; for (uint64_t i = 0; i < nodes_len; i++) { uint64_t offset = 27 + 16 * i; uint64_t degree = from_big_endian(forest+offset); uint64_t node_offset = from_big_endian(forest+offset+8); total_degree += degree; printf("the %llu-th node has degree %llu and offset %llu\n", i, degree, node_offset); printf("label: "); print_label(read_label(forest + labels_offset + 34 * i)); for (uint64_t j = 0; j < degree; j++) { uint64_t child = from_big_endian(forest+node_offset+8*j); printf("the %llu-th child is %llu\n", j, child); } printf("\n"); } uint64_t correct = 27 + 50 * nodes_len + 8 * total_degree; if (forest_len != correct) { fprintf(stderr, "length does not conform to the format: %llu\n", correct); clean_unsigned(forest_ptr, 15); return 1; } printf("the forest has the correct length according to the format\n"); printf("saving to the file \"forest.rep\"\n"); char *open_mode = "a"; if (fopen("forest.rep", "r") != NULL) { printf("The file \"forest.rep\" already exists.\n" "Do you want to overwrite it? [y/n] "); fflush(stdout); #define UNANSWERED 0 #define YES 1 #define NO 2 int yes = UNANSWERED; while (yes == UNANSWERED) { char input = getchar(); switch (input) { case 'y': yes = YES; break; case 'n': yes = NO; break; default: printf("Please answer 'y' or 'n'.\n"); yes = UNANSWERED; break; } } if (yes == NO) { printf("Exiting without saving...\n"); clean_unsigned(forest_ptr, 15); return 0; } open_mode = "w"; #undef UNANSWERED #undef YES #undef NO } FILE *forest_file = fopen("forest.rep", open_mode); if (forest_file == NULL) { fprintf(stderr, "Cannot open file \"forest.rep\" to write\n"); clean_unsigned(forest_ptr, 15); return 1; } fwrite(forest, 1, forest_len, forest_file); fclose(forest_file); printf("Successfully saved the forest to the file \"forest.rep\"\n"); clean_unsigned(forest_ptr, 15); } else { printf("no forest\n"); } return 0; }