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