Reputation:
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
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