help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Section 3.1.1 User's Manual Question on $code require


From: slipbits
Subject: Section 3.1.1 User's Manual Question on $code require
Date: Sat, 18 Jun 2022 12:09:11 -0700
User-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.10.0

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]