在C中运行时选择库

时间:2014-09-18 22:42:25

标签: c exec dynamic-linking

我目前正在创建一个解析器库,出于测试目的,我希望能够在主repl运行时加载其中一个解析器。它读取命令并执行解析器,可以通过按下Ctrl-D退出,就像shell一样。我该如何在运行时选择我想要的解析器?我应该:

  1. 包括我可能使用的所有解析器并运行用户选择的解析器,
  2. 使用动态库系统(如dlfcn(或更好的替代方案?))加载和卸载所需的解析器,
  3. 为每个解析器分别执行一个单独的程序,或
  4. 不使用主repl,只需将repl编译到每个解析器中并单独运行它们。
  5. 我希望我的程序是跨平台的(所以如果我做2或3我需要在Windows上使用草率功能),最好是内存和CPU光。我不想获得完整的解决方案,只是为了知道我的哪些想法(或其他想法)最有效。

    这是我的主程序(当前没有重新编译时不会切换解析器):

    //run_parser.c
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include "get_line.h"//getline clone
    #include "ptree.h"//parse tree library; used for all parsers
    #include "parser_llk.h"//parser library; used for all parsers
    #include "tree_parser.h"//two different parsers that I do not want loaded at the same time, if feasible.
    #include "calc_parser.h"
    #include "debug.h"
    #define START start //current compile-time parser switch
    int main(int argc, char **argv){
        FILE *file = stdin;
        if(argc < 2){
            puts("No file specified, reading from stdin:");
        }else{
            file = fopen(argv[1], "r");
            if(!file){
                printf("Could not open \"%s\"!  Reading from stdin:\n", argv[1]);
                file = stdin;
            }
        }
        size_t length = 0;
        char *line = NULL;
        int read = 0;
        Position *p;
        Ptree *t;
        while((read = getLine(&line, &length, file)) > 0){
            line[read - 1] = '\0'; //remove new line
            printf("\"%s\"\n", line);
            t = mallocPtree();
            p = firstPosition(line);
            if(START(p, t)){//calls the START parser on the line entered (THE THING I WANT TO CHANGE AT RUNTIME)
                puts("Parsed successfully.  Output:");
                flattenTagged(t);//remove most single child nodes in parse trees (all but those with no grandchildren)
                printPtree(t, 0);
            }else{
                puts("Parsed unsuccessfully");
            }
            deletePtree(t);
            free(t);
            free(p);
        }
        free(line);
        fclose(file);
    }
    

    我当前的实现只是通过#including并链接它来加载每个解析器,这对于更复杂的后处理(如解释器)的解析器来说似乎不可扩展。每个解析器都应该有一个start函数来解析一些输入和一个execute函数,它开始后期处理(解释,编译,计算等)。如果我采用策略1或4,这就是我真正需要的。如果我使用2或3,我实际上可以像我想的那样一次加载一个解析器。我应该使用以下哪种方法?我是否应该只加载我使用的解析器,或者与加载它们相比它是否值得呢?

0 个答案:

没有答案