c – 解析一个int(x)参数
这里是一个简单的函数,一个int参数:
void f(int x) {} f(42); 这里还有一个int参数的函数: void g(int(x)) {} g(42); 现在让我们将x定义为一个类型: typedef int x; void h(int(x)) {} h(42); // warning: passing argument 1 of ‘h’ makes pointer from integer without a cast (这是我用gcc 4.8.2观察的行为) 解析器作者如何处理这种情况? 看来经典的流水线Lexer – >解析器 – >语义检查器 – > …在这里不工作 解决方法
你有效地将h定义为:
void h(int(int)) {} 该参数被解释为一个未命名的函数指针,它接受一个int并返回一个int.当您尝试传递42时,编译器会抱怨您正在尝试从一个整数形成一个函数指针. 我想你所要求的是编译器如何处理(未命名)函数指针类型及其可能含糊的解析.您的问题与C中的the most vexing parse有关. 在那里,他们决定,每当函数指针类型和另一种解析方式之间存在歧义时,它将被解释为函数指针.他们做到这一点,因为当你不想让它成为一个函数指针时,有其他的方法可以消除歧义(例如 – 用括号括起来,使用{}初始化语法等). 了解解析器作者如何处理此解析的细节,以下是C11:http://quut.com/c/ANSI-C-grammar-l-2011.html的词法分析器和语法在您的示例中,在typedef之前,x在之后将是一个IDENTIFIER令牌,它将是一个TYPEDEF_NAME令牌,因为分析仪正在通过符号表通知x现在是一种类型.在这种特殊情况下,解析是明确的.在这种情况下,您通过符号表发出的“流水线反馈”发生在这种情况下,在汇编进行时,词汇分析器会被上级影响其输出的上级信息通知上下文. 编辑:These three articles,由OP发现,描述了这个问题,以及它如何被一些C解析器/编译器非常好地解决.基本上,几乎可以指定仅接受/产生合法C语法的上下文无关语法(CFG).通过引入范围查找表,允许词法分析器适当地区分标识符和typedef名称,那么只能接受/产生合法C的CFG [和更重要的是LALR(1)解析器(例如,yacc生成)]可以指定语法. 这是一个比OP更可怕的例子: typedef int x; int main() { x x = 5; return x; } /* crazily enough this is legal C syntax and a well formed C program */ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |