Yacc 范围问题

发布于 2024-10-28 02:08:10 字数 2354 浏览 1 评论 0原文

所以我四处寻找这个问题的答案,但我唯一能收集到的是我遇到了范围问题。

错误读取 ch3-05.y:54: error: Expected '=', ',', ';', 'asm' or 'attribute' before '{' token

这是我的代码逐字

%{
#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; }
    |   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();
    }

我一直盯着屏幕,但还没有任何效果。任何帮助将不胜感激。

另外,后来我又遇到了一些错误,但我认为这可能是因为我还没有解决这个问题。

这是我对 ch3hdr2.h 的内容

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

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

struct symtab *symlook();

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; }
    |   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();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

七禾 2024-11-04 02:08:10

您在 addfunc() 中的拼写错误是 struct sumtab 而不是 struct symtab

否则,代码在 GCC(MacOS X 10.6.7 上的 4.6.0)下编译时会出现一些轻微的问题。

您可能会遇到类似于使用 G++ 而不是 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

这是因为函数样式在 C++ 中无效,即使它在 C 中“OK”(但过时)。

您实际使用的是哪个编译器 -在哪个平台上?


修复拼写错误后,当我将 #include 添加到标头列表并使用 GCC 4.2.1 (XCode 3) 或 GCC 4.6.0 时,代码将编译为警告,但它编译:

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

GCC 4.6.0 输出很有趣 - 更容易看到触发每个警告的内容:

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]

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]
时光与爱终年不遇 2024-11-04 02:08:10

不要看 yacc 代码。打开生成的 y.tab.c 文件(或任何您命名的文件)并查看 C 代码。

这将更好地指示问题所在,因为正是编译器正在尝试处理的问题。有时,yacc 放入 C 代码中的 #file#line 构造只会造成妨碍。

我的第一个想法是它与古老的函数“原型”有关。您可能需要考虑重新执行这些操作,例如:

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

如果做不到这一点,我经常会看到类似于返回类型的定义不存在的错误。确保此时已经完全定义了 struct symtab 。

然后,如果还是不行,把生成的C源代码(包括头文件)以及yacc代码贴出来。

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.

扶醉桌前 2024-11-04 02:08:10

我怀疑问题可能是 addfunc 中的 struct sumtab 。否则,ch3hdr2.h 头文件或它包含的其他一些头文件可能有问题......

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...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文