dcl代码解析
K&R的第五章最后一个示例程序是一个语法解析器,功能很强大,能将C语言的声明转换文文字形式,例如:
// 输入
int *a
// 输出
a pointer to int
该程序的源码竟然还不到100行。
需要强调的是,dcl和direct-dcl的定义:
dcl: direct-dcl前加一个可选的*
direct-dcl: name
(dcl)
direct-dcl()
direct-dcl[optional size]
一定要记住这个,才能更好的理解dcl和dir-dcl的源码。
void dcl(void)
{
int ns;
for (ns = 0; gettoken() == '*';) /* count *'s */
ns++;
dirdcl();
while (ns-- > 0)
strcat(out, " pointer to");
}
dcl解析*,以及后面跟的dirdcl,解析完成后每个对应一个指针以此打印。
dir-dcl稍微复杂一些。
/* dirdcl: parse a direct declarator */
void dirdcl(void)
{
int type;
if (tokentype == '(')
{
dcl();
/* ( dcl ) */
if (tokentype != ')')
printf("error: missing )\\n");
}
else if (tokentype == NAME) /* variable name */
strcpy(name, token);
else
printf("error: expected name or (dcl)\\n");
while ((type = gettoken()) == PARENS || type == BRACKETS)
if (type == PARENS)
strcat(out, " function returning");
else
{
strcat(out, " array");
strcat(out, token);
strcat(out, " of");
}
}
因为第一次dirdcl的调用发生在dcl之后,而dcl方法调用了gettoken()解析,所以此时已经有token和token_type的信息了,因此先处理 (dcl)
和 name
的情形。再去处理 direct-dcl() direct-dcl[optional size]
的情况。
最后就是gettoken()的实现: