微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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 */

原文地址:https://www.jb51.cc/c/114228.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐