Austin Group Defect Tracker

Aardvark Mark IV


Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0001388 [1003.1(2016/18)/Issue7+TC2] Shell and Utilities Objection Omission 2020-08-11 14:17 2020-08-19 16:42
Reporter geoffclare View Status public  
Assigned To
Priority normal Resolution Open  
Status New  
Name Geoff Clare
Organization The Open Group
User Reference
Section yacc
Page Number 3456
Line Number 116732
Interp Status ---
Final Accepted Text
Summary 0001388: yacc description does not say who declares yyerror() and yylex()
Description The description of yacc talks about the functions yyerror() and yylex() in various places, but nowhere does it state who is responsible for declaring them. This means that, in practice, a portable application has to declare them in the .y file (if it does not define them) in case yacc does not provide declarations of them in the code file and the compiler that will be used treats calls to undeclared functions as an error.

It doesn't take much thought about the reasons why prototypes were added to the C language to come to the conclusion that the greatly preferable solution is for yacc to be required to supply prototypes for yyerror() and yylex() that match the yyerror() definition in its library and the yylex() definition produced by lex, even (some might say especially) if the .y file includes definitions of those functions to be used instead of the library version of yyerror() and a lex-generated yylex().

There is also no statement about a declaration of main(), but the situation for main() is quite different from the above two functions. Although in theory an application could call yacc's library version of main() from code in a .y file, it is questionable why any application (other than a test suite) would do so, in particular because that version of main() does not accept any arguments and it calls exit() -- it does not return -- and therefore is of little use recursively. An application that provides its own main() could call it recursively, but can reasonably be expected to ensure it does not call main() without previously defining or declaring it. In addition, since main() has multiple different allowed prototypes, if yacc were to output a declaration it would have to be a non-prototype one:

int main();

so that there is no risk of a clash with a definition of main() that has a different prototype, but there does not seem much point in it producing such a declaration. (Or it could check whether the .y file contains a definition of main() and output a prototype declaration if it does not contain one, but that seems impractical.)

The simplest solution is just not to allow yacc to provide a declaration of main().
Desired Action On page 3456 line 116732 section yacc (Code File), change:
It also shall contain a copy of the #define statements in the header file.
to:
It also shall contain prototype declarations of the yyerror() and yylex() functions, and a copy of the #define statements in the header file, prior to any code copied from within <tt>%{</tt> and <tt>%}</tt> in the declarations section in grammar.

On page 3456 line 116734 section yacc (Code File), add a new paragraph:
The code file shall not contain a declaration of the main() function, unless one is present within <tt>%{</tt> and <tt>%}</tt> in the declarations section in grammar.

On page 3469 line 117335 section yacc (RATIONALE), add new paragraphs:
Earlier versions of this standard did not require the code file created by yacc to contain declarations of yyerror() and yylex(). This meant that portable applications that did not define them had to declare them in the grammar file, to ensure they would not be diagnosed by the compiler as being called without being declared, but this was not stated in those versions of the standard either. The standard developers decided it was preferable for yacc to include the declarations in the code file and this is now a requirement.

Earlier versions of this standard were also silent about a declaration of main(). However, the equivalent solution was not adopted since a declaration of main() would only be needed if it is called recursively by an application. Although in theory an application could call the yacc library version of main() from code in a grammar file, it is questionable why any application (other than a test suite) would do so, in particular because that version of main() does not accept any arguments and it calls exit() -- it does not return -- and therefore is of little use recursively. An application that includes its own definition of main() could call it recursively, but can reasonably be expected to ensure it does not call main() without previously defining or declaring it. An additional complication is that main() has multiple different allowed prototypes. The standard developers decided the simplest solution was not to allow yacc to provide a declaration of main() in the code file.

Tags No tags attached.
Attached Files

- Relationships

-  Notes
(0004919)
shware_systems (reporter)
2020-08-11 16:53

A collateral issue is ensuring yyin is declared as a FILE *, if yyparse() is linked to a yylex() generated by lex, in a manner accessible to code calling yyparse(). This adds an implied requirement on the .c or .h file produced to do a #include <stdio.h> to get the defining declaration of FILE.

The example main() for lex assumes such a declaration of yyin is produced at the top or bottom of the %% section, but there is no requirement this be an extern the header produced by yacc could reference. The lex description just has it shall be used, nothing on how it is to be declared, actually. The main() example for yacc doesn't declare or assign stdin to it either, assuming yylex() does this by default somehow on first call if generated by lex, or accesses stdin directly in a yylex() implemented in the programs section of the .y file.

Maybe this has been addressed as part of some other bug, but I don't remember any such discussion offhand.
(0004928)
Konrad_Schwarz (reporter)
2020-08-19 10:08

Aren't default implementations of these symbols defined in the -ly library?
(0004931)
shware_systems (reporter)
2020-08-19 16:42
edited on: 2020-08-19 16:44

Yes, but when a compiler requires the absence of any main() to be found to format an a.out as a dynamic library, rather than a utility executable, the use of liby and libl is precluded so the compile doesn't see the main() in those libraries. As such, the output of yacc or lex needs to be compile-able in a manner that doesn't require any library to provide those prototypes implicitly.


- Issue History
Date Modified Username Field Change
2020-08-11 14:17 geoffclare New Issue
2020-08-11 14:17 geoffclare Name => Geoff Clare
2020-08-11 14:17 geoffclare Organization => The Open Group
2020-08-11 14:17 geoffclare Section => yacc
2020-08-11 14:17 geoffclare Page Number => 3456
2020-08-11 14:17 geoffclare Line Number => 116732
2020-08-11 14:17 geoffclare Interp Status => ---
2020-08-11 16:53 shware_systems Note Added: 0004919
2020-08-19 10:08 Konrad_Schwarz Note Added: 0004928
2020-08-19 16:42 shware_systems Note Added: 0004931
2020-08-19 16:44 shware_systems Note Edited: 0004931


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker