yangnas 发表于 2010-08-11 17:27

很奇怪的lcc编译器,表达式分析代码

本帖最后由 yangnas 于 2010-08-11 17:32 编辑

最近在分析LCC编译的表达式语法分析部分代码时,看到分析primary-expression的代码
函数如下(注意下面函数中的加红色部分):

static Tree primary(void) {
        Tree p;

        assert(t != '(');
        switch (t) {
        case ICON:
        case FCON: p = tree(CNST + ttob(tsym->type), tsym->type, NULL, NULL);
                   p->u.v = tsym->u.c.v;
break;
        case SCON: tsym->u.c.v.p = stringn(tsym->u.c.v.p, tsym->type->size);
                   tsym = constant(tsym->type, tsym->u.c.v);
                   if (tsym->u.c.loc == NULL)
                           tsym->u.c.loc = genident(STATIC, tsym->type, GLOBAL);
                   p = idtree(tsym->u.c.loc); break;
        case ID:   if (tsym == NULL)
                           {
                                Symbol q = install(token, &identifiers, level, level < LOCAL ? PERM : FUNC);
                                q->src = src;
                                t = gettok();
                                if (t == '(') {
                                        Symbol r;
                                        q->sclass = EXTERN;
                                        q->type = func(inttype, NULL, 1);
                                        if (Aflag >= 1)
                                                warning("missing prototype\n");
                                        (*IR->defsymbol)(q);
                                       if ((r = lookup(q->name, externals)) != NULL) {
                                                q->defined = r->defined;
                                                q->temporary = r->temporary;
                                                q->generated = r->generated;
                                                q->computed = r->computed;
                                                q->addressed = r->addressed;
                                        } else {
                                                r = install(q->name, &externals, GLOBAL, PERM);
                                                r->src = q->src;
                                                r->type = q->type;
                                                r->sclass = EXTERN;
                                        }
                                } else {
                                        error("undeclared identifier `%s'\n", q->name);
                                        q->sclass = AUTO;
                                        q->type = inttype;
                                        if (q->scope == GLOBAL)
                                                (*IR->defsymbol)(q);
                                        else
                                                addlocal(q);
                                }
                                if (xref)
                                        use(q, src);
                                return idtree(q);
                        }
                   if (xref)
                           use(tsym, src);
                   if (tsym->sclass == ENUM)
                           p = consttree(tsym->u.value, inttype);
                   else {
                           if (tsym->sclass == TYPEDEF)
                                   error("illegal use of type name `%s'\n", tsym->name);
                           p = idtree(tsym);
                   } break;
        default:
                error("illegal expression\n");
                p = consttree(0, inttype);
        }
        t = gettok();
        return p;
}

因为primary-expression的文法如下:
primary-expression:
   identifier
   constant
   string-literal
   '(' expression ')'
我猜想,primary()函数里应该有判断 t == ‘(' 的代码才对啊(此处的t为超前扫描的token),为什么在程序的一开头就来一个assert(t != '(' )
百思不得其解。。。

yangnas 发表于 2010-08-11 17:42

当我第一眼看到,primary-expression的文法时
想到,肯定有判断 t == ‘('的代码,怎么我看lcc的代码怎么一上来就assert(t != '(' )
:(

EricFisher 发表于 2010-08-11 18:21

大体看了下,猜测如下:

primary()是由unary()调用的,在unary()中,当t为'('时,会先作处理。只有当t不为'('时,才会调用postfix(primary()),所以,这个时候的primary expression就没有 '(' expression ')' 这样的情况了。

yangnas 发表于 2010-08-12 00:24

谢谢,楼上!
页: [1]
查看完整版本: 很奇怪的lcc编译器,表达式分析代码