开发者

Yacc Scope Problem

So I looked around for an answer to this, but the only thing I could gather was that i was having a scope problem.

The error reads ch3-05.y:54: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘attribute’ before ‘{’ token

Here is my code verbatim

%{
#include <stdio.h>
#include "ch3hdr2.h"
#include <string.h>
#include <math.h>
%}

%union {
    double dval;
    struct symtab *symp;
}
%token <symp> NAME
%token <dval> NUMBER
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS

%type <dval> expression
%%
statement_list  : statement '\n'
                | statement_list statement '\n'
            ;

statement   : NAME '=' expression   {$1->value = $3;}
        | expression        { printf("= %g \n", $1); }

expression  :   expression '+' expression { $$ = $1 + $3;}
    |   expression '-' expression { $$ = $1 - $3;}
    |   expression '*' expression { $$ = $1 * $3;}
    |   expression '/' expression { 
            if($3 == 0.0)
                yyerror("divide by zero");
            else
                $$ = $1 / $3;
            }
    |   '_' expression %prec UMINUS {$$ = -$2;}
    |   '(' expression ')'  { $$ = $2;}
    |   NUMBER
    |   NAME        {$$ = $1->value; }开发者_如何学C
    |   NAME '(' expression ')' {
            if($1 ->funcptr)
                $$ = ($1->funcptr) ($3);
            else {
                printf("%s not a function\n", $1->name);
                $$ = 0.0;
                }
            }
    ;
%%

struct symtab *
symlook(s) 
char *s;
{ // this is where the error is
    char *p;
    struct symtab *sp;

    for(sp = symtab; sp < &symtab[NSYMS]; sp++){
        if(sp -> name && !strcmp(sp->name, s))
            return sp;

    if(!sp->name) {
        sp->name = strdup(s);
        return sp;
        }
}
yyerror("TOO MANY SYMBOLS");
exit(1);
}

addfunc(name, func)
char *name;
double (*func)();
{
    struct sumtab *sp = symlook(name);
    sp->funcptr = func;
    }

main()
{
    extern double sqrt(), exp(), log();

addfunc("sqrt", sqrt);
addfunc("exp", exp);
addfunc("log", log);
yyparse();
    }

I've been staring at the screen but nothing as worked yet. Any help will be greatly appreciated.

Also, I get a few more errors later on, but I think it may be because I haven't resolved this one yet.

Here is what I have for ch3hdr2.h

#define NSYMS 20 /* max number of symbols */

struct symtab {
    char *name;
    double (*funcptr)();
    double value;
} symtab [NSYMS];

struct symtab *symlook();


You have a typo struct sumtab instead of struct symtab at in addfunc().

Otherwise, the code compiles under GCC (4.6.0 on MacOS X 10.6.7) with some minor wittering.

You can get an error similar to the one you get if you compile with G++ instead of GCC:

xx.tab.c: In function ‘int yyparse()’:
xx.tab.c:1252:16: error: ‘yylex’ was not declared in this scope
xx.y:32:41: error: ‘yyerror’ was not declared in this scope
xx.y:42:91: error: too many arguments to function
xx.tab.c:1432:35: error: ‘yyerror’ was not declared in this scope
xx.tab.c:1578:35: error: ‘yyerror’ was not declared in this scope
xx.y: At global scope:
xx.y:52:9: error: ‘symtab* symlook’ redeclared as different kind of symbol
ch3hdr2.h:9:16: error: previous declaration of ‘symtab* symlook()’
xx.y:52:9: error: ‘s’ was not declared in this scope
xx.y:54:1: error: expected unqualified-id before ‘{’ token

That's because the function style is invalid in C++ even though it is 'OK' (but archaic) in C.

Which compiler are you actually using - on which platform?


After fixing the typo, when I add #include <stdlib.h> to the list of headers and use either GCC 4.2.1 (XCode 3) or GCC 4.6.0, then the code compiles with warnings, but it compiles:

yacc  ch3-05.y
/usr/bin/gcc -g -I/Users/jleffler/inc -std=c99 -Wall -Wextra -Wmissing-prototypes \
         -Wstrict-prototypes -Wold-style-definition   -c y.tab.c
In file included from ch3-05.y:3:
ch3hdr2.h:5: warning: function declaration isn’t a prototype
ch3hdr2.h:9: warning: function declaration isn’t a prototype
y.tab.c: In function ‘yyparse’:
y.tab.c:1253: warning: implicit declaration of function ‘yylex’
ch3-05.y:33: warning: implicit declaration of function ‘yyerror’
ch3-05.y: At top level:
ch3-05.y:54: warning: function declaration isn’t a prototype
ch3-05.y: In function ‘symlook’:
ch3-05.y:55: warning: old-style function definition
ch3-05.y:56: warning: unused variable ‘p’
ch3-05.y: At top level:
ch3-05.y:73: warning: return type defaults to ‘int’
ch3-05.y:73: warning: function declaration isn’t a prototype
ch3-05.y: In function ‘addfunc’:
ch3-05.y:74: warning: function declaration isn’t a prototype
ch3-05.y:75: warning: old-style function definition
ch3-05.y:78: warning: control reaches end of non-void function
ch3-05.y: At top level:
ch3-05.y:81: warning: return type defaults to ‘int’
ch3-05.y:81: warning: function declaration isn’t a prototype
ch3-05.y: In function ‘main’:
ch3-05.y:81: warning: old-style function definition

The GCC 4.6.0 output is interesting - much easier to see what triggers each warning:

In file included from ch3-05.y:3:0:
ch3hdr2.h:5:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
ch3hdr2.h:9:8: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
y.tab.c: In function ‘yyparse’:
y.tab.c:1253:7: warning: implicit declaration of function ‘yylex’ [-Wimplicit-function-declaration]
ch3-05.y:33:17: warning: implicit declaration of function ‘yyerror’ [-Wimplicit-function-declaration]
ch3-05.y: At top level:
ch3-05.y:53:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
ch3-05.y: In function ‘symlook’:
ch3-05.y:53:1: warning: old-style function definition [-Wold-style-definition]
ch3-05.y:56:11: warning: unused variable ‘p’ [-Wunused-variable]
ch3-05.y: At top level:
ch3-05.y:72:1: warning: return type defaults to ‘int’ [enabled by default]
ch3-05.y:72:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
ch3-05.y: In function ‘addfunc’:
ch3-05.y:74:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
ch3-05.y:72:1: warning: old-style function definition [-Wold-style-definition]
ch3-05.y: At top level:
ch3-05.y:80:1: warning: return type defaults to ‘int’ [enabled by default]
ch3-05.y:80:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
ch3-05.y: In function ‘main’:
ch3-05.y:80:1: warning: old-style function definition [-Wold-style-definition]
ch3-05.y: In function ‘addfunc’:
ch3-05.y:78:1: warning: control reaches end of non-void function [-Wreturn-type]


Don't look at the yacc code. Open up the generated y.tab.c file (or whatever you've called it) and look at the C code.

That will be a better indicator of what the problem is since that is what the compiler is trying to process. Sometimes the #file and #line constructs that yacc puts into the C code just get in the way.

My first thoughts are that it has something to do with the archaic function "prototypes". You may want to consider re-doing these like:

struct symtab *symlook (char *s) { // this is hopefully where the error isn't :-)
: : :

Failing that, I often see errors similar to that where the definition of a return type is not in existence. Make sure that struct symtab has been fully defined at that point.

Then, if it still doesn't work, post the generated C source code (including header files) as well as the yacc code.


I suspect the problem is probably the struct sumtab in addfunc. Otherwise, its likely something wrong in the ch3hdr2.h header file or some other header file it includes...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜