我目前正在创建一个解析器库,出于测试目的,我希望能够在主repl运行时加载其中一个解析器。它读取命令并执行解析器,可以通过按下Ctrl-D退出,就像shell一样。我该如何在运行时选择我想要的解析器?我应该:
我希望我的程序是跨平台的(所以如果我做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,我实际上可以像我想的那样一次加载一个解析器。我应该使用以下哪种方法?我是否应该只加载我使用的解析器,或者与加载它们相比它是否值得呢?