我想创建一个程序,检查输入在C语法中是否有效

时间:2015-04-09 17:48:08

标签: c

如何创建一个C程序,它接受C中的命令作为输入,如果有任何错误则打印?

例如,

    Input: for(i=0; i<5; i++);
    No errors.

    Input: for((i=0); i>2,(i<5) ; i++);
    No errors.

    Input: for(i=0, i<5; i++);
    Error.

    Input: for((i=0; i<5; i++));
    Error.

我认为最简单的方法是编译输入字符串,并检查是否发生任何错误。但我不知道如何编译在运行时传递的一段代码。此外,存在未声明变量的问题。

1 个答案:

答案 0 :(得分:2)

C解析时特别复杂。即使你删除它的预处理器一面,仍然有棘手的部分。

如果您正在为自己学习,可以查看C语法(有一些用于ANSI C的lex / yacc格式),您可以查看。

从你的例子中我想你想要只识别C的一个子集,而不是整个语言,对吗?如果是这种情况,您应该定义该子集并为其编写解析器。

如果你还没有使用它们,你应该学习语法和解析器生成器,而不是尝试手工编写解析器。

如果它是您感兴趣的C的子集,我会使用像PackCC这样的PEG解析生成器来轻松获取解析器。

作为一个超级简单的例子,以下解析器:

%prefix "mc"

stmt <- _ assign            { printf("assignment\n"); }   
     / _ if                 { printf("if\n"); }
     / ( !EOL . )* EOL      { printf("error\n"); }

if <- 'if' _ '(' _ var _ ')' _ stmt 

assign <- var _ '=' _ num _ ';' _ EOL
var    <- [A-Za-z_] [0-9A-Za-z_]*
num    <- [0-9]+
_      <- [ \t]*
EOL    <- '\n' / '\r\n' / '\r'

%%
int main() {
    mc_context_t *ctx = mc_create(NULL);
    while (mc_parse(ctx, NULL));
    mc_destroy(ctx);
    return 0;
}

将接受赋值(其中左值是变量名,右值是整数)和if语句是变量名的语句。假设解析器位于文件mu.peg

home> packcc mu.peg
home> gcc -o mu mu.c
home> ./mu
t = 5;
assignment
t = 5
error
if (x) p = 3;
assignment
if
if (x) if (y) t = 3;
assignment
if 
if

相反,如果您需要在运行时检查sintatically有效的C代码,并且系统上安装了编译器,通常是GCC或Clang,您可以通过system()调用它并拦截任何错误。根据您要对代码执行的检查类型,您可以考虑使用静态分析器,如splint

如果您需要在应用程序中嵌入所有内容,可以尝试使用tcc作为库。