user14396231
user14396231

Reputation:

Implicit declaration errors and compile errors in YACC

The language that I am dealing with looks like this:

program xyz is 
begin
  print 2 * 10 / (1+4)
end

But this error occured:

calc.y: In function ‘yyparse’:
calc.y:45:18: warning: implicit declaration of function ‘AssignVal’ [-Wimplicit-function-declaration]
   45 |   {AssignVal($1, $3);}
      |                  ^~~~~    
calc.y:54:18: warning: implicit declaration of function ‘checkDuplicate’ [-Wimplicit-function-declaration]
   54 |   {checkDuplicate($1);VarArray[i].var_name = $1; VarArray[i].initialized = 0; i++;}
      |                  ^~~~~~~~~~~~~~
calc.y:54:50: error: ‘VarArray’ undeclared (first use in this function)
   54 |   {checkDuplicate($1);VarArray[i].var_name = $1; VarArray[i].initialized = 0; i++;}
      |                                                  ^~~~~~~~
calc.y:54:50: note: each undeclared identifier is reported only once for each function it appears in
calc.y:54:59: error: ‘i’ undeclared (first use in this function)
   54 |   {checkDuplicate($1);VarArray[i].var_name = $1; VarArray[i].initialized = 0; i++;}
      |                                                           ^
calc.y:71:18: warning: implicit declaration of function ‘checkDenominator’ [-Wimplicit-function-declaration]
   71 |   {checkDenominator($3); $$ = $1 / $3;}
      |                  ^~~~~~~~~~~~~~~~
calc.y:79:18: warning: implicit declaration of function ‘checkInitialize’ [-Wimplicit-function-declaration]
   79 |   {checkInitialize($1);$$ = returnVal($1);}
      |                  ^~~~~~~~~~~~~~~
calc.y:79:63: warning: implicit declaration of function ‘returnVal’ [-Wimplicit-function-declaration]
   79 |   {checkInitialize($1);$$ = returnVal($1);}
      |                                                               ^        
y.tab.c:1501:7: warning: implicit declaration of function ‘yyerror’; did you mean ‘yyerrok’? [-Wimplicit-function-declaration]
 1501 |       yyerror (YY_("syntax error"));
      |       ^~~~~~~
      |       yyerrok
calc.y: At top level:
calc.y:99:6: warning: conflicting types for ‘checkDuplicate’
   99 | void checkDuplicate(char* id)
      |      ^~~~~~~~~~~~~~
calc.y:54:18: note: previous implicit declaration of ‘checkDuplicate’ was here
   54 |   {checkDuplicate($1);VarArray[i].var_name = $1; VarArray[i].initialized = 0; i++;}
      |                  ^~~~~~~~~~~~~~
calc.y: In function ‘checkDuplicate’:
calc.y:106:46: error: ‘yyline’ undeclared (first use in this function)
  106 |    printf("Duplicate ID Error at line %d\n", yyline);
      |                                              ^~~~~~
calc.y: At top level:
calc.y:113:6: warning: conflicting types for ‘checkInitialize’
  113 | void checkInitialize(char * id)
      |      ^~~~~~~~~~~~~~~
calc.y:79:18: note: previous implicit declaration of ‘checkInitialize’ was here
   79 |   {checkInitialize($1);$$ = returnVal($1);}
      |                  ^~~~~~~~~~~~~~~
calc.y: In function ‘checkInitialize’:
calc.y:123:57: error: ‘yyline’ undeclared (first use in this function)
  123 |     printf("Uninitialized Variable Error at line %d\n", yyline);
      |                                                         ^~~~~~
calc.y: At top level:
calc.y:132:6: warning: conflicting types for ‘checkDenominator’
  132 | void checkDenominator(int x)
      |      ^~~~~~~~~~~~~~~~
calc.y:71:18: note: previous implicit declaration of ‘checkDenominator’ was here
   71 |   {checkDenominator($3); $$ = $1 / $3;}
      |                  ^~~~~~~~~~~~~~~~
calc.y: In function ‘checkDenominator’:
calc.y:136:44: error: ‘yyline’ undeclared (first use in this function)
  136 |   printf("Divide by 0 Error at line %d\n", yyline);
      |                                            ^~~~~~
calc.y: At top level:
calc.y:152:6: warning: conflicting types for ‘AssignVal’
  152 | void AssignVal(char * id, int x)
      |      ^~~~~~~~~
calc.y:45:18: note: previous implicit declaration of ‘AssignVal’ was here
   45 |   {AssignVal($1, $3);}
      |                  ^~~~~    
calc.y: In function ‘yyerror’:
calc.y:172:46: error: ‘yyline’ undeclared (first use in this function)
  172 | {    printf("yyerror: %s at line %d\n", str, yyline);

I changed the YACC program.
This time no error occurred, but there was another problem. I tried to test the end result by testing this sample language file:

program xyz is 
begin
  print 2 * 10 / (1+4)
end

Even though this sample was grammatically correct the result would show as:

yyerror: syntax error at line 1
reject

Every other sample showed the same result as above.

What is the problem here?

Upvotes: 0

Views: 221

Answers (1)

rici
rici

Reputation: 241861

Your input is not grammatically correct (according to your grammar). Your grammar says:

program : PROGRAMnumber IDnumber ISnumber declaration compoundstatement

with

declaration : VARnumber declaration2

So the token after is must be var, according to the grammar. That's not the case, so you have a syntax error.

It's possibly a bit confusing that your parser reports that the syntax error is on line 1, since it actually is produced when the parser sees the begin token when it was expecting a var token, and the begin token is at line 2. The reason for this error is that you (implicitly) initialise yyline to 0, and it stays 0 until the first newline character is encountered. If you consider the first line of the input to be line 0, this is correct behaviour, but for the sake of most of the world which considers the first line to be line 1, it would be more reasonable to initialise

int yyline = 1, yycolumn = 1;

The "implicit declaration" in your first attempt is what happens in any C program, whether or not it is generated by yacc/bison, when you use a function before declaring it. That's actually an error, but GCC "generously" lets you get away with it because (very) old versions of C allowed functions to be implicitly defined, as long as they returned an int and were called with exactly the correct argument types. Modern C requires a declaration, so implicit declarations are thankfully no longer valid. In the (hopefully near) future, C will no longer allow declarations of functions which don't specify the argument types, either, and the declarations you inserted with empty parameter lists are now considered deprecated.

As @NateEldredge says in a comment, you really should declare your functions with correct prototypes, and you would be better off putting those declarations in a header file.

Upvotes: 1

Related Questions