Section 3.1.1 User's Manual Question on $code require

slipbits <[email protected]> Sat, 18 Jun 2022 12:09:11 -0700
Newsgroups gmane.comp.parsers.bison.general
Message-ID <[email protected]>
I've included my understanding of a few sections in the Bison User's 
Manual. What I am confused about is whether the declarations in %code 
require { declarations } are included in both the header file, if 
%header is given, and the source file (basename.<ext>). The text in the 
User's Manual, pg. 50 says  “and the new YYLTYPE definition before the 
Bison-generated YYSTYPE and YYLTYPE definitions in both the parser 
implementation file and the parser header file", which seems to say that 
it is.

thanks
art


      3.1 Outline of a Bison Grammar

The input Bison file contains 3 sections, {Declarations, Grammar Rules, Epilog}. The Declarations must precede the Grammar Rules, which must precede the Epilog Section. As in:

Declarations
%%
Grammar Rules
%%
Epilog

All Sections are optional except the Grammar Rules Section.

The Declarations Section consists of intermixed Prologue Declarations and Bison Declarations. The Prologue Declarations contains language specific declarative statements. The Bison Declarations contains Bison specific declarations, declarative statements which generate language specific output and execution time environmental directives (such as the names of files). This section is only concerned with declaration directives which cause generation of language specific declarations.

There may be many Prologue and Bison Declarations given in any order. There can only be one Grammar Rules Section and Epilog Section. The Prologue and Bison Declarations terminate when the Grammar Rules sections starts. After Grammar Rules are initiated, no Prologue or Bison Declaration statements are allowed.

The Prologue and Declaration Sections act in concert. The Prologue Declaration data is moved verbatim to the generated parser file, and some Bison Declarations cause output of data to the generated parser file,/basename/.<ext>. The Bison statements themselves are not copied to the generated parser, only the generated code.

For purposes of this section,/basename/.y is the Bison input file, and/basename/.<ext> is the generated parser file, where <ext> is the language specific suffix.

3.1.1 Order Independent Declarations
The Prologue Declarations and Bison Declarations are put in the generated parser file, or/basename/.<ext>, or header file,/basename/.h, or imported file in the order seen. That is, if the order of appearance in/basename/.y is “B P P B P”, then the order of elements in the generated parser file is “B P P B P” where P stands for Prologue Declarations and B stands for Bison*Declerations*  in/basename/.y and Declaration expansions in/basename/.<ext>.

The Prologue Declarations determines the content of language specific statements to be copied to the generated parser code. Positioning  preserves the application specific dependency order of statements, that is, when there is a dependency order where one statement must precede another, positioning allows preservation of that order. Positioning is strictly a consequence of the placement of the Prologue Declaration in/basename/.y.

An example of a dependency in C/C++ is:
typedef YYSTYPE YYSTYPE;
func(YYSTYPE x);

whereYYSTYPE  must be known before the function prototype is declared. If the order were reversed:
void func(YYSTYPE x);
typedef YYSTYPE YYSTYPE;

the function prototype would be incorrect because YYSTYPE was unknown.

In Bison this ordering is guaranteed by using:
%{
     typedef YYSTYPE YYSTYPE;
     void func(YYSTYPE x);
%}

or
%{typedef YYSTYPE YYSTYPE; %}
%{ void func(YYSTYPE x); %}

where “%{ declarations %}” is defined as a/Prologue Definitinn Block //(PDB)/. “%{  %}” is legal.

This is more complicated when there are Bison Declarative dependencies. In this case, a Bison Declarative generates code copied to/basename/.<ext> in which either other Bison Declaratives have a dependency or in which there is source dependency. In this case, the order of Prologue Dependencies must be sensitive the the Bison Declaratives.

Let’s consider the example above. As it turns our, YYSTYPE is determined by using the Bison Declarative %union. Suppose we have the following statements:
typedef int X;		// C/C++
%union { X Y }		// Bison Declarative
void func(YYSTYPE x);   // C/C++

What we have is that %union is dependent on the typedef, and the functionprototype is dependent on %union. How should be arrange our Prologue Directive and Dison Directives to ensure that the dependencies are supported. (This is an easy case, mind you):
%{ typedef int X;	%}	     // C/C++
%union { X Y }		     // Bison Declarative
%{ void func(YYSTYPE x); %}  // C/C++

The first Prologue Directive gets copied verbatim to/basename/.<ext>, the code generated by the Bison Declarative gets put into/basename/.<ext> next, and finally the 2^nd    Prologue Directive gets copied verbatim to/basename/.<ext>.

This is a simple case. More complex cases cause indigestion amongst the unwary, but help is on the way in 3.1.2 Order Specific Declaration. Note that the Bison ordering of elements in/basename/.<ext> are not considered here.

One other point. It is possible to specify that a header file be constructed,/basename/.h using, for example, the Bison Declarative %*api.header.include **o**r %header or %header **/filename/**.**The header will contain the Prologue Directives and the Bison 
Directives consistent with the order used in **/basename/**.<ext>. **For purposes of this section, we will consider all header files as 
having the format **/basename/**.h. In Java, a header file is an importable class containing 
declarations, and in D it is an importable document containing D 
declarations.*
*In all languages, it is possible to rename **/basename/**, **/basename/**.<ext> and **/basename/**.h. For purposes of this discussion we will treat **/basename/**as the standard name.*

Since the Prologue Declarations are copied to/basename/.<ext> in the order seen.

If the parser is for C then the following additional rules apply:

 1.

    C trigraphs are ignored.C digraphs for ‘{‘ and ‘}’ must be balanced.

 2.

 3.

    “%{“ and “%}” are allowed in comments in all languages.

Summary:
Standard Prologue declarations are delimited by “%{“ and “%}” as in

      %{ declaratives %}
Items contained in this section cause a verbatim transfer of data from the Bison input to/basename/.<ext>. This means that if there is a mixture of Prologue statements and Bison Declarative statements, they are each transferred to the/basename/.<ext> in the order seen, as in:

    /basename.y/

    	


    	

    /basename/.<ext>

    %{ declarative 1 %}

    	


    	

    declarative 1

    Bison Declaration 1

    	


    	

    Bison Declaration 1

    %{ declarative 2 %}

    	

    --->

    	

    declarative 2

    %{ declarative 3 %}

    	


    	

    declarative 3

    Bison Declaration 2

    	


    	

    Bison Declaration 2

where Bison Declarations cause the generation of source language declarations to be inserted into/basename/.<ext>

3.1.2 Order Specific Declarations
There are cases where it is difficult to use the standard order, or the standard order defeats other objectives. In these cases there is a mechanism to force the placement ofPrologue Definitinn Blocks  and Bison Declaratives into a defined order tnto/basename/.<ext>.

As an example, consider the dedicated Bison Declarative statement %union (for C/C++). This statement defines the possible token values returned from the lexer/scanner, and defines them as a type (YYSTYPE) which allows an object of this type to be returned for all of the various lexer values.

Let us use the ordering statements in this section to look at our previous example.
typedef int X;		// C/C++
%union { X Y }		// Bison Declarative
void func(YYSTYPE x);  // C/C++

We guarantee that the dependency is resolved by guaranteeing that each item above is put into its correct location in/basename/.<ext>. This is done by:

%code top { typedef int X; }   // C/C++
%union { X Y }                 // Bison Declarative
%code { void func(YYSTYPE x); }// C/C++

where %code top guarantees the the typedef is placed before the %union and %code guarantees the function prototype is placed after. Further,
%code { void func(YYSTYPE x); }// C/C++
%union { X Y }                 // Bison Declarative
%code top { typedef int X; }   // C/C++

Works just as well because the Order Specific Declarations state where the code is to go. In fact, any combination of the above statement would work just as well. The Order Specific Declarations are not sensitive the placement of the declarations within/basename/.y.

The generated parser, in all languages, is separated into allocation sections. The location of these sections is language dependent, but the basic content and organization is as specified below.

/basename/.<ext>

	

/basename/.h

Bison Preamble

	

Bison Preamble

Top Block

	

%Token definitions

Require Block

	

Require Block

YYSTYPE, |YYLTYPE|  

	

YYSTYPE, YYLTYPE

Bison Declaration Expansions

	

Bison Declaration Expansions

Provide Block

	

Provide Block

Bison Epilog

	

Bot Block

Bot Block

	

    The description of these different generated parser locations is below.

 1.

    Bison Preamble: A pro forma set of generated statements output by Bison. This region is exclusive to Bison.

 2.

    Top Block: Defined as “%code top { declarations }”. Placement immediately after the Bison Preamble declarations. The contents are the same as for aPDB  block with the additional condition that placement in the generated file is made explicit.

 3.

    Require Block: Defined as “%code require { declarations }”. Declarations are placed before the YYSTYPE and YYLTYPE declarations.

 4.

    YYSTYPE, YYLTYPE  Declaration:

 5.

    Bison Declaration Expansions. The code generated by Bison directive is placed immediately following Top. This can either be in the C/C++ header file, the D, Java import files, or in the generated parser depending on Bison directives used. Bison declaratives are placed in this region in the order seen. That is, if declaration1 occurs in the Bison input file,/basename/.y, before declaration2, the in the generated parser declaration1 precedes declaration2.

 6.

    Provide Block: Defined as “%code require { declarations }”. Declarations are placed after the YYSTYPE and YYLTYPE declarations.

 7.

    Bison Epilog. Bison code required to ensure proper function of the generated parser are placed here. This region is exclusive to Bison.

 8.

    Bot: Application code placed immediately before yyparse().

The positioning regions are:

 1.

    %code import {/declarations/  } [D, Java] defines an/import block/. Contains only language import directives. Placed before the Java Class declaration in a file. IN D, placed before any class definitions.

 2.

    %code provides {/declarations/  } [C/C++] defines a/provide block/. Placed after the defintions for YYSTYPE and YYLTYPE.

 3.

    %code requires {/declarations/} [C/C++] defines a/require block//

    Copies the/declarations/  to/basename/.h, if a header file is specified through a Bison declaration. In all cases, copies the declarations to/basename/.<ext> and treats the require block as a top block. The declarations are placed before the Bison generated declarations for YYSTYPE and YYLTYPE. YYSTYPE defines the location structure used to define the beginning and end of a token(s) received from the scanner/lexer, subject to changes done as a result of grammar rule reductions. YYSTYPE defines the values returned by the scanner/slexer.
    NOTE: See 3.1.2 Prologue Alternatives, pg. 50 “and the new YYLTYPE definition before the Bison-generated YYSTYPE
    and YYLTYPE definitions in both the parser implementation file and
    the parser header file”. This position causes, in this case, YYLTYPE to be doubly defined in the same scope and is probably a C/C++ error. What you probably mean is that in the absence of %header, the require block is treated as a top block. When a %header is present, the declarations in the require block are copied to/basename/.h.

 4.

    %code top {/declarations/  } [C/C++] defines a top/block/. Placed after any Bison Preamble declarations. Figuratively, placed at the top of/basename/.h or/basename/.<ext> before any other declarations.

 5.

    %code {/declarations/  } [C/C++, D, Java] defines a/bot block/. Places the declarations before the yyparse() prototype/definition. All declarations made in any %code <tag> blocks are available for use.

Codes are concatenated. If two code with the same tag appear in any order in/basename/.y, then they are
concatenated in the order found. For example:

%code provide { declaration1; }
%code         { declaration2; }
%code provide { declaration3; } // becomes

%code provide { declaration1;
                 declaration3; }
%code         { declaration2; }


The organization (when things appear) in basename.y are ignored.
  
The %code blocks are sorted by tags and then concatenated as required.
The sort preserves the order of %code blocks seen, that is, if we have:

%code tag1 { declaration1; }
%code tag2 { declaration2; }
%code tag1 { declaration3; } // becomes

%code tag1 { declaration1; }
%code tag1 { declaration3; }
%code tag2 { declaration2; } // and  after concatenation

%code tag1 { declaration1; }
              declaration3; }
%code tag2 { declaration2; }

Here is an extended example in C/C++. Suppose we have:

%code         { declaration1 }
%code provide { declaration2 }
%code require { declaration3 }
%code         { declaration4 }
%code top     { declaration5 }
%code top     { declaration6 }
%code require { declaration7 }


This is copied to/basename/.h and/basename/.<ext> as:


	

%heading

/basename/.<ext>

	

/b//asename.h/

	

/basename.<ext>/

declaration5 declaration6

	

declaration5 declaration6

	

declaration3 declaration7

declaration3 declaration7

	

declaration3 declaration7

	

YYSTYPE, YYLTYPE

YYSTYPE, YYLTYPE

	

YYSTYPE, YYLTYPE

	


declaration2

	

declaration2

	


declaration1 declaration4

	

declaration1 declaration4

	



where %heading indicates that a heading (/basename/.h) file is required.

The example shows the rearrangement of declarations according to their tags and the concatenation of declarations with the same tag.

Summary:
The code blocks are sensitive to the language and can not be intermixed. %code blocks with the same tag are concatenated in the order seen before placement into/basename/.h,/basename/.<ext>. Tor order of %code definitions are independent of their placement in a header file, source file, or class.

%code tag

	

C/C++

	

D/Java

	

Description

%code

	

•

	


	

Placed after all declarations

%code import

	

•

	

•

	

Placed in an importable class

%code provides

	

•

	


	

Placed after YYSTAB, YYLTYPE declearation

%code requires

	

•

	


	

Placed before YYSTAB, YYLTYPE declearation

%code top

	

•

	


	

Placed after Bison prologue and before %code require