The union in which the type for the expr variable is declared is... %union { /* this becomes yylval ! */ int val; /* GMP type required here. */ struct symtab *symp; }
The declaration of the variable is... %type <val> expr /* determines that expr is an int, though I really want it any kind of non-terminal */ It is typically called as... | MAX '(' expr ',' expr ')' { $$ = ($3 > $5) ? $3 : $5 ;} Bison advises that the var expr is undeclared. I'm also generally not certain about the declaration of it as expr, a non-terminal, may be a complex statement such as... ne(abs(X0),abs(X1)) // where X0 and X1 may be integral constants, ne is !=, and abs is abs() It is also not clear to me how there is 'linkage' between expr and the symbol table structure that follows. Any help on this would be appreciated. -------------------------------------------------------------------------------------------- The source for the symbol table structure as written so far follows... --------------------------------------------------------------------------------------------- /* symtable.h has the symbol table for storing constants names and values*/ /* l & y 68 */ /****************************************************************************/ #define NUM_SYMS 4096 /* MAXIMUM number of Domains/paramConstants */ /***************************************************************************** a symtab will contain a record for each variable whether Domain (1..20) or Parameter. X1 = 5 Each variable will have a name D0, D1,for domains, or X0, V1 for parameters. *****************************************************************************/ #define NUMBER_DOMAINS 0 #define CONSTANT 1 #define DOMAIN 2 int NUM_DOMAINS; struct symtab /* a domain value(s) or parameter value */ { char name[16]; /* name of each DOMAIN OR PARAMETER */ int symType; /* NUM_DOMAINS (0) or CONSTANT (1) or DOMAIN (2) */ int numDomains; /* number of domains for this program to be compiled */ int numVariables; /* can be almost indefinite for DOMAIN, or 1 for CONSTANT */ int floor_value; /* bottom or only value for a symbol */ int ceil_value; /* top or only value for a symbol */ char cDomain[16]; /* the domain to which this variable belongs */ struct symtab *next; /* next in the list */ } symtab[NUM_SYMS]; /* symtab; */ struct symtab *start; /* start of the symtable list(s) */ struct symtab *previous; /* the previous structure address */ /*struct symtab *set_symbol(char *symbol_name, int value);*/ /* add a new symbol to the list */ struct symtab *symlook(char *symbol_name); /* prototype for the symbol table lookup fn */ --------------------------------------------------------------------------------------------- The so-far source parse.y follows... -------------------------------------------- /* parse.y for the project language */ %{ /* C DECLARATIONS */ #include <string.h> /* if needed for symlook() and strstr()*/ #include <math.h> /* for abs, min max etc */ #include <stdio.h> /* for printf etc */ #include <gmp.h> /* the GMP library */ #include "symtable.h" /* our symbol table */ %} /* BISON DECLARATIONS */ %union { /* this becomes yylval ! */ int val; /* GMP type required here. */ struct symtab *symp; } %token <val> NUM /* Decimal constant. */ %token <symp> NAME /* Domain/parameter name. */ %token NUM_DOMAINS /* how many domains will be declared in the program */ %token IFF %token NEWLINE %token MAX /* functions or macros to be called */ %token MIN %token ABS %token XOR %token PWR %token SEMICOLON /* terminates a statement (line of info) */ %token COMMA /* lowest precedence thru to... */ /* There is no ASSIGN operator */ %right IF /* conditional if */ %left OR %left AND %left EQ NE /* equal to, not equal */ %left LT LE GT GE /* lessThan, lessThanOrEQto, greaterThan,grThanOrEQto */ %left ADD SUB /* addition, subtraction */ %left MUL DIV MOD /* multiply, divide, modulus */ %right NOT /* ! */ %nonassoc NEG /* NEGATION */ %token L_BRAC R_BRAC /* left parenthesis, r parenthesis */ /*... highest precedence is bottom of list above */ %type <val> expr /* determines that expr is an int, whereas really it should be capable of being a non-terminal */ %% /* GRAMMAR RULES OR PRODUCTIONS */ /* see l & y 69..75 */ statement_list: statement '\n' | statement_list statement '\n' ; statement: expr ';' '\n' {printf("\n\n%s\n= %s\n",$1, $1 == 0 ? "FALSE" : "TRUE");} ; expr: /*IFF {;}*/ /* SET UP RULES FOR MACROS / FUNCTIONS / OPERATORS */ | | MAX '(' expr ',' expr ')' { $$ = ($3 > $5) ? $3 : $5 ;} | MIN '(' expr ',' expr ')' { $$ = ($3 < $5) ? $3 : $5 ;} | ABS '(' expr ')' { $$ = ($3 < 0) ? $3 * (-1) : $3 ;} | XOR '(' expr ',' expr ')' { $$ = (($3 || $5) && !($3 && $5)); } | PWR '(' expr ',' expr ')' { $$ = pow($3 , $5);} | IF '(' expr ',' expr ',' expr ')' { $$ = ($3 ? $5 : $7);} | OR '(' expr ',' expr ')' { $$ = ($3 || $5);} | AND '(' expr ',' expr ')' { $$ = ($3 && $5);} | EQ '(' expr ',' expr ')' { $$ = ($3 == $5);} | NE '(' expr ',' expr ')' { $$ = ($3 != $5);} | LT '(' expr ',' expr ')' { $$ = ($3 < $5);} | LE '(' expr ',' expr ')' { $$ = ($3 <= $5);} | GT '(' expr ',' expr ')' { $$ = ($3 > $5);} | GE '(' expr ',' expr ')' { $$ = ($3 >= $5);} | ADD '(' expr ',' expr ')' {$$ = $3 + $5; } | SUB '(' expr ',' expr ')' {$$ = $3 - $5; } | MUL '(' expr ',' expr ')' {$$ = $3 * $5; } | DIV '(' expr ',' expr ')' {if($5 == 0) { yyerror("Division by zero\n"); exit(1); } else $$ = $3 / $5; } | MOD '(' expr ',' expr ')' {$$ = ($3 % $5);} | NOT '(' expr ')' {$$ = !($3);} | NEG '(' expr ')' {$$ = $3 * (-1); } /* SET UP THE SYMBOL TABLE VALUES */ | NUM_DOMAINS expr '\n' { $1->symType = NUMBER_DOMAINS; $1->numDomains = $3; /* number of domains in this program */ } | NAME expr ',' expr '\n'{ $1->symType = CONSTANT; $1->cDOMAIN = $2; $1->floor_value = $4; } | NAME expr ',' expr ',' expr '\n' /* number of fields confirms a DOMAIN */ { $1->symType = DOMAIN; $1->numValues = $2; $1->floor_value = $4; $1->ceil_value = $6; } ; %% /*////////////////////////////////////////////////////////////////////////////////// // look up a symbol table entry, if not present then add it */ struct symtab * symlook(s) char *s; { char *p; struct symtab * sp; for(sp = symtab;, sp < &symtab[NUM_SYMS]; sp++) { /* is variable identifier already here ? */ if(sp->name && !strcmp(sp->name, s)) // s already exists return sp; if(!sp->name) { sp->name = strdup(s); return sp; } /* else go to the next record. */ } /* make provision for either dynamic alloc for symbol records, or */ /* keep a count of array being exceeded, but for now... yyerror("Too many symbols (Constant or domain declarations)\n"); exit(1); // quitted. */ } /*/////////////////////////////////////////////////////////////////////*/ int yyerror(char *error) { printf("%s\n", error); return; } /*////////////////////////////////////////////////////////////////////*/ void init_symtable() { struct symtable * sp; for(sp = symtab; sp->name, sp < &symtab[NUM_SYMS]; sp++) strcpy(sp->name,""); // fill the name fields with nulls } /*////////////////////////////////////////////////////////////////////*/ main() { init_symtable() do /* l & y p. 18 */ { yyparse(); } while(!feof(yyin)); } ======================================= -- View this message in context: http://www.nabble.com/Bison-advises-that-a-variable-%27expr%27-I-use-isn%27t-declared.-tp22425828p22425828.html Sent from the Gnu - Bison - Help mailing list archive at Nabble.com. _______________________________________________ help-bison@gnu.org http://lists.gnu.org/mailman/listinfo/help-bison