Yacc Scope Problem - PullRequest
       1

Yacc Scope Problem

1 голос
/ 30 марта 2011

Так что я искал ответ на этот вопрос, но единственное, что я смог собрать, это то, что у меня возникла проблема с областью видимости.

Ошибка читается как ch3-05.y: 54: ошибка: ожидается ‘=’, ‘,’, ‘;’, ‘asm’ или ‘ атрибут ’ перед символом ‘{’

Вот мой код дословно

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

Ответы [ 3 ]

2 голосов
/ 30 марта 2011

У вас есть опечатка struct sumtab вместо struct symtab в addfunc().

В противном случае код компилируется в GCC (4.6.0 в MacOS X 10.6.7) с небольшим увяданием.

Вы можете получить ошибку, аналогичную той, которая появляется, если вы компилируете с 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.

Какой компилятор вы на самом деле используете - на какой платформе?


После исправления опечатки, когда я добавляю #include <stdlib.h> в список заголовков и использую либо 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]
0 голосов
/ 30 марта 2011

Я подозреваю, что проблема, вероятно, struct sumtab в addfunc.Иначе, вероятно, что-то не так в заголовочном файле ch3hdr2.h или в каком-либо другом заголовочном файле, который он включает ...

0 голосов
/ 30 марта 2011

Не смотрите на код YACC.Откройте сгенерированный файл y.tab.c (или как вы его назвали) и посмотрите на код C.

Это будет лучшим индикатором проблемы, поскольку означает, что что компилятор пытается обработать.Иногда конструкции #file и #line, которые yacc вставляет в код C, просто мешают.

Мои первые мысли о том, что это как-то связано с архаичной функцией "прототипы".Возможно, вы захотите повторить это, например:

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

В противном случае я часто вижу ошибки, подобные тем, где определение возвращаемого типа не существует.Убедитесь, что struct symtab полностью определен на этом этапе.

Затем, если он все еще не работает, опубликуйте сгенерированный исходный код C (включая файлы заголовков), а также код yacc.

...