Implementation =============== Once you generate your parser you can use it as a part of you project. It can be used with any C/C++ compiler that supports C99 syntax. The code is compatible with both Linux and Windows. You can generate the parser as single file or multiple files. By default, the parser includes a main function (for demo purposes), machine code (runs the parser) and program code (defines the parser). You can exclude the main and the machine code from the generation. Declarations are included inside the source file by default but you can generate a separate header file if you want. You can generate multiple parsers (as programs) and use a single machine to run all of them. The generated program is stored as a :code:`struct Program`. It is normally in the name of the parser such as :code:`struct Program ParserProgram;`. You can use :code:`GetTokenizeResult` to generate the tokens and :code:`GetAnalyzeResult` to generate the syntax. You can quickly print the result to your screen using :code:`PrintTokenizeResult` and :code:`ExportAnalyzeResult` respectfully. These print function will also print any encountered error. When it comes to extracting the parsed data to use in your program/library you can use the raw data from :code:`struct TokenizeResult` and :code:`struct AnalyzeResult`. These structs do not allocate strings but refer to the text (passed to the parser to be parsed) buffer using indices. However, an easier way to extract the parsed data is using the functions :code:`ExportTokenizeResult` and :code:`ExportAnalyzeResult`. These function converts the data in :code:`struct TokenizeResult` and :code:`struct AnalyzeResult` into string pairs, stored in the types :code:`struct TokenPairList` and :code:`struct NodePairList` respectfully. The strings in these structs are allocated and should be released after no longer needed with the functions :code:`DestroyTokenPairList` and :code:`DestroyNodePairList` respectfully. You can see the generated main function as a example on how to use the parser in your program. Here is a sample code .. code-block:: c #ifndef ALGODAL_GENERATED_PARSER_MAIN_C #define ALGODAL_GENERATED_PARSER_MAIN_C #include #ifdef __cplusplus extern "C" { #endif #ifdef ALGODAL_GENERATED_PARSER_MAIN_PRINT_USING_EXPORT static void printNodePair(struct AlgodalParser_NodePair nodePair, uint32_t indent) { for(uint32_t i = 0; i < indent; i++) cwpc_printf("\t"); cwpc_printf("%u.%u %s : %s\n", nodePair.lineNumber, nodePair.columnNumber, nodePair.key, nodePair.value ? nodePair.value : "" ); for(uint32_t i = 0; i < nodePair.children.size; i++) { printNodePair(nodePair.children.addr[i], indent + 1); } } #endif static int ExitParsing(int retv[], int retc) { for(int i = 0; i < retc; i++) { if(retv[i] != 0) return EXIT_FAILURE; } return EXIT_SUCCESS; } int main(int argc, char *argv[]) { if(argc > 1) { FILE* fp = fopen(argv[1], "rb"); if(fp) { if(fp == 0) return EXIT_FAILURE; fseek(fp, 0, SEEK_END); size_t length = ftell(fp); fseek(fp, 0, SEEK_SET); char *text = malloc(length + 1); text[length] = 0; fread(text, 1, length, fp); fclose(fp); #if defined(ALGODAL_GENERATED_PARSER_UTILITY_H) || defined(ALGODAL_GENERATED_PARSER_UTILITY_C) #ifndef __linux__ char*temp = text; text = AlgodalParserUtility_CreateFilteredOutString(temp, length, (const char*[]){"\r"}, 1, &length); free(temp); #endif #endif clock_t begin = clock(), end; double duration; struct AlgodalParser_TokenizeResult TokenizeResult = AlgodalParser_GetTokenizeResult(*ProgramPtr, text, length, 0); struct AlgodalParser_AnalyzeResult AnalyzeResult = AlgodalParser_GetAnalyzeResult(*ProgramPtr, text, TokenizeResult.tokens.addr, TokenizeResult.tokens.size, 0); end = clock(); duration = (double)(end - begin) / CLOCKS_PER_SEC; #ifndef ALGODAL_GENERATED_PARSER_MAIN_NO_PRINT struct AlgodalParser_Linenumber *PLn = AlgodalParser_CreateParserLinenumber(text, length); cwpc_printf("\nTokenization:\n"); #ifndef ALGODAL_GENERATED_PARSER_MAIN_PRINT_USING_EXPORT AlgodalParser_PrintTokenizeResult(*ProgramPtr, TokenizeResult, text, PLn); #else struct AlgodalParser_TokenPairList tokenStringPairs = AlgodalParser_ExportTokenizeResult(TokenizeResult, *ProgramPtr, text, PLn); for(uint32_t i = 0; i < tokenStringPairs.size; i++) { cwpc_printf("%u.%u %s : %s\n", tokenStringPairs.addr[i].lineNumber, tokenStringPairs.addr[i].columnNumber, tokenStringPairs.addr[i].key, tokenStringPairs.addr[i].value ); } #endif if(TokenizeResult.error.flags == 0) { cwpc_printf("\nAnalyzation:\n"); #ifndef ALGODAL_GENERATED_PARSER_MAIN_PRINT_USING_EXPORT AlgodalParser_PrintAnalyzeResult(*ProgramPtr, AnalyzeResult, TokenizeResult.tokens.addr, text, PLn); #else struct AlgodalParser_NodePairList nodeStringPairs = AlgodalParser_ExportAnalyzeResult(TokenizeResult.tokens.addr, AnalyzeResult, *ProgramPtr, text, PLn); for(uint32_t i = 0; i < nodeStringPairs.size; i++) { printNodePair(nodeStringPairs.addr[i], 0); } #endif } else { if((*ProgramPtr).CountOfEntrypoints) { cwpc_printf("Tokenization step contains error - Analyzation not done.\n"); } } cwpc_printf("completed in %f milliseconds\n", duration * 1000); AlgodalParser_DestroyParserLinenumber(PLn); #endif AlgodalParser_DestroyTokenizeResult(TokenizeResult); AlgodalParser_DestroyAnalyzeResult(AnalyzeResult); free(text); int ret[] = {TokenizeResult.error.flags, AnalyzeResult.error.flags}; return ExitParsing(ret, sizeof(ret)/sizeof(int)); } cwpc_printf("FAILED TO OPEN FILE %s\n", argv[1]); } cwpc_printf("PASS THE NAME OF THE FILE TO PARSE\n"); return EXIT_FAILURE; } #ifdef __cplusplus } #endif #endif //ALGODAL_GENERATED_PARSER_MAIN_C