File:  [Local Repository] / gnujdoc / bison-1.28 / bison-ja.texinfo
Revision 1.4: download - view: text, annotated - select for diffs
Tue May 31 11:32:03 2005 UTC (15 years, 5 months ago) by futoshi
Branches: MAIN
CVS tags: HEAD
bison-1.28 delete one footnote :-(
flex-2.5.4 version down to flex-2.3.7 :-(
* @ifset does not work fine :-(

\input texinfo @c -*-texinfo-*-
@c =============================================================
@c = 翻 訳: 石川直太@慶應義塾
@c = ただし、GPLに関しては引地美恵子(mieko@gnu.org)の管理して
@c = いる日本語訳(FSFの指示に従って弁護士のレビューを経たもの)
@c = を用いた。
@c =============================================================
@c
@c Bison 1.25 から Bison 1.28 の変更点は
@c 林芳樹 <t90553@mail.ecc.u-tokyo.ac.jp> が訳しました。
@c
@comment %**start of header
@setfilename bison-ja.info
@include bison-v.texi
@settitle Bison @value{VERSION}
@setchapternewpage odd

@iftex
@finalout
@end iftex

@c SMALL BOOK version   
@c This edition has been formatted so that you can format and print it in
@c the smallbook format. 
@c @smallbook

@c Set following if you have the new `shorttitlepage' command
@c @clear shorttitlepage-enabled
@c @set shorttitlepage-enabled

@c infoファイル作成のため以下3行を追加(訳者)
@c Following 3 lines are added by naota to make info file.
@ifinfo
@clear shorttitlepage-enabled
@end ifinfo

@c ISPELL CHECK: done, 14 Jan 1993 --bob

@c Check COPYRIGHT dates.  should be updated in the titlepage, ifinfo
@c titlepage; should NOT be changed in the GPL.  --mew

@iftex
@syncodeindex fn cp
@syncodeindex vr cp
@syncodeindex tp cp
@end iftex
@ifinfo
@synindex fn cp
@synindex vr cp
@synindex tp cp
@end ifinfo
@comment %**end of header

@ifinfo
@format
START-INFO-DIR-ENTRY
* bison-ja: (bison-ja). GNU Project parser generator (yacc replacement).
END-INFO-DIR-ENTRY
@end format
@end ifinfo

@ifinfo
このファイルはBison構文解析器生成器の説明文書です。

Copyright (C) 1988, 89, 90, 91, 92, 93, 95, 98, 1999 Free Software Foundation, Inc.

Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.

@ignore
Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).

@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
sections entitled ``GNU General Public License'' and ``Conditions for
Using Bison'' are included exactly as in the original, and provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that the sections entitled ``GNU General Public License'',
``Conditions for Using Bison'' and this permission notice may be
included in translations approved by the Free Software Foundation
instead of in the original English.
@end ifinfo

@ifset shorttitlepage-enabled
@shorttitlepage Bison
@end ifset
@titlepage
@title Bison入門
@subtitle YACC互換構文解析器生成ツール
@subtitle @value{UPDATED}, Bison Version @value{VERSION}

@author by Charles Donnelly and Richard Stallman
@c 日本語訳:石川直太

@page
@vskip 0pt plus 1filll
Copyright @copyright{} 1988, 89, 90, 91, 92, 93, 95, 98, 1999 Free Software
Foundation 

@sp 2
Published by the Free Software Foundation @*
59 Temple Place, Suite 330 @*
Boston, MA  02111-1307  USA @*
Printed copies are available for $15 each.@*
ISBN 1-882114-45-0

Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.

@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).

@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
sections entitled ``GNU General Public License'' and ``Conditions for
Using Bison'' are included exactly as in the original, and provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that the sections entitled ``GNU General Public License'',
``Conditions for Using Bison'' and this permission notice may be
included in translations approved by the Free Software Foundation
instead of in the original English.
@sp 2
Cover art by Etienne Suvasa.
@end titlepage
@page


@node Top, Introduction, (dir), (dir)

@ifinfo
このマニュアルはBison @value{VERSION}の説明文書です。
@end ifinfo

@menu
* Introduction::      
* Conditions::        
* Copying::           GNU一般使用公有許諾書はBisonを複製したり共有したり
                        する方法を示している

チュートリアル部分:
* Concepts::          Bisonを理解するための基本概念.
* Examples::          Bisonの利用を簡単に説明した3つの例.

参照部分:
* Grammar File::      Bisonの宣言と規則を書く.
* Interface::         解析器関数@code{yyparse}へのC言語のインターフェース.
* Algorithm::         Bison解析器が実行時に動作する方法.
* Error Recovery::    エラー回復の規則を書く.
* Context Dependency::  言語構文がBisonが率直に扱うには複雑すぎるときに
                        何をすべきか.
* Debugging::         間違った解析をするBison解析器のデバッグをする.
* Invocation::        (解析器ソースファイルを生成するために)Bisonを実行
                      する方法.
* Table of Symbols::  Bisonの全てのキーワードの説明.
* Glossary::          基本概念の説明.
* Index::             テキストへの相互参照.

 --- The Detailed Node Listing ---

Bisonの概念

* Language and Grammar::  数学の発想と同じ、言語と文脈に依存しない文法.
* Grammar in Bison::  Bisonのために文法を表現する方法.
* Semantic Values::   それぞれのトークンや文法グループは意味値
                        (整数の値、識別子の名前、など。)
                         を取ることができる.
* Semantic Actions::  それぞれの規則はCコードを含んだアクションを持つこ
                        とができる.
* Bison Parser::      Bisonの入力と出力な何で、出力はどのように使われる
                       か。
* Stages::            Bisonの文法を書いて実行させる手順.
* Grammar Layout::    Bison文法ファイルの全体の構造.

例

* RPN Calc::          逆ポーランド記法電卓;
                        演算子の優先順位が無い、最初の例.
* Infix Calc::        中間(代数)記法電卓.
                        演算子の優先順位が導入された.
* Simple Error Recovery::  構文エラーの後も続行する.
* Multi-function Calc::  メモリと三角関数付きの電卓.
                           意味値に複数のデータ型を使用する.
* Exercises::         多機能電卓を改善するための着想.

逆ポーランド記法電卓

* Decls: Rpcalc Decls.  rpcalcのためのBisonとCの宣言.
* Rules: Rpcalc Rules.  rpcalcのための文法規則。説明付き.
* Lexer: Rpcalc Lexer.  字句解析器.
* Main: Rpcalc Main.    制御関数.
* Error: Rpcalc Error.  エラー報告関数.
* Gen: Rpcalc Gen.      文法ファイルでBisonを実行する.
* Comp: Rpcalc Compile. 出力コードにCコンパイラを実行する.

@code{rpcalc}のための文法規則

* Rpcalc Input::      
* Rpcalc Line::       
* Rpcalc Expr::       

多機能電卓:@code{mfcalc}

* Decl: Mfcalc Decl.      多機能電卓のためのBisonの宣言.
* Rules: Mfcalc Rules.    電卓のための文法規則.
* Symtab: Mfcalc Symtab.  記号表を管理するサブルーチン.

Bison文法ファイル

* Grammar Outline::   文法ファイルの概略.
* Symbols::           終端記号と非終端記号.
* Rules::             文法規則の書き方.
* Recursion::         再帰的規則の書き方.
* Semantics::         意味値とアクション.
* Declarations::      全ての種類のBison宣言の説明.
* Multiple Parsers::  一つのプログラムに一つより多くのBison構文解析器を
                        入れる.

Bison文法の概要

* C Declarations::    C宣言部の構文と使用法.
* Bison Declarations::  Bison宣言部の構文と使用法.
* Grammar Rules::     文法規則部の構文と使用法.
* C Code::            追加のCコード部の構文と使用法.

言語の意味の定義

* Value Type::        全ての意味値に一つのデータ型を指定する.
* Multiple Types::    複数の別のデータ型を指定する.
* Actions::           アクションは文法規則の意味的定義.
* Action Types::      アクションが操作するデータ型を指定する.
* Mid-Rule Actions::  ほとんどのアクションは規則の最後に行く.
                      これは規則の最中で、いつ、なぜ、どのように
                        例外アクションを使用するかを指示する.

Bison宣言

* Token Decl::        終端記号を宣言する.
* Precedence Decl::   優先順位と結合規則とともに終端を宣言する.
* Union Decl::        全ての意味値の型の集合を宣言する.
* Type Decl::         非終端記号のための型の選択を宣言する.
* Expect Decl::       シフト/還元衝突の警告を抑制する.
* Start Decl::        開始記号を指定する.
* Pure Decl::         再入構文解析器を要求する.
* Decl Summary::      全てのBison宣言の表.

構文解析器のC言語インターフェイス

* Parser Function::   @code{yyparse}の呼び方と、それが返すもの.
* Lexical::           トークンを読み込む関数@code{yylex}を提供しなければ
                        ならない.
* Error Reporting::   関数@code{yyerror}を提供しなければならない.
* Action Features::   アクションで使える特別な機能.

字句解析器関数@code{yylex}

* Calling Convention::  @code{yyparse}が@code{yylex}を呼ぶ方法.
* Token Values::      @code{yylex}がどのように読み込んだトークンの
                        意味値を返さなければならないか.
* Token Positions::   アクションが望むときに、どのように@code{yylex}が
                        テキストの位置(行数など)を返さなければならない
                        か。
* Pure Calling::      純粋な構文解析器で呼び出し型の習慣がどのように
                        違うか (@pxref{Pure Decl, ,A Pure (Reentrant) Parser}).

Bison構文解析器のアルゴリズム

* Look-Ahead::        構文解析器は何をするかを決めるときに一つ先のトーク
                        ンを見る.
* Shift/Reduce::      衝突: シフトと還元の両方が有効なとき.
* Precedence::        演算子の優先順位は衝突を解決することで動作する.
* Contextual Precedence::  演算子の優先順位が文脈に依存するとき.
* Parser States::     構文解析器はスタック付きの有限状態機械.
* Reduce/Reduce::     同じ状況に2つの規則が適用可能なとき.
* Mystery Conflicts::  正しくないように見える還元/還元衝突.
* Stack Overflow::    スタックが一杯になったときに何が起こるうか. それを
                        避ける方法.

演算子の優先順位

* Why Precedence::    優先順位が必要なことを示す例.
* Using Precedence::  Bison文法で優先順位を指定する方法.
* Precedence Examples::  前の例でこれらの機能が使われた方法.
* How Precedence::    どのように動作するか.

文脈依存性の処理

* Semantic Tokens::   トークン構文解析は意味的文脈に依存する.
* Lexical Tie-ins::   トークン構文解析は構文的文脈に依存する.
* Tie-in Recovery::   字句結び付きはエラー回復規則を書く方法に影響する.

Bisonの実行

* Bison Options::     全てのオプションが詳しく、短いオプションでアルファ
                        ベット順に説明されている.
* Option Cross Key::  長いオプションのアルファッベット順のリスト.
* VMS Invocation::    VMSでのBisonのコマンド構文.
@end menu

@node Introduction, Conditions, Top, Top
@unnumbered まえがき
@cindex introduction
@cindex まえがき

Bisonは、LALR(1)文脈自由文法の文法定義を、
その文法を解析するためのCで書かれたプログラムに変換する、
汎用の構文解析器生成ツールです。
あなたがBisonに熟練すれば、
簡単な電卓から複雑なプログラミング言語まで、
広い範囲の言語解析器を開発できるようになるでしょう。

BisonはYaccの上位互換です。
正しく書かれたすべてのYacc文法を、変更なくBisonで処理できます。
Yaccに親しんでいるすべての人は、ちょっと考えるだけで、
Bisonを使えるようになるでしょう。
Bisonを使い、本書を理解するためには、
C言語に精通している必要があります。

1章と2章は入門の章です。1章では、Bisonを使うための基本的な概念を説明し、
2章では3つの具体例を示します。
BisonやYaccを知らない方は、
1章から読みはじめてください。
3章以降では、Bisonの仕様を詳細に解説します。

Bisonは、最初にRobert Corbettによって開発され、
Richard StallmanがYacc互換にしました。
カーネギーメロン大学のWilfred Hansenが、
文字列リテラル@footnote{【訳注】2文字以上の文字列、たとえば@samp{==}を、
トークン名に使う機能。}といくつかの機能を追加しました。

本書は、Bisonのバージョン@value{VERSION}に基づいています。

@unnumberedsec 日本語訳にあたって

本書は、株式会社アスキーの
支援を受けて、慶應義塾の石川直太
(@samp{naota@@sfc.keio.ac.jp、http://www.sfc.keio.ac.jp/~naota/})
が翻訳しました。

なお、「GNU一般公有使用許諾書」の日本語訳については、
引地さんのところの日本語訳を使わせていただいたことを
ここに記して感謝いたします。

日本語訳したtexinfoファイルは、
@samp{http://www.ascii.co.jp/pub/GNU/bison-1.25-man-jp.tgz}
にあります。コマンドtexi2dviなどでdviファイルを生成したり、GNU Emacsで
infoファイルへ変換したりできます。

バージョン1.25 からバージョン@value{VERSION}の変更はgnujdocプロジェクトの
一環として林芳樹 (@email{t90553@@mail.ecc.u-tokyo.ac.jp}) が
行いました。

gnujdoc の詳細は、
@uref{http://duff.kuicr.kyoto-u.ac.jp/%7Eokuji/gnujdoc/}
を参照してください。

@node Conditions, Copying, Introduction, Top
@unnumbered Bisonの利用条件

Bisonバージョン1.24において、フリーでないプログラムへのBisonの出力の
利用を許可するために、@code{yyparse}の配布条件を変えました。
それまでは、Bisonによって生成された構文解析器は、
フリーソフトウェアのプログラム中でのみ、利用可能でした。

GNU Cコンパイラなど他のGNUプログランミングツールには、
このような制限がありません。
それらは、いつでも、フリーでないソフトウェアの開発に利用できます。
Bisonの利用条件が異なっていた理由は、特別な政治的判断によるものではありません。
BisonのすべてのソースコードにGPLを適用した結果です。

Bisonの出力であるBison構文解析器ファイルには、
@code{yyparse}関数のためのコードである、
かなりの量のBisonのソースコードの一部分が、そのまま含まれます
(あなたが定義した文法によるアクションは、
この関数の1か所に挿入されるだけで、残りの関数は変わりません)。
われわれFSFが@code{yyparse}のコードにGPLを適用した結果、
Bisonの出力をフリーソフトウェアのみに利用するという制約ができたのです。

ソフトウェアを専売しようとする人々への思いやりによって、
われわれが条件を変えることはありませんでした。
@strong{ソフトウェアはフリーであるべきです。}
しかし、われわれは、Bisonの利用をフリーソフトウェアに限定したことは、
他のソフトウェアをフリーにしようとする人々を勇気づけるために、
少なからず役立っただろうと、結論を下しました。
そこで、われわれは、その他のGNUツールの現実的な利用条件に合わせて、
Bisonの現実的な利用条件を決定することにしました。


@node Copying, Concepts, Conditions, Top
@unnumbered GNU GENERAL PUBLIC LICENSE
@center Version 2, June 1991

@display
Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@end display

@unnumberedsec Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software---to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.)  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

  The precise terms and conditions for copying, distribution and
modification follow.

@iftex
@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end iftex
@ifinfo
@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end ifinfo

@enumerate 0
@item
This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The ``Program'', below,
refers to any such program or work, and a ``work based on the Program''
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term ``modification''.)  Each licensee is addressed as ``you''.

Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.

@item
You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.

You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.

@item
You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

@enumerate a
@item
You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.

@item
You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.

@item
If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License.  (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
@end enumerate

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.

In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

@item
You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:

@enumerate a
@item
Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,

@item
Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,

@item
Accompany it with the information you received as to the offer
to distribute corresponding source code.  (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
@end enumerate

The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.

If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.

@item
You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.

@item
You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

@item
Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

@item
If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

@item
If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

@item
The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and ``any
later version'', you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

@item
If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

@iftex
@heading NO WARRANTY
@end iftex
@ifinfo
@center NO WARRANTY
@end ifinfo

@item
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW@.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE@.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU@.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

@item
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
@end enumerate

@iftex
@heading END OF TERMS AND CONDITIONS
@end iftex
@ifinfo
@center END OF TERMS AND CONDITIONS
@end ifinfo

@page
@unnumberedsec How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the ``copyright'' line and a pointer to where the full notice is found.

@smallexample
@var{one line to give the program's name and an idea of what it does.}
Copyright (C) 19@var{yy}  @var{name of author}

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE@.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
@end smallexample

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:

@smallexample
Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
type `show w'.  This is free software, and you are welcome
to redistribute it under certain conditions; type `show c' 
for details.
@end smallexample

The hypothetical commands @samp{show w} and @samp{show c} should show
the appropriate parts of the General Public License.  Of course, the
commands you use may be called something other than @samp{show w} and
@samp{show c}; they could even be mouse-clicks or menu items---whatever
suits your program.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a ``copyright disclaimer'' for the program, if
necessary.  Here is a sample; alter the names:

@smallexample
@group
Yoyodyne, Inc., hereby disclaims all copyright
interest in the program `Gnomovision'
(which makes passes at compilers) written 
by James Hacker.

@var{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
@end group
@end smallexample

This General Public License does not permit incorporating your program into
proprietary programs.  If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library.  If this is what you want to do, use the GNU Library General
Public License instead of this License.


@node Concepts, Examples, Copying, Top
@chapter Bisonの概念

この章では、Bisonの詳細を理解するのに欠くことのできない、
多くの基礎概念を説明します。
まだBisonやyaccの使い方を知らない方は、
この章を注意深く読むことから始めてください。

@menu
* Language and Grammar::  数学の発想と同じ、言語と文脈に依存しない文法.
* Grammar in Bison::  Bisonのために文法を表現する方法.
* Semantic Values::   それぞれのトークンや文法グループは意味値
                        (整数の値、識別子の名前、など。)
                         を取ることができる.
* Semantic Actions::  それぞれの規則はCコードを含んだアクションを持つこ
                        とができる.
* Bison Parser::      Bisonの入力と出力な何で、出力はどのように使われる
                       か。
* Stages::            Bisonの文法を書いて実行させる手順.
* Grammar Layout::    Bison文法ファイルの全体の構造.
@end menu


@node Language and Grammar, Grammar in Bison,  , Concepts
@section 言語と文脈自由文法

@cindex context-free grammar
@cindex grammar, context-free
@cindex 文脈自由文法
@cindex 文法

Bisonが言語を解析するためには、その言語が
@dfn{文脈自由文法(context-free grammar)}で記述されている必要があります。
すなわち、1個以上の@dfn{文法グループ(syntactic groupings)}を定め、
その文法グループを部品から組み立てる規則を与える必要があります。
たとえば、C言語では、ある種のグループは「式」と呼ばれます。
式を作る規則の1つは、
「1つの式とは、別の式にマイナス記号を付けたものでもよい」かもしれません。
別の規則は、「1つの式とは、整数でもよい」かもしれません。
ここから解るように、規則はしばしば再帰的になりますが、
再帰を始めるための少なくとも1個の規則が必要です。

@cindex BNF
@cindex Backus-Naur form
@cindex バッカス-ナウア記法

このような規則を人間が読めるように表現する、もっとも一般的な形式的な方法は、
@dfn{バッカス-ナウア記法(Backus-Naur form)}略して``BNF''です。
これは、Algol 60言語を定義するために開発されました。
BNFで表現された任意の言語は、文脈自由言語です。
Bisonへの入力は、本質的には、機械可読なBNFです。

すべての文脈自由言語をBisonで扱えるわけではありません。
LALR(1)だけを扱えます。
簡単に説明すると、ちょうど1個のトークンを先読みすることによって、
入力文字列の任意の部分を解析できる必要があるということです。
厳密に説明すると、これはLR(1)文法の説明で、
LALR(1)には簡単に説明できない追加の制限があります。
しかし、LALR(1)になれないLR(1)文法は、現実にはまれです。
より詳しい説明は
@xref{Mystery Conflicts, , Mysterious Reduce/Reduce Conflicts}。

@cindex symbols (abstract)
@cindex token
@cindex syntactic grouping
@cindex grouping, syntactic
@cindex シンボル
@cindex 記号
@cindex 終端記号
@cindex 非終端記号
@cindex トークン
@cindex 文法グループ
@cindex グループ

ある言語についての形式文法的な規則では、
文法的な単位またはグループを@dfn{記号(symbol)}と呼びます。
文法規則に従って小さい部分から組み立てられた記号を
@dfn{非終端記号(nonterminal symbol)}といい、
@dfn{終端記号(terminal symbol)}または@dfn{トークン型(token type)}と呼ばれる
ものに分解できます。
本書では、1個の終端記号に対応する入力の一部分を@dfn{トークン(token)}、
1個の非終端記号に対応する入力の一部分を@dfn{グループ(grouping)}と呼びます。

何が終端記号で何が非終端記号かを示すために、
例としてC言語を使います。
Cのトークンは、識別子、定数(数値または文字列)、さまざまな予約語、
算術演算子、区切り記号です。
C言語の終端記号には、「識別子」、「数値」、「文字列」、そして、
予約語、演算子、区切り記号のそれぞれに対する記号、
すなわち、「if」、「return」、「const」、「static」、「int」、「char」、
「プラス記号」、「開きブレース」、「閉じブレース」、「カンマ」、
などが含まれます
(これらのトークンは文字に分解できますが、
それは文法の問題ではなく、字句解析の問題です)。

次の例は、トークンに分解されたCの関数です。

@example
int             /* @r{予約語 `int'} */
square (x)      /* @r{識別子, 開きかっこ,} */
                /* @r{識別子, 閉じかっこ} */
     int x;     /* @r{予約語 `int', 識別子, セミコロン} */
@{               /* @r{開きブレース} */
  return x * x; /* @r{予約語 `return', 識別子,} */
                /* @r{アスタリスク, 識別子, セミコロン} */
@}               /* @r{閉じブレース} */
@end example

Cの文法的なグループには、式、文、宣言、関数定義が含まれます。
これらは、Cの文法で、非終端記号、「式」、「文」、「宣言」、
「関数定義」として表されます。
完全な文法では、上記の4つの意味を表現するために、
それぞれの非終端記号について、数十個の追加の言語構築が必要です。
上記の例で、関数定義は、宣言と文を含みます。
文の中で、それぞれの@samp{x}は式であり、
@samp{x * x}も式です。

それぞれの非終端記号には、それがより単純な構成要素からどのように作られるか
示すために、文法規則が必要です。
たとえば、Cの文の1つである@code{return}文について、
文法規則を形式ばらずに書くと、次のようになります。

@quotation
「文」は、キーワード「@code{return}」、「式」、「セミコロン」から
作ることができる。
@end quotation

@noindent
Cの各種の文について、「文」には多くの他の規則があるでしょう。

@cindex start symbol
@cindex 開始記号
1つの非終端記号が、言語の全体を表現するように、
特別なものとして識別される必要があります。
これを@dfn{開始記号(start symbol)}と呼びます。
コンパイラでは、これは完全な入力プログラムを意味します。
C言語では、非終端記号「定義と宣言の並び」が、この働きをします。

たとえば、@samp{1 + 2}は有効なCの式で、
Cのプログラムの有効な一部分ですが、
Cプログラム@emph{全体}としては無効です。
したがって、Cの文脈自由文法では、「式」は開始記号でないとわかります。

Bison構文解析器は、入力としてトークンの列を読み、
文法規則を使ってトークンをグループにします。
もし入力が有効であれば、最終的な結果として、トークンの列全体が
文法の開始記号である1つのグループの記号に還元されます。
もしわれわれがCの文法を使うならば、入力全体は
「定義と宣言の列」の必要があります。
もしそうでなければ、構文解析器が文法エラーを報告します。


@node Grammar in Bison, Semantic Values, Language and Grammar, Concepts
@section 形式規則からBisonの入力へ
@cindex Bison grammar
@cindex Bison 文法
@cindex grammar, Bison
@cindex formal grammar
@cindex 形式文法

形式文法(formal grammer)は、数学的な構成です。
Bisonのために言語を定義するためには、Bisonの書式で文法を記述した
@dfn{Bison文法(Bison grammer)}ファイルを書く必要があります。
@xref{Grammar File, ,Bison Grammar Files}。

形式文法の中での1つの非終端記号は、Bisonの入力の中で、
Cの識別子のような、1つの識別子として表現されます。
@code{expr}、@code{stmt}、@code{declaration}のように、
通常、非終端記号は小文字で書きます。

終端記号に対するBisonの表現は、
@dfn{トークン型(token type)}ともいいます。
トークン型は、C言語で使われるような識別子であるかもしれません。
通常、非終端記号からこれらを区別するために、大文字で書きます。
たとえば、@code{INTEGER}、@code{IDENTIFIER}、@code{IF}、@code{RETURN}
のように書きます。
言語の個々のキーワードを表す終端記号は、
キーワードを大文字に変換してから命名するべきです。
@cindex error
終端記号@code{error}は、エラーからの回復処理のために予約されています。
@xref{Symbols}。

ある終端記号は、C言語の文字定数のような、1文字リテラルを表している
かもしれません。
トークンがちょうど1文字である(たとえば、かっこ、プラス記号など)ならば必ず、
そのトークンに対する終端記号として、同じ文字を使うべきです。

終端記号を表す第3の方法は、何文字かを含むC言語の文字列定数です。
詳細は@xref{Symbols}。

文法規則は、Bisonの文法の中で、もう1つの式を持ちます。
たとえば、C言語の@code{return}文に対するBisonの規則があります。
クォート(')で囲まれたセミコロンは、文に対するC言語の文法の一部分を表す、
1文字のリテラルトークンです。
クォートで囲まれていないセミコロンとコロンは、
あらゆる規則の中で使われる、Bisonの区切り文字です。

@example
stmt:   RETURN expr ';'
        ;
@end example

@noindent
@xref{Rules, ,Syntax of Grammar Rules}。


@node Semantic Values, Semantic Actions, Grammar in Bison, Concepts
@section 意味値
@cindex semantic value
@cindex value, semantic
@cindex 意味値
@cindex 値

形式文法は、トークンを分類法に基づいてのみ、選びます。
たとえば、ある規則が`integer constant'という終端記号について言及するならば、
それは、文法的にそこに現れてよい@emph{任意の}整数型定数を意味します。
その定数の正確な値は、入力が解析される方法と無関係です。
もし、@samp{x+4}が文法的に正しいならば、@samp{x+1}も、@samp{x+3989}も、
同様に文法的に正しいのです。

しかし、いったん解析されれば、入力にとって正確な値はきわめて重要です。
プログラム中の定数として4と1と3989を区別できないコンパイラは、
役に立ちません。
そこで、Bison文法の中のそれぞれのトークンは、トークン型のほかに、
@dfn{意味値(semantic value)}を持ちます。詳細については、
@xref{Semantics, ,Defining Language Semantics}。

トークン型は、@code{INTEGER}、@code{IDENTIFIER}、@code{','}のように、
文法の中で定義される終端記号です。
これは、そのトークンが正しい位置に現れているか確かめ、
他のトークンとどのようにグループ化するか決めるために必要な、
すべての情報を含んでいます。
文法規則は、トークンの型以外の何も知りません。

意味値は、トークンに関する、たとえば、整数の値や識別子の名前のような、
トークン型以外のあらゆる情報を持っています
(@code{','}のような区切り記号であるトークンは、
意味値を持つ必要がありません)。

たとえば、ある入力されたトークンは、トークン型が@code{INTEGER}で、
意味値が4であると分類されるかもしれません。
別の入力されたトークンは、同じ@code{INTEGER}型で、
値が3989であるかもしれません。
文法規則が@code{INTEGER}の出現を許すのならば、
どちらのトークンも@code{INTEGER}型なので、受け入れられます。
構文解析器は、トークンを受け入れるときに、その意味値を記憶します。

それぞれのグループ化は、それに対応する非終端記号とともに、意味値を持てます。
たとえば、電卓の中では、1つの式は、通常、数値である意味値を持ちます。
プログラミング言語のコンパイラの中では、1つの式は、通常、
式の意味を表す木構造の意味値を持ちます。


@node Semantic Actions, Bison Parser, Semantic Values, Concepts
@section 意味アクション
@cindex semantic actions
@cindex actions, semantic
@cindex 意味アクション
@cindex アクション

役に立つようにするためには、プログラムは、入力を解析するだけでなく、
入力に基づくなんらかの出力を生成する必要があります。
Bison文法の中では、文法規則は、
Cで書かれた@dfn{アクション(action)}を持てます。
そのルールへのマッチを構文解析器が認識するたびに、アクションが実行されます。
@xref{Actions}

多くの場合に、アクションの目的は、部品の意味値から全体の意味値を
計算することです。
たとえば、1つの式とは2つの式の和でありうると仮定します。
構文解析器が和を認識すると、
部分式それぞれは、それがどのように構成されたかを表す意味値を持っています。
アクションは、新しく認識された合成式について、
同様の意味値を構成するべきです。

以下に、1つの式が2つの部分式の和となる規則の例を示します。

@example
expr: expr '+' expr   @{ $$ = $1 + $3; @}
        ;
@end example

このアクションは、2個の部分式の値から、
式の和の意味値を生成する方法を示しています。


@node Bison Parser, Stages, Semantic Actions, Concepts
@section Bisonの出力――構文解析器ファイル
@cindex Bison parser
@cindex Bison utility
@cindex lexical analyzer, purpose
@cindex parser
@cindex Bison構文解析器
@cindex Bisonユーティリティ
@cindex 字句解析器
@cindex 構文解析器

Bisonを使うときには、入力としてBison文法ファイルを指定します。
文法で記述された言語を解析する、Cのソースファイルが出力になります。
このファイルを@dfn{Bison構文解析器(Bison parser)}と呼びます。
BisonユーティリティとBison構文解析器は、
別のプログラムであることに注意してください。
Bisonユーティリティの出力がBison構文解析器で、
あなたのプログラムの一部分になるのです。

Bison構文解析器の仕事は、文法規則に従って、トークンをグループ化することです。
たとえば、識別子と演算子から式を組み立てます。
このために、文法規則に対応するアクションを実行します。

トークンは、@dfn{字句解析器(lexical analyzer)}と呼ばれる関数によって得られ、
その関数を(Cで書くような)なんらかの方法で与える必要があります。
Bison構文解析器は、新しいトークンを必要とするたびに、
字句解析器を呼び出します。
Bison構文解析器は、トークンの「内部」がなんであるか知りません
(しかし、トークンの意味値は関係します)。
一般に、字句解析器は、テキスト中の文字を解析してトークンを得ますが、
Bisonはその方法を知りません。
@xref{Lexical, ,The Lexical Analyzer Function @code{yylex}}。

Bison構文解析器ファイルは、Cのプログラムで、@code{yyparse}という名前の、
文法を実装する関数を定義します。
この関数は、完全なCのプログラムを構成しません。
いくつかの関数を補ってやる必要があります。
1つは、字句解析器です。
もう1つは、エラーを報告するために構文解析器が呼び出す、
エラー報告関数です。
さらに、完全なCプログラムは@code{main}関数から実行を始める必要がありますので、
これを補って、そこから@code{yyparse}を呼び出してください。
@xref{Interface, ,Parser C-Language Interface}。

あなたが書くアクションの中でのトークンの型名と記号に関係なく、
Bison構文解析器の中で使われるすべての変数と関数の名前は、
@samp{yy}または@samp{YY}で始まります。
これは、字句解析関数@code{yylex}とエラー報告関数@code{yyerror}および
構文解析関数@code{yyparse}のようなインターフェイス関数も含みます。
また、内部で使われる多数の識別子も同様です。
したがって、本書で定義されている場合を除いて、
Bison文法ファイルの中で@samp{yy}または@samp{YY}で始まる
Cの識別子の利用は避けるべきです。


@node Stages, Grammar Layout, Bison Parser, Concepts
@section Bisonを使う手順
@cindex stages in using Bison
@cindex using Bison
@cindex 使用方法
@cindex Bisonの使用方法

Bisonを使って、文法の定義から実際に動くコンパイラやインタープリタを作るまでの、
言語設計手順は、次のようになります。

@enumerate
@item
Bisonが認識できる形式で、文法を形式的に指定します
(@pxref{Grammar File, ,Bison Grammar Files})。
言語の各文法規則に対して、
その規則のインスタンスが認識されたときに実行される
アクションを記述します。
アクションは、C言語の文の並びで書きます。

@item
入力を処理し、トークンを構文解析器に渡すために、字句解析器を書きます。
字句解析器は、Cで手作業で書いてもかまいません
(@pxref{Lexical, ,The Lexical Analyzer Function @code{yylex}})。
Lexを使って生成することも可能ですが、本書ではLexの使い方については解説
していません。

@item
Bisonが生成した構文解析器を呼び出す、制御関数を書きます。

@item
エラー報告関数を書きます。

@end enumerate

このソースプログラムを実行可能なプログラムにするために、
次の手順が必要です。

@enumerate
@item
構文解析器を生成するために、Bisonを実行します。

@item
Bisonが生成したソースプログラムとその他のソースプログラムを、
コンパイルします。

@item
オブジェクトファイルをリンクして、最終的なプログラムを得ます。

@end enumerate


@node Grammar Layout,  , Stages, Concepts
@section Bison文法の全体像
@cindex grammar file
@cindex file format
@cindex format of grammar file
@cindex layout of Bison grammar
@cindex 文法ファイル
@cindex ファイル書式

Bisonユーティリティへの入力は、
@dfn{Bison文法ファイル(Bison grammar file)}です。
Bison文法ファイルの一般的な書式は、次のとおりです。

@example
%@{
@var{C宣言部(C declarations)}
%@}

@var{Bison宣言部(Bison declarations)}

%%
@var{文法規則部(Grammar rules)}
%%
@var{追加のCプログラム部(Additional C code)}
@end example

Bison文法ファイル中の@samp{%%}、@samp{%@{}、@samp{%@}}は、
ファイルを節に分ける区切り記号です。

@dfn{C宣言部}では、
アクションの中で使われる型と変数を定義できます。
マクロを定義するためのプリプロセッサディレクティブや、
ヘッダファイルをインクルードするための@code{#include}命令も使用できます。

@dfn{Bison宣言部}には、終端記号、非終端記号、さらに、
演算子の優先順位、さまざまな記号の意味値のデータ型を記述できます。

@dfn{文法規則部}では、各非終端記号をその部品から組み立てる方法を
定義します。

@dfn{追加のCプログラム部}には、
あなたが望むCプログラムを記述できます。
よく字句解析関数@code{yylex}や
文法規則の中のアクションから呼ばれる関数をここに書きます。
単純なプログラムでは、@footnote{【訳注】他のファイルに書くのではなく}ここに
残りのプログラム全部を書きます。


@node Examples, Grammar File, Concepts, Top
@chapter 例
@cindex simple examples
@cindex examples, simple
@cindex 単純な例
@cindex 例

本章では、Bison文法を使って書いた例を3つ示します。
逆ポーランド記法電卓、算術(中置)記法電卓、多機能電卓です。
すべてBSD UNIX 4.3上でテストしました。
限定的ではありますが、対話的な電卓として利用可能です。

これらの例は単純ですが、現実のプログラミング言語に対する
Bison文法も、書き方は同じです。

@ifinfo
これらの例をInfoファイルから取り出してソースファイルにコピーし、
試すことができます。
@end ifinfo

@menu
* RPN Calc::          逆ポーランド記法電卓;
                        演算子の優先順位が無い、最初の例.
* Infix Calc::        中間(代数)記法電卓.
                        演算子の優先順位が導入された.
* Simple Error Recovery::  構文エラーの後も続行する.
* Multi-function Calc::  メモリと三角関数付きの電卓.
                           意味値に複数のデータ型を使用する.
* Exercises::         多機能電卓を改善するための着想.
@end menu


@node RPN Calc, Infix Calc,  , Examples
@section 逆ポーランド記法電卓
@cindex reverse polish notation
@cindex polish notation calculator
@cindex rpcalc
@cindex calculator, simple
@cindex 逆ポーランド記法
@cindex 電卓

最初の例は、@dfn{逆ポーランド記法(reverse polish notation)}を使う
倍精度の電卓で、演算子を後に書きます。
この例は、演算子の優先順位の問題がないので、入門には適しています。
第2の例では、演算子の優先順位をどのように扱うかを示します。

この電卓のソースファイルを@file{rpcalc.y}とします。
Bisonの入力ファイルには、通常@samp{.y}という拡張子を付けます。

@menu
* Decls: Rpcalc Decls.  rpcalcのためのBisonとCの宣言.
* Rules: Rpcalc Rules.  rpcalcのための文法規則。説明付き.
* Lexer: Rpcalc Lexer.  字句解析器.
* Main: Rpcalc Main.    制御関数.
* Error: Rpcalc Error.  エラー報告関数.
* Gen: Rpcalc Gen.      文法ファイルでBisonを実行する.
* Comp: Rpcalc Compile. 出力コードにCコンパイラを実行する.
@end menu


@node Rpcalc Decls, Rpcalc Rules,  , RPN Calc
@subsection @code{rpcalc}のための宣言

逆ポーランド記法電卓のためのCとBisonの宣言を示します。
Cと同様に@samp{/*@dots{}*/}はコメントです。

@example
/* 逆ポーランド記法電卓 */

%@{
#define YYSTYPE double
#include <math.h>
%@}

%token NUM

%% /* 文法規則とアクションが続く */
@end example

C宣言部(@pxref{C Declarations, ,The C Declarations Section})には、
2つのプリプロセッサディレクティブがあります。

@code{#define}ディレクティブで、トークンとグループの意味値に対する
Cのデータ型を指定するために、マクロ@code{YYSTYPE}を定義します
(@pxref{Value Type, ,Data Types of Semantic Values})。
Bison構文解析器は、@code{YYSTYPE}に定義された型を使います。
定義しないと、@code{int}型が使用されます。
各トークンと式は、浮動小数点数である記録値を持つので、
ここでは@code{double}を指定します。

べき乗関数@code{pow}の宣言を使うために、
@code{#include}ディレクティブを使っています。

第2の部、Bison宣言は、Bisonのためにトークン型についての情報を用意します
(@pxref{Bison Declarations, ,The Bison Declarations Section})。
1文字リテラルでない終端記号は、ここで宣言する必要があります
(通常、1文字のリテラルを宣言する必要はありません)。
この例では、すべての算術演算子が1文字リテラルなので、
数値定数に対するトークン型@code{NUM}だけを、
終端記号として宣言します。


@node Rpcalc Rules, Rpcalc Lexer, Rpcalc Decls, RPN Calc
@subsection @code{rpcalc}のための文法規則

逆ポーランド記法電卓のための文法規則を示します。

@example
input:    /* 空 */
        | input line
;

line:     '\n'
        | exp '\n'  @{ printf ("\t%.10g\n", $1); @}
;

exp:      NUM             @{ $$ = $1;         @}
        | exp exp '+'     @{ $$ = $1 + $2;    @}
        | exp exp '-'     @{ $$ = $1 - $2;    @}
        | exp exp '*'     @{ $$ = $1 * $2;    @}
        | exp exp '/'     @{ $$ = $1 / $2;    @}
      /* べき乗関数 */
        | exp exp '^'     @{ $$ = pow ($1, $2); @}
      /* 単項のマイナス    */
        | exp 'n'         @{ $$ = -$1;        @}
;
%%
@end example

ここで定義されるrpcalc「言語」のグループは、
式(@code{exp})と、入力行(@code{line})と、
完全な入力の写し(@code{input})です。
これらの非終端記号には、「論理和」という@samp{|}記号で区切られた、
いくつかの規則があります。
以下の項で、これらの規則の意味を説明します。

言語の意味は、グループが認識されたときのアクションによって決まります。
アクションとは、ブレースで囲まれたCのプログラムです。
@xref{Actions}。

これらのアクションをCで書く必要がありますが、
Bisonには規則の間で意味値を受け渡しする方法があります。
それぞれのアクションで、擬似変数@code{$$}は、
その規則が構成しようとしているグループの意味値を示します。
@code{$$}に値を代入することが、アクションの主な仕事です。
規則の部品の意味値は、@code{$1}、@code{$2}などの
名前で参照されます。

@menu
* Rpcalc Input::      
* Rpcalc Line::       
* Rpcalc Expr::       
@end menu


@node Rpcalc Input, Rpcalc Line,  , Rpcalc Rules
@subsubsection @code{input}の説明

@code{input}の定義について考えます。

@example
input:    /* 空 */
        | input line
;
@end example

この定義の意味は、「完全な入力とは、空文字列であるか、あるいは、
完全な入力に入力行が続いたものである」ということです。
「完全な入力」が、それ自身を使って定義されていることに注意してください。
列の中で@code{input}が常に左端の記号なので、
このような定義を@dfn{左再帰(left recursive)}と呼びます。
@xref{Recursion, ,Recursive Rules}。

最初の選択肢は、@samp{:}と@samp{|}の間に記号がないので空です。
これは、(トークンを含まない)空の入力文字列にマッチします。
電卓を起動した直後に@kbd{Ctrl-d} @footnote{【訳注】UNIXの標準的なコンソールの
設定で、入力の終わりを示す制御文字で、MS-DOSでは代わりに@kbd{Ctrl-z}。}を
押しても、正しい入力と扱われるように、この規則を入れました。
通常、空に対応する選択肢を最初に置き、そこに@samp{/* 空 */}と
書きます。

2つめの選択肢である規則(@code{input line})は、
自明(空)でないすべての入力を扱います。
その意味は、「任意の数の行を読み込んだ後で、もし可能ならば、
もう1行読み込む」ということです。
左再帰が、この規則を繰り返しにします。
最初の選択肢が空の入力にマッチするので、
0回以上任意の回数の繰り返しになります。

構文解析器関数@code{yyparse}は、文法エラーが発生するか、あるいは、
字句解析器がもうトークンがないと判定するまで、
入力の処理を続けます。
ファイルの終わりで起きることについては、後で考慮します。


@node Rpcalc Line, Rpcalc Expr, Rpcalc Input, Rpcalc Rules
@subsubsection @code{line}の説明

次に、@code{line}の定義について考えます。

@example
line:     '\n'
        | exp '\n'  @{ printf ("\t%.10g\n", $1); @}
;
@end example

最初の選択肢は、改行文字であるトークンです。
これは、rpcalcが空行を受け入れ、それに対応するアクションがないので、
無視することを示します。
第2の選択肢は、式の後に改行が続いたものです。
これが、rpcalcを有用にする選択肢です。
問い合わせの中の@code{exp}が、この選択肢に現れる最初の記号なので、
@code{exp}グループの意味値は、@code{$1}の値です。
アクションは、問い合わされた計算の結果である、
この値を表示します。

このアクションは、値を@code{$$}に代入しないので、例外的です。
したがって、@code{line}に対応する意味値は、初期化されず、
その値は予想できなくなります。
もし、その値が使われると、この仕様はバグになりますが、われわれはこの値を使い
ません。ユーザーが入力した行に対する値を表示したら、
その値はもはや必要ありません。


@node Rpcalc Expr,  , Rpcalc Line, Rpcalc Rules
@subsubsection @code{expr}の説明

@code{exp}グループは、いくつかの規則を持ち、
それぞれが式の種類に対応しています。
最初の規則は、数値そのものであるもっとも単純な式を処理します。
第2の規則は、2個の式に加算記号が続くような、加算式を処理します。
第3の規則は、減算式を処理する、といった具合です。

@example
exp:      NUM
        | exp exp '+'     @{ $$ = $1 + $2;    @}
        | exp exp '-'     @{ $$ = $1 - $2;    @}
        @dots{}
        ;
@end example

すべての@code{exp}規則をまとめるために@samp{|}を使っていますが、
次のように別々に書くことも可能です。

@example
exp:      NUM ;
exp:      exp exp '+'     @{ $$ = $1 + $2;    @} ;
exp:      exp exp '-'     @{ $$ = $1 - $2;    @} ;
        @dots{}
@end example

規則のほとんどは、式の部品の値から式の値を計算するための、
アクションを持っています。
たとえば、加算のための規則では、@code{$1}は式の第1の部品を、
@code{$2}は式の第2の部品を表します。
第3の部品@code{'+'}は、意味値には関連する情報を持ちませんが、
もし値を持っていれば、@code{$3}として参照できます。
@code{yyparse}がこの規則を使って加算式を認識すると、
式全体の値として、2個の部分式の値の和が生成されます。
@xref{Actions}。

すべての規則に対してアクションを書く必要はありません。
アクションを省略すると、Bisonは@code{$1}の値を@code{$$}に複写します。
第1の規則では、@code{NUM}の値をそのまま複写するために、
このようになっています。

ここで示したリストは、望ましい書式ですが、
Bisonがこのように要求するわけではありません。
必要に応じて、空白、タブ、改行を置けます。
次のような書き方も可能です。

@example
exp   : NUM | exp exp '+' @{$$ = $1 + $2; @} | @dots{}
@end example

これは、次のリストと等価です。

@example
exp:      NUM
        | exp exp '+'    @{ $$ = $1 + $2; @}
        | @dots{}
@end example

しかし、後者のほうが可読性が優れています。


@node Rpcalc Lexer, Rpcalc Main, Rpcalc Rules, RPN Calc
@subsection @code{rpcalc}字句解析器
@cindex writing a lexical analyzer
@cindex lexical analyzer, writing
@cindex 字句解析器

字句解析器の仕事は、低水準の構文解析で、文字または文字列を
トークンに変換します。
Bison構文解析器は、字句解析器を呼び出してトークンを得ます。
@xref{Lexical, ,The Lexical Analyzer Function @code{yylex}}。

RPN(逆ポーランド記法)電卓には、簡単な字句解析器のみが必要です。
この字句解析器は、空白とタブを読み飛ばし、
数値を読み込んで@code{double}型の@code{NUM}トークンとして返します。
数値の一部分ではないその他の文字は、独立のトークンです。
1文字トークンのトークン符号はその文字自身であることに注意してください。

字句解析関数の戻り値は、トークン型を表す数値です。
Bison規則の中でトークン型を表すために使われる文字列と同じものが、
その型の数値符号を表すCの式でもあります。
これには、2種類の働きがあります。
もし、トークン型が文字リテラルならば、
その数値符号は文字のASCII符号であり、
数値を表すために字句解析器の中と同じ文字リテラルを使えます。
もし、トークン型が識別子ならば、適切な番号を定義するCのマクロとして、
その識別子がBisonによって定義されます。
したがって、この例では、@code{NUM}は、@code{yylex}のために使える
マクロにもなります。

トークンの意味値は、もし存在すれば、大域変数@code{yylval}に記憶され、
Bison構文解析器はそこを見にいきます
(@code{yylval}のCデータ型は、文法の最初で定義される@code{YYSTYPE}です。
@pxref{Rpcalc Decls, ,Declarations for @code{rpcalc}})。

ファイルの終わりに達すると、トークン型のコード0が返されます
(Bisonは、正でない任意の値を入力の終わりと認識します)。

字句解析器のプログラムの例を示します。

@example
@group
/*
 * 字句解析器は、数値を読めば、double型の値をスタックに積んで
 * トークン「NUM」を返し、数値以外を読めば、その文字のアスキー符号を返す。
 * 空白とタブは読み飛ばされる。ファイルが終わると0を返す。
 */

#include <ctype.h>
@end group

@group
yylex ()
@{
  int c;

  /* 空白類を読み飛ばす  */
  while ((c = getchar ()) == ' ' || c == '\t')  
    ;
@end group
@group
  /* 数値を処理する   */
  if (c == '.' || isdigit (c))                
    @{
      ungetc (c, stdin);
      scanf ("%lf", &yylval);
      return NUM;
    @}
@end group
@group
  /* ファイルの終わりを処理する  */
  if (c == EOF)                            
    return 0;
  /* 1文字を返す */
  return c;                                
@}
@end group
@end example


@node Rpcalc Main, Rpcalc Error, Rpcalc Lexer, RPN Calc
@subsection 制御関数
@cindex controlling function
@cindex main function in simple example
@cindex 制御関数
@cindex 単純な例のmain関数
@cindex main関数

この例の精神に則って、制御関数は、飾りのない最小限のものです。
唯一必要なことは、構文解析の処理を始めるために、
@code{yyparse}関数を呼び出すことです。

@example
@group
main ()
@{
  yyparse ();
@}
@end group
@end example

@footnote{【訳注】古いK&R-C処理系を使う場合には前述の例のままでよいのですが、
ANSI-C処理系を使う場合には、@code{main}関数が返す値が
@code{int}型なので、次のように書くべきです。
他の関数についても同様です。本書の例のすべては古い書式で書かれています。

@example
@group
int main ()
@{
  return yyparse ();
@}
@end group
@end example
}

@node Rpcalc Error, Rpcalc Gen, Rpcalc Main, RPN Calc
@subsection エラー報告関数
@cindex error reporting routine
@cindex エラー報告関数

@code{yyparse}は、構文エラーを検出すると、エラーメッセージ
(必ずそうとはかぎりませんが、通常は@code{"parse error"})を
表示するために、エラー報告関数@code{yyerror}を呼び出します。

@example
@group
#include <stdio.h>

yyerror (s)  /* エラーが起きるとyyparseから呼び出される */
     char *s;
@{
  printf ("%s\n", s);
@}
@end group
@end example

@code{yyerror}から戻った後に、Bison構文解析器は、
文法に適切なエラー規則(@pxref{Error Recovery})があれば、
エラーから回復し、解析を継続できます。
そうでない場合には、@code{yyparse}が0でない値を返します。
この例では、エラー規則を書いていないので、
不正な入力はすべて電卓プログラムを終了させます。
これは、実際の電卓としてはきれいな動作ではありませんが、
最初の例としては十分です。


@node Rpcalc Gen, Rpcalc Compile, Rpcalc Error, RPN Calc
@subsection 構文解析器を生成するためにBisonを実行
@cindex running Bison (introduction)
@cindex Bisonの実行

構文解析器を生成するためにBisonを実行する前に、
1つ以上のソースファイルのすべてをどのように整えるか、
決める必要があります。
このような単純な例では、すべてを1個のファイルに詰め込む方法が
いちばん簡単です。
@code{yylex}、@code{yyerror}、@code{main}の定義を、
ファイルの「追加のCコード」部の最後に置きます
(@pxref{Grammar Layout, ,The Overall Layout of a Bison Grammar})。

大きなプロジェクトでは、ソースコードを複数のファイルに分け、
まとめてリコンパイルするために@code{make}を使うでしょう。

1つのファイルにすべてのソースが入っているならば、
次のコマンドで、それを構文解析器ファイルに変換できます。

@example
bison @var{file_name}.y
@end example

この例では、ファイルは@file{rpcalc.y}(逆ポーランド記法電卓)と
呼ばれています。Bisonは、元のファイル名から@samp{.y}を取り除いて、
@file{@var{file_name}.tab.c}というファイルを生成します。
Bisonが出力したファイルには、@code{yyparse}のソースコードが含まれています。
入力ファイル中の追加の関数(@code{yylex}、@code{yyerror}、@code{main})は、
出力にそのまま複写されます。


@node Rpcalc Compile,  , Rpcalc Gen, RPN Calc
@subsection 構文解析器ファイルのコンパイル
@cindex compiling the parser
@cindex コンパイル

構文解析器ファイルをコンパイルする方法を示します。
@footnote{【訳注】UNIX上で@code{cc}コマンドを使ってコンパイルする方法を示します。}

@example
@group
# @r{カレントディレクトリのファイルの一覧を見る。}
% ls
rpcalc.tab.c  rpcalc.y
@end group

@group
# @r{Bison構文解析器をコンパイルする。}
# @r{数学ライブラリ内の@code{pow}関数をリンクするために@samp{-lm}を指定する。}
% cc rpcalc.tab.c -lm -o rpcalc
@end group

@group
# @r{再び、ファイルの一覧を見る。}
% ls
rpcalc  rpcalc.tab.c  rpcalc.y
@end group
@end example

できた@file{rpcalc}ファイルは、実行可能プログラムです。
@code{rpcalc}を実行させる例を示します。

@example
% rpcalc
4 9 +
13
3 7 + 3 4 5 *+-
-13
3 7 + 3 4 5 * + - n              @r{単項マイナスを示す@samp{n}に注意}
13
5 6 / 4 n +
-3.166666667
3 4 ^                            @r{べき乗関数}
81
^D                               @r{入力の終わり}
%
@end example


@node Infix Calc, Simple Error Recovery, RPN Calc, Examples
@section 中間記法電卓:@code{calc}
@cindex infix notation calculator
@cindex calc
@cindex calculator, infix notation
@cindex 中間記法

後置記法演算子に代わって中間記法演算子を扱うように
rpcalcを変更します。
中間記法には、演算子の優先順位の概念と、
適切な深さに入れ子できるかっこが必要です。
中間記法電卓を作るためのBisonソースファイル
@file{calc.y}を示します。

@example
/* 中間記法電卓 -- calc */

%@{
#define YYSTYPE double
#include <math.h>
%@}

/* BISON宣言 */
%token NUM
%left '-' '+'
%left '*' '/'
%left NEG     /* negation--単項マイナス */
%right '^'    /* べき乗関数        */

/* 文法規則が続く */
%%
input:    /* 空文字列 */
        | input line
;

line:     '\n'
        | exp '\n'  @{ printf ("\t%.10g\n", $1); @}
;

exp:      NUM                @{ $$ = $1;         @}
        | exp '+' exp        @{ $$ = $1 + $3;    @}
        | exp '-' exp        @{ $$ = $1 - $3;    @}
        | exp '*' exp        @{ $$ = $1 * $3;    @}
        | exp '/' exp        @{ $$ = $1 / $3;    @}
        | '-' exp  %prec NEG @{ $$ = -$2;        @}
        | exp '^' exp        @{ $$ = pow ($1, $3); @}
        | '(' exp ')'        @{ $$ = $2;         @}
;
%%
@end example

@code{yylex}、@code{yyerror}、@code{main}関数は、
前の例のものと同じです。

このプログラムには、2つの重要な特徴があります。

第2の部分(Bison宣言部)では、
@code{%left}がトークンの型とそれが左結合演算子であると宣言します。
宣言@code{%left}と@code{%right}(右結合演算子)は、
結合性を持たないトークン型名を宣言するために使われる@code{%token}の代わりに
なります
(1文字のリテラルであるトークンは、通常、宣言する必要がありません。
ここでは、結合性を宣言します)。

演算子の優先順位は、宣言が書かれる行の順序で決まります。
後から宣言された演算子ほど、高い優先順位を持ちます。
したがって、べき乗の優先順位がもっとも高く、
単項の負(@code{NEG})、「@samp{*}」と「@samp{/}」と続きます。
@xref{Precedence, ,Operator Precedence}。

もう1つの重要な特徴は、単項の負の演算子のために文法部分にある
@code{%prec}です。
@code{%prec}は、単純にBisonに対して、規則@samp{| '-' exp}は
@code{NEG}と同じ優先順位を持つように指示し、
この例ではどちらも2番目に高い優先順位を持ちます。

以下は@file{calc.y}の実行例です。

@need 500
@example
% calc
4 + 4.5 - (34/(8*3+-3))
6.880952381
-56 + 2
-54
3 ^ 2
9
@end example


@node Simple Error Recovery, Multi-function Calc, Infix Calc, Examples
@section 単純なエラー回復
@cindex error recovery, simple
@cindex エラー回復

今まで、本書では、@dfn{エラー回復(error recovery)}、
つまり、構文エラーを検出した後で構文解析を続ける方法については
言及していませんでした。
今までに扱ったことは、@code{yyerror}を使ってエラーを報告することだけでした。
@code{yyerror}を呼び出した後で、特に指定しないと@code{yyparse}は
処理を終わることを思い出してください。
つまり、エラーを含む入力行が、電卓プログラムを終了させます。
この欠陥をどのように改善するか示しましょう。

Bison言語の文法規則には、予約語@code{error}があります。
次の例では、@code{line}に対する選択肢群に@code{error}を追加する
方法を示します。

@example
@group
line:     '\n'
        | exp '\n'   @{ printf ("\t%.10g\n", $1); @}
        | error '\n' @{ yyerrok;                  @}
;
@end group
@end example

文法へのこの追加によって、構文解析エラーが発生した場合に、
簡単なエラー回復が可能になります。
評価不可能な式が読み込まれると、
@code{line}に対する第3の規則によってエラーが認識され、
構文解析が続けられます。
この場合にも、関数@code{yyerror}は呼び出され、
メッセージを表示します。
アクションは、
Bisonによって自動的に定義されるマクロである@code{yyerrok}文を実行します。
これはエラー回復の完了を意味します(@pxref{Error Recovery})。
@code{yyerrok}と@code{yyerror}の違いに注意してください。

この形式のエラー回復は、構文エラーを扱います。
他の種類のエラーもあります。
たとえば、0による除算は、例外シグナルを発生し、通常は致命的です。
実際の電卓プログラムは、このシグナルをつかまえて、@code{longjmp}を使って
@code{main}に戻り、入力行の構文解析を続ける必要があります。
さらに、現在の入力行の残りは破棄されるべきです。
しかし、これらの問題は、Bisonのプログラムに固有の問題ではないので、
本書では解説しません。


@node Multi-function Calc, Exercises, Simple Error Recovery, Examples
@section 多機能電卓:@code{mfcalc}
@cindex multi-function calculator
@cindex mfcalc
@cindex calculator, multi-function
@cindex 多機能電卓
@cindex 電卓, 多機能

Bisonの基礎についての説明が終わったので、より高度な話題に移りましょう。
前述の電卓は、5種類の機能、@samp{+}、@samp{-}、@samp{*}、@samp{/}、
@samp{^}を持っています。
この電卓に、その他の数学関数、たとえば、@code{sin}、@code{cos}などを
追加するとよいでしょう。

中間記法電卓への新しい演算子の追加は、
その演算子が1文字リテラルならば簡単です。
字句解析器@code{yylex}は、数値以外のすべての文字をトークンとして渡すので、
追加の演算子に対応する文法規則を追加するだけです。
しかし、次のような表記方法の、より柔軟な組み込み関数が必要です。

@example
@var{関数名} (@var{引数})
@end example

さらに、電卓にメモリを追加し、名前付き変数を作り、そこに値を記憶し、
後で使えるようにしましょう。
以下に多機能電卓を使う作業の例を示します。

@example
% mfcalc
pi = 3.141592653589
3.1415926536
sin(pi)
0.0000000000
alpha = beta1 = 2.3
2.3000000000
alpha
2.3000000000
ln(alpha)
0.8329091229
exp(ln(beta1))
2.3000000000
%
@end example


複数の代入@footnote{【訳注】例の@samp{alpha = beta1 = 2.3}}と
関数の入れ子@footnote{【訳注】例の@samp{exp(ln(beta1))}}が
許されることに注意してください。

@menu
* Decl: Mfcalc Decl.      多機能電卓のためのBisonの宣言.
* Rules: Mfcalc Rules.    電卓のための文法規則.
* Symtab: Mfcalc Symtab.  記号表を管理するサブルーチン.
@end menu


@node Mfcalc Decl, Mfcalc Rules,  , Multi-function Calc
@subsection @code{mfcalc}のための定義

以下には、多機能電卓のための、CとBisonの宣言があります。

@smallexample
%@{
#include <math.h>  /* cos(), sin()などの数学関数のため */
#include "calc.h"  /* `symrec'の定義を含む             */
%@}
%union @{
double     val;    /* 数値を返すため                   */
symrec  *tptr;     /* 記号表へのポインタを返すため     */
@}

%token <val>  NUM        /* 単純な倍精度数値 */
%token <tptr> VAR FNCT   /* 変数と関数       */
%type  <val>  exp

%right '='
%left '-' '+'
%left '*' '/'
%left NEG     /* 否定 -- 単項の負 */
%right '^'    /* べき乗           */

/* 文法が続く */

%%
@end smallexample

この文法の導入部分では、Bison言語の新しい2つの機能を使っています。
これらの機能によって、意味値がいろいろなデータ型を持てます
(@pxref{Multiple Types, ,More Than One Value Type})。

@code{%union}宣言は、@code{YYSTYPE}の定義の代わりで、
可能な型の一覧を指定します。
ここで許される型は、(@code{exp}と@code{NUM}のための)倍精度浮動小数点型と、
記号表の項目へのポインタです。
@xref{Union Decl, ,The Collection of Value Types}。

値がいろいろな型を持つことができるので、
意味値を使うそれぞれの文法記号に対して、
型を関連づける必要があります。
これらの記号は@code{NUM}、@code{VAR}、@code{FNCT}、@code{exp}です。
それらの宣言は、不等号で囲まれた(@samp{<...>})データ型に関する
情報を付加されています。

Bisonは、ちょうど@code{%token}がトークン型の宣言に使われるのと同じように、
@code{%type}が非終端記号の宣言に使われるようにします。
非終端記号は通常それらを定義する規則によって暗黙に宣言されるので、
@code{%type}をその規則よりも先に使ってはいけません。
しかし、@code{exp}は、その値の型を指定するので、
明示的に宣言する必要があります。
@xref{Type Decl, ,Nonterminal Symbols}。


@node Mfcalc Rules, Mfcalc Symtab, Mfcalc Decl, Multi-function Calc
@subsection @code{mfcalc}のための文法規則

多機能電卓のための文法規則を示します。
大部分は、@code{calc}の文法規則からの複写です。
@code{VAR}、@code{FUNCT}に関連する3つの規則が新しいものです。

@smallexample
input:   /* 空 */
        | input line
;

line:
          '\n'
        | exp '\n'   @{ printf ("\t%.10g\n", $1); @}
        | error '\n' @{ yyerrok;                  @}
;

exp:      NUM                @{ $$ = $1;                         @}
        | VAR                @{ $$ = $1->value.var;              @}
        | VAR '=' exp        @{ $$ = $3; $1->value.var = $3;     @}
        | FNCT '(' exp ')'   @{ $$ = (*($1->value.fnctptr))($3); @}
        | exp '+' exp        @{ $$ = $1 + $3;                    @}
        | exp '-' exp        @{ $$ = $1 - $3;                    @}
        | exp '*' exp        @{ $$ = $1 * $3;                    @}
        | exp '/' exp        @{ $$ = $1 / $3;                    @}
        | '-' exp  %prec NEG @{ $$ = -$2;                        @}
        | exp '^' exp        @{ $$ = pow ($1, $3);               @}
        | '(' exp ')'        @{ $$ = $2;                         @}
;
/* 文法の終わり */
%%
@end smallexample


@node Mfcalc Symtab,  , Mfcalc Rules, Multi-function Calc
@subsection @code{mfcalc}の記号表
@cindex symbol table example
@cindex 記号表の例

変数と関数の名前と意味を保持するために、
多機能電卓は記号表を必要とします。
これは、アクションを除く文法規則とBison宣言には影響しませんが、
追加のCの関数がいくつか必要です。

記号表は、レコードのリンクリストからなります。
その定義は、後述の、ヘッダファイル@file{calc.h}にあります。
関数と変数の両方を表に置くことができます。

@smallexample
@group
/* 記号表のリンクを表すデータ型                 */
struct symrec
@{
  char *name;  /* 記号の名前                    */
  int type;    /* 記号の種類:VARまたはFNCT     */
  union @{
    double var;           /* VARの値            */
    double (*fnctptr)();  /* FNCTの値           */
  @} value;
  struct symrec *next;    /* 次の項目へのリンク */
@};
@end group

@group
typedef struct symrec symrec;

/* `struct symrec'のリンクである記号表          */
extern symrec *sym_table;

symrec *putsym ();
symrec *getsym ();
@end group
@end smallexample

新しい@code{main}関数は、記号表を初期化する関数である
@code{init_table}を呼びます。
@code{main}と@code{init_table}を以下に示します。

@smallexample
@group
#include <stdio.h>

main ()
@{
  init_table ();
  yyparse ();
@}
@end group

@group
yyerror (s)  /* エラーがあるとyyparseから呼び出される */
     char *s;
@{
  printf ("%s\n", s);
@}

struct init
@{
  char *fname;
  double (*fnct)();
@};
@end group

@group
struct init arith_fncts[]
  = @{
      "sin", sin,
      "cos", cos,
      "atan", atan,
      "ln", log,
      "exp", exp,
      "sqrt", sqrt,
      0, 0
    @};

/* 記号表:`struct symrec'のリスト       */
symrec *sym_table = (symrec *)0;
@end group

@group
init_table ()  /* 数学関数を表に登録する */
@{
  int i;
  symrec *ptr;
  for (i = 0; arith_fncts[i].fname != 0; i++)
    @{
      ptr = putsym (arith_fncts[i].fname, FNCT);
      ptr->value.fnctptr = arith_fncts[i].fnct;
    @}
@}
@end group
@end smallexample

単純に初期化リストを編集して、必要なインクルードファイルを追加するだけで、
電卓に関数を追加できます。

記号表に記号を登録して検索するために、2個の重要な関数があります。
関数@code{putsym}は、登録すべきオブジェクトの
名前と型(@code{VAR}や@code{FNCT})を渡されます。
オブジェクトはリストの先頭にリンクされ、
オブジェクトへのポインタが返されます。
関数@code{getsym}は、検索すべき記号の名前を渡されます。
もし見つかれば記号へのポインタが返され、
見つからなければ0が返されます。

@smallexample
symrec *
putsym (sym_name,sym_type)
     char *sym_name;
     int sym_type;
@{
  symrec *ptr;
  ptr = (symrec *) malloc (sizeof (symrec));
  ptr->name = (char *) malloc (strlen (sym_name) + 1);
  strcpy (ptr->name,sym_name);
  ptr->type = sym_type;
  ptr->value.var = 0; /* 関数の場合にも値を0にする */
  ptr->next = (struct symrec *)sym_table;
  sym_table = ptr;
  return ptr;
@}

symrec *
getsym (sym_name)
     char *sym_name;
@{
  symrec *ptr;
  for (ptr = sym_table; ptr != (symrec *) 0;
       ptr = (symrec *)ptr->next)
    if (strcmp (ptr->name,sym_name) == 0)
      return ptr;
  return 0;
@}
@end smallexample

今度の関数@code{yylex}は、変数、数値、1文字の算術演算子を
認識する必要があります。
英字で始まり英数字からなる文字列は、記号表にどう書かれているかに応じて、
変数と関数のどちらとも認識されます。

文字列は、記号表を検索するために@code{getsym}に渡されます。
もし名前が表にあれば、その場所へのポインタと
名前の型(@code{VAR}または@code{FNCT})が、
@code{yyparse}に返されます。
名前がまだ表になければ、@code{putsym}を使って、
@code{VAR}として登録されます。
そして、ポインタと型(この場合には必ず@code{VAR})が
@code{yyparse}に返されます。

@code{yylex}の中で、数値と算術演算子の扱いに関する部分は、
変更する必要がありません。

@smallexample
@group
#include <ctype.h>
yylex ()
@{
  int c;

  /* 空白を読み飛ばし、空白以外を得る         */
  while ((c = getchar ()) == ' ' || c == '\t');

  if (c == EOF)
    return 0;
@end group

@group
  /* 数値を読む   */
  if (c == '.' || isdigit (c))
    @{
      ungetc (c, stdin);
      scanf ("%lf", &yylval.val);
      return NUM;
    @}
@end group

@group
  /* 識別子を読む */
  if (isalpha (c))
    @{
      symrec *s;
      static char *symbuf = 0;
      static int length = 0;
      int i;
@end group

@group
      /* バッファの長さの初期値は40文字       */
      if (length == 0)
        length = 40, symbuf = (char *)malloc (length + 1);

      i = 0;
      do
@end group
@group
        @{
          /* あふれたのでバッファを大きくする */
          if (i == length)
            @{
              length *= 2;
              symbuf = (char *)realloc (symbuf, length + 1);
            @}
          /* 文字をバッファに変える           */
          symbuf[i++] = c;
          /* 次の文字を読む                   */
          c = getchar ();
        @}
@end group
@group
      while (c != EOF && isalnum (c));

      ungetc (c, stdin);
      symbuf[i] = '\0';
@end group

@group
      s = getsym (symbuf);
      if (s == 0)
        s = putsym (symbuf, VAR);
      yylval.tptr = s;
      return s->type;
    @}

  /* その他の文字は文字リテラルトークン       */
  return c;
@}
@end group
@end smallexample

このプログラムは、強力かつ柔軟です。
新しい関数の追加は簡単です。
@code{pi}や@code{e}のようにあらかじめ定義された変数を追加するために
プログラムを変更することは、簡単な仕事でしょう。


@node Exercises,  , Multi-function Calc, Examples
@section 練習問題
@cindex exercises
@cindex 練習問題

@enumerate
@item
@file{math.h}にある関数のいくつかを、初期化リストに追加しなさい。

@item
定数の名前と値を記憶する別の配列を追加しなさい。
そして、@code{init_table}を変更し、定数を記号表に追加しなさい。
定数に型@code{VAR}を与えれば簡単でしょう。

@item
初期化されていない変数について、値を書き込むのではなく、
値を使おうとするとエラーを報告するように、プログラムを改良しなさい。
@end enumerate


@node Grammar File, Interface, Examples, Top
@chapter Bison文法ファイル

Bisonは、文脈自由文法の仕様を入力として受け取り、
その文法の正しいインスタンスを認識する、
C言語の関数を生成します。

Bison文法ファイルの名前は、通常@samp{.y}で終わります。

@menu
* Grammar Outline::   文法ファイルの概略.
* Symbols::           終端記号と非終端記号.
* Rules::             文法規則の書き方.
* Recursion::         再帰的規則の書き方.
* Semantics::         意味値とアクション.
* Declarations::      全ての種類のBison宣言の説明.
* Multiple Parsers::  一つのプログラムに一つより多くのBison構文解析器を
                        入れる.
@end menu


@node Grammar Outline, Symbols,  , Grammar File
@section Bison文法の概要


Bison文法ファイルは4つの主要な部分からなります。
それらを、適切な区切り文字とともに示します。

@example
%@{
@var{C宣言部(C declarations)}
%@}

@var{Bison宣言部(Bison declarations)}

%%
@var{文法規則部(Grammar rules)}
%%

@var{追加のCプログラム部(Additional C code)}
@end example


@samp{/* @dots{} */}で囲まれたコメントは、どの部分にも書けます。

@menu
* C Declarations::    C宣言部の構文と使用法.
* Bison Declarations::  Bison宣言部の構文と使用法.
* Grammar Rules::     文法規則部の構文と使用法.
* C Code::            追加のCコード部の構文と使用法.
@end menu


@node C Declarations, Bison Declarations,  , Grammar Outline
@subsection C宣言部
@cindex C declarations section
@cindex declarations, C
@cindex C宣言部
@cindex 宣言, C


@dfn{C宣言部(C declarations)}には、マクロ定義と、文法定義のアクションで
使うための関数と変数の宣言があります。
これらは、@code{yyparse}の定義に優先するように、構文解析器ファイルの最初に
複写されます。
ヘッダファイルから宣言を得るには@samp{#include}を使います。
C宣言がまったく必要ない場合は、この部分を囲む
@samp{%@{}と@samp{%@}}を省略できます。


@node Bison Declarations, Grammar Rules, C Declarations, Grammar Outline
@subsection Bison宣言部
@cindex Bison declarations (introduction)
@cindex declarations, Bison (introduction)
@cindex Bison宣言(導入)
@cindex 宣言, Bison(導入)

@dfn{Bison宣言部(Bison declarations)}は、終端記号と非終端記号の宣言、
演算子の優先順位の指定などを含みます。
単純な例では、宣言を省略できます。
@xref{Declarations, ,Bison Declarations}。


@node Grammar Rules, C Code, Bison Declarations, Grammar Outline
@subsection 文法規則部
@cindex grammar rules section
@cindex rules section for grammar
@cindex 文法規則部
@cindex 規則部,文法に対する

@dfn{文法規則部(grammar rules)}は、1つ以上のBison文法規則を含み、
それ以外は含みません。
@xref{Rules, ,Syntax of Grammar Rules}。

少なくとも1つの文法規則が存在する必要があります。
また、文法規則より先に@samp{%%}が必要で、
もしそれ以前に何も記述されていなくても、省略できません。


@node C Code,  , Grammar Rules, Grammar Outline
@subsection 追加のCプログラム部
@cindex additional C code section
@cindex C code, section for additional
@cindex 追加のCプログラム部
@cindex Cプログラム, 追加の

@dfn{追加のCプログラム部(additional C code)}は、@dfn{C宣言部}が構文解析器ファイルの先頭に複写
されるのと同じように、構文解析器ファイルの末尾にそのまま複写されます。
構文解析器ファイル中に置く必要があって、
@code{yyparse}の定義よりも前に置く必要のないものを、ここに置くと便利です。
たとえば、@code{yylex}と@code{yyerror}の定義は、
よくここに置かれます。
@xref{Interface, ,Parser C-Language Interface}。

もし直前の部が空ならば、文法規則と区別するための
@samp{%%}を省略できます。

Bison構文解析器は、名前が@samp{yy}で始まる多くの静的変数と、
名前が@samp{YY}で始まる多くのマクロを含んでいます。
本書で解説しているものを意図的に使う場合を除いて、
そのような名前を文法ファイルの追加のCプログラム部で使うのは避けるべきです。


@node Symbols, Rules, Grammar Outline, Grammar File
@section 記号、終端と非終端
@cindex nonterminal symbol
@cindex terminal symbol
@cindex token type
@cindex symbol
@cindex 非終端記号
@cindex 終端記号
@cindex トークン型
@cindex 記号

Bison文法の@dfn{記号(symbols)}は、
言語の文法的分類を表現します。

@dfn{終端記号(terminal symbol)}
(@dfn{トークン型(tokens types)}ともいいます)は、
構文的に等価なトークンのクラスを表します。
そのクラスのトークンが許されることを表すために、
文法規則の中で記号を使えます。
その記号は、Bison構文解析器の中で番号で表現され、
@code{yylex}関数は、どのような種類のトークンが読み込まれたかを示すために、
トークン番号を返します。
これを表す記号を知っていればよく、その番号を知っている必要はありません。

@dfn{非終端記号(nonterminal symbol)}は、
構文的に等価なグループを表現します。
記号名は文法規則の記述に使われます。
通常、非終端記号名を小文字で書きます。

記号名は、英字、先頭以外での数字、下線記号(@samp{_})とピリオドからなります。
ピリオド記号(@samp{.})は、非終端記号の名前には使えますが、
終端記号の名前には使えません。

文法中で終端記号を記述するには3種類の方法があります。

@itemize @bullet
@item
@dfn{名前付きトークン型(named token type)}を、
C言語における識別子と同様な、識別子とともに書きます。
通常、大文字で書きます。
これらは@code{%token}のようなBison宣言とともに定義する必要があります。
@xref{Token Decl, ,Token Type Names}。

@item
@cindex character token
@cindex literal token
@cindex single-character literal
@cindex 文字トークン
@cindex リテラルトークン
@cindex 1文字リテラル
@dfn{文字トークン型(character token type)}、
すなわち@dfn{リテラル文字トークン(literal character token)}は、
C言語の文字定数と同じ構文で書かれ、
たとえば@code{'+'}は文字トークン型です。
意味値データ型(@pxref{Value Type, ,Data Types of Semantic Values})、
結合性、優先順位(@pxref{Precedence, ,Operator Precedence})を
指定する必要がなければ、
文字トークン型を宣言する必要はありません。

通常、文字トークン型は、特別な文字@footnote{【訳注】英数字以外の文字。}から
なるトークンを表すためだけに使います。
たとえば、トークン型@code{'+'}を、
トークンとしての@samp{+}文字を表すために使います。
このようにする義務はありませんが、そうしないと、
あなたが書いたプログラムを読む人が混乱するでしょう。

C言語の文字リテラルで使われる通常のエスケープシーケンス
@footnote{【訳注】@samp{\}に続く表現。}を、Bisonでも使えます。
しかし、@code{'\0'}だけはASCII符号の0を表し、
@code{yylex}がファイルの終わりを示す符号なので、
文字リテラルとしては使えません
(@pxref{Calling Convention, ,Calling Convention for @code{yylex}})。

@item
@cindex string token
@cindex literal string token
@cindex multi-character literal
@cindex 文字列トークン
@cindex リテラル文字列トークン
@cindex 複数文字リテラル
@dfn{リテラル文字列トークン(literal string token)}は、
C言語における文字列定数と同様に書きます。
たとえば、@code{"<="}がリテラル文字列トークンです。
意味値(@pxref{Value Type})、
結合性、優先順位(@pxref{Precedence, ,Operator Precedence})を
指定する必要がなければ、
リテラル文字列トークンを宣言する必要はありません。

@code{%token}宣言(@pxref{Token Decl, ,Token Declarations})を使って、
リテラル文字列トークンを、記号名の別名として関連づけられます。
そうしないと、字句解析器は、
@code{yytname}表(@pxref{Calling Convention})を使って、
リテラル文字列トークンからトークン番号を検索する必要があります。

@strong{【警告】}@code{yacc}ではリテラル文字列トークンを使えません。

通常、特殊文字の列からなるトークンの表現にのみ、
リテラル文字列トークンを使います。
たとえば、トークンとしての@samp{<=}を表すために、
トークン型@code{"<="}を使うべきです。
そうする義務はありませんが、そうしないと、
あなたが書いたプログラムを読む人が混乱するでしょう。

C言語で使えるエスケープシーケンスはすべてBisonでも使えます。
リテラル文字列トークンは、2文字以上からなります。
もし、トークンが1文字ならば、前述の1文字トークンを使ってください。
@end itemize

終端記号を書く方法は、終端記号の文法的意味に関係なく、
規則の中に現れる位置と、
構文解析器関数が記号を返す方法に関係します。

@code{yylex}が返す値は、終端記号のどれかを表し、
入力の終わりでは0です。
文法規則の中でどの方法でトークン型を書いても、
@code{yylex}を定義する書き方は同じです。
1文字トークン型に対する符号は、その文字のASCII符号なので、
@code{yylex}は必要な符号を生成するために同一の文字定数を使えます。
名前を付けられたトークン型はそれぞれ、
構文解析器ファイルの中でCのマクロになるので、
@code{yylex}は符号に対するマクロ名を使えます。
これが、終端記号の名前にピリオド記号を使えない理由です。
@xref{Calling Convention, ,Calling Convention for @code{yylex}}。

@code{yylex}が構文解析器と別のソースファイルの中に書かれる場合には、
そこでトークン型マクロ定義を使えるように準備する必要があります。
@samp{-d}オプションを付けてBisonを実行してください。
すると、マクロ定義が@file{@var{name}.tab.h}というファイルに書かれ、
必要に応じて別のソースファイルからインクルードできます。
@xref{Invocation, ,Invoking Bison}。

記号@code{error}は、エラー回復用に予約された終端記号(@pxref{Error Recovery})
で、他の目的に使うべきではありません。
実際に、@code{yylex}がこの値を返すことは決してありません。


@node Rules, Recursion, Symbols, Grammar File
@section 文法規則の構文
@cindex rule syntax
@cindex grammar rule syntax
@cindex syntax of grammar rules
@cindex 規則の構文
@cindex 文法規則の構文
@cindex 構文, 文法規則

Bison文法規則は、一般的に次の書式です。

@example
@group
@var{result}: @var{components}@dots{}
        ;
@end group
@end example

@var{result}は、この規則が記述する非終端記号で、
@var{components}は、この規則で一緒に置かれるさまざまな
終端および非終端記号です。
例を示します。

@example
@group
exp:      exp '+' exp
        ;
@end group
@end example

この例では、@samp{+}トークンを間にはさんで
型@code{exp}の2つのグループ化が行われ、
型@code{exp}のより大きなグループができます。

規則の中の空白@footnote{【訳注】任意の数の空白文字、タブ符号、改行符号。}は、
記号を分けるだけの意味を持ちます。
必要に応じて、余分な空白を書いてもかまいません。

@var{components}の周辺にあるものは、
規則の意味を決定する@var{アクション(action)}になることができます。
アクションは、次のようになります。

@example
@{@var{C statements}@}
@end example

通常、1つだけのアクションと、それに続く@var{components}があります。
@xref{Actions}。

@findex |
同一の@var{result}に対する複数の規則は、
別々に書くこともできますし、
次の例のように縦線記号@samp{|}で区切ってまとめて書くことも可能です。

@ifinfo
@example
@var{result}:   @var{rule1-components}@dots{}
        | @var{rule2-components}@dots{}
        @dots{}
        ;
@end example
@end ifinfo
@iftex
@example
@group
@var{result}:    @var{rule1-components}@dots{}
        | @var{rule2-components}@dots{}
        @dots{}
        ;
@end group
@end example
@end iftex

まとめて書いても、それぞれの規則は別々のものとみなされます。

もし、規則中の@var{components}が空ならば、
@var{result}が空の列にマッチできることを意味します。
例として、カンマで区切られた0個以上の@code{exp}のグループを
定義する方法を示します。

@example
@group
expseq:   /* 空 */
        | expseq1
        ;
@end group

@group
expseq1:  exp
        | expseq1 ',' exp
        ;
@end group
@end example

空の@var{component}を持つ規則には、通常
@samp{/* 空 */}という注釈を書きます。


@node Recursion, Semantics, Rules, Grammar File
@section 再帰的規則
@cindex recursive rule
@cindex 再帰的規則

@var{result}である非終端記号が規則の右側にも現れる場合に、
その規則は@dfn{再帰的(recursive)}であるといいます。
Bison文法の大部分は再帰的規則を使います。
なぜならば、任意の数の並びを定義する唯一の方法が、
再帰的規則だからです。
1つ以上のカンマで区切られた式の並びの定義を考えてみましょう。

@example
@group
expseq1:  exp
        | expseq1 ',' exp
        ;
@end group
@end example

@cindex left recursion
@cindex right recursion
@cindex 左再帰
@cindex 右再帰

@code{expseq1}で使われている再帰は、規則の右側の中でもっとも左側にあるので、
このような再帰を@dfn{左再帰(left recursion)}と呼びます。
逆に、同じ構造を@dfn{右再帰(right recursion)}を使って書いてみます。

@example
@group
expseq1:  exp
        | exp ',' expseq1
        ;
@end group
@end example

あらゆる並びを、左再帰を使っても、右再帰を使っても、定義できます。
しかし、限られたスタック容量で任意の数の並びを走査できるので、
つねに左再帰を使うべきです。
右再帰では、規則が適用される前にすべての要素をスタックに積む必要があるので、
要素の数に比例するスタック領域を消費します。
詳細については、@xref{Algorithm, ,The Bison Parser Algorithm }。

@cindex mutual recursion
@cindex 相互再帰

規則の結果が直接その右側には含まれず、
右側にある非終端記号の中に含まれるとき、
@dfn{間接(indirect)}すなわち@dfn{相互(mutual)}再帰が起きます。

例を示します。

@example
@group
expr:     primary
        | primary '+' primary
        ;
@end group

@group
primary:  constant
        | '(' expr ')'
        ;
@end group
@end example

この例では、それぞれの規則が互いに参照しているので、
2個の相互再帰が定義されています。


@node Semantics, Declarations, Recursion, Grammar File
@section 言語の意味の定義
@cindex defining language semantics
@cindex language semantics, defining 
@cindex 言語の意味の定義
@cindex 定義, 言語の意味

言語に対する文法規則は、文法だけを決めます。
意味は、各種のトークンとグループ化に対応する意味値により、
各種のグループ化が認識されるときに、決定されます。

電卓の例では、式のそれぞれに対応する値が適切な数値なので、
電卓は正確に計算できます。
グループ@w{@samp{@var{x} + @var{y}}}に
対応するアクションが、@var{x}と@var{y}に関する数値の和を計算します。

@menu
* Value Type::        全ての意味値に一つのデータ型を指定する.
* Multiple Types::    複数の別のデータ型を指定する.
* Actions::           アクションは文法規則の意味的定義.
* Action Types::      アクションが操作するデータ型を指定する.
* Mid-Rule Actions::  ほとんどのアクションは規則の最後に行く.
                      これは規則の最中で、いつ、なぜ、どのように
                        例外アクションを使用するかを指示する.
@end menu


@node Value Type, Multiple Types,  , Semantics
@subsection データ型と意味値
@cindex semantic value type
@cindex value type, semantic
@cindex data types of semantic values
@cindex default data type
@cindex 意味値型
@cindex 値型, 意味
@cindex 意味値のデータ型
@cindex 省略時データ型

単純なプログラムでは、言語の要素のすべての意味値に対して同じデータ型を
使えば十分です。
逆ポーランド記法と中間記法電卓の例では、そうでした
(@pxref{RPN Calc, ,Reverse Polish Notation Calculator})。

特に指定しないと、Bisonはすべての意味値に対して@code{int}型を使います。
他の型を使うには、次の例のように、マクロ@code{YYSTYPE}を定義します。

@example
#define YYSTYPE double
@end example

このマクロ定義は、文法ファイルのC宣言部に置く必要があります
(@pxref{Grammar Outline, ,Outline of a Bison Grammar})。


@node Multiple Types, Actions, Value Type, Semantics
@subsection 複数の値型

多くのプログラムでは、異なる種類のトークンとグループに対して、
異なるデータ型が必要です。
たとえば、数値定数は@code{int}型や@code{long}型を必要とし、
文字列定数は@code{char *}型を必要とし、
識別子は記号表の項目へのポインタを必要とするでしょう。

同一の構文解析器内で、意味値に対して2つ以上のデータ型を使うには、
次の2項目が必要です。

@itemize @bullet
@item
Bison宣言の@code{%union}で、考えられるデータ型全体の集合を指定します
(@pxref{Union Decl, ,The Collection of Value Types})。

@item
終端または非終端記号のそれぞれについて、
その意味値を使うために、上記の型のどれか1つを選びます。
トークンに対する型の指定には、Bison宣言の@code{%token}を使います
(@pxref{Token Decl, ,Token Type Names})。
グループ化に対する型の指定には、Bison宣言の@code{%type}を使います
(@pxref{Type Decl, ,Nonterminal Symbols})。
@end itemize


@node Actions, Action Types, Multiple Types, Semantics
@subsection アクション
@cindex action
@cindex アクション
@vindex $$
@vindex $@var{n}

文法規則にともなうアクションは、その規則が認識されるたびに実行される
Cのプログラムからなります。
アクションの仕事のほとんどは、関連するトークンまたは小さいグループから
規則にしたがって構成されるグループの、意味値の計算です。

アクションは、Cの複文のように、ブレースで囲まれたCの文からなります。
アクションは、規則のどの場所にも置け、その場所で実行されます。
規則のほとんどは、規則の終わりの構成要素の並びの後に、
1つだけアクションを持ちます。
規則の途中に置かれたアクションは、手の込んだ方法で特別な目的に使われます
(@pxref{Mid-Rule Actions, ,Actions in Mid-Rule})。

アクションの中のCで書かれたプログラムは、
規則の第@var{n}番目の要素に対応する意味値を、
@code{$@var{n}}という書式で参照できます。
また、その規則が構成するグループの意味値を、
@code{$$}という書式で参照できます。
アクションが構文解析器ファイルに複写されるときに、Bisonは、
上記の構成要素を配列要素への参照に変換します。

例を示します。

@example
@group
exp:    @dots{}
        | exp '+' exp
            @{ $$ = $1 + $3; @}
@end group
@end example

この規則は、加算記号で結び付けられた2つの小さい@code{exp}グループから、
1つの@code{exp}を構成します。
このアクションの中で、@code{$1}と@code{$3}は、
規則の右側の最初と3番目の記号である@code{exp}グループの
意味値を参照します。
この規則によって認識される加算式の値になるように、
和が@code{$$}に代入されます。
もし、@samp{+}トークンに有用な値があるならば、
それを@code{$2}として参照できるでしょう。

@cindex default action
@cindex 省略時アクション

規則に対してアクションを指定しなければ、Bisonは、
省略時アクション@w{@code{$$ = $1}}を補います。
したがって、規則の最初の記号の値が規則全体の値になります。
もちろん、両者の型が一致する場合にのみ、省略時アクションは有効です。
空規則に対する省略時アクションは無意味です。
すべての空規則は、その規則の値が必要ならば、
明示的なアクションを持つ必要があります。

@code{$@var{n}}の@var{n}は0または負が許され、
現在の規則にマッチする@emph{前に}スタックに積まれていた
トークンとグループの意味値を参照します。
これは非常に危険な手法で、安全に使うためには、
その規則が適用される文脈をあなたが完全に理解している必要があります。
これを安全に使える例を示します。

@example
@group
foo:      expr bar '+' expr  @{ @dots{} @}
        | expr bar '-' expr  @{ @dots{} @}
        ;
@end group

@group
bar:      /* 空 */
        @{ previous_expr = $0; @}
        ;
@end group
@end example

@code{bar}がここに書かれた方法でのみ使われるならば、
@code{foo}の定義の中で@code{bar}より前の
@code{expr}の値を@code{$0}が参照します。


@node Action Types, Mid-Rule Actions, Actions, Semantics
@subsection アクション中の値のデータ型
@cindex action data types
@cindex data types in actions
@cindex アクションのデータ型
@cindex データ型, アクション

すべての意味値に対して同一のデータ型を使っているのならば、
@code{$$}と@code{$@var{n}}はそのデータ型を持ちます。

さまざまなデータ型を指定するために@code{%union}を使っているならば、
意味値を持つ終端記号と非終端記号のそれぞれに対して、
データ型の中から適切なものを選ぶように宣言する必要があります。
すると、@code{$$}と@code{@var{n}}を使うたびに、
規則の中でそれらがどの記号を参照するかに応じて、
データ型が決められます。
例を示します。

@example
@group
exp:    @dots{}
        | exp '+' exp
            @{ $$ = $1 + $3; @}
@end group
@end example

@code{$1}と@code{$3}は@code{exp}という種類の記号を参照するので、
@code{$1}と@code{$3}は、非終端記号@code{exp}に対して宣言された
データ型を持ちます。
もし、@code{$2}が使われるならば、どのような型であれ、
終端記号@code{+}に対して宣言されたデータ型が使われます。

別の方法として、値を参照するときにそのデータ型を指定できます。
そのためには、参照のための@samp{$}記号の後に@samp{<@var{type}>}を
挿入します。例を示します。

@example
@group
%union @{
  int itype;
  double dtype;
@}
@end group
@end example

この場合に、@code{$<itype>1}と書けば、
最初の要素を@code{int}型として参照でき、@code{$<dtype>1}と書けば、
@code{double}型として参照できます。


@node Mid-Rule Actions,  , Action Types, Semantics
@subsection 規則の途中のアクション
@cindex actions in mid-rule
@cindex mid-rule actions
@cindex 規則の途中のアクション
@cindex アクション, 規則の途中

まれに、アクションを規則の途中に置くと便利な場合があります。
これらのアクションは、通常の規則の終わりに置かれたアクションと同様に
記述されますが、構文解析器が後に続く要素を認識する前に実行されます。

規則の途中のアクションは、そのアクションよりも前にある要素を
@code{$@var{n}}を使って参照できますが、後に続く要素は
まだ構文解析されていないので参照できません。

規則の途中のアクション自身は、規則の要素の1つとして数えられます。
同じ規則の中に別のアクションが続く場合(通常は最後)に問題が起きます。
@code{$@var{n}}に使う番号@var{n}に
規則の途中のアクションを数えるのを忘れないように注意してください。

規則の途中のアクションは、意味値を持てます。
そのアクションは、@code{$$}への代入で値を定め、
後に続くアクションの中で、@code{$@var{n}}で値を参照できます。
アクションに記号名を対応させる方法がないので、
アクションのデータ型を宣言できません。
そこで、アクションの意味を参照するときに、
@samp{$<@dots{}>}を使ってデータ型を指定する必要があります。


規則の途中のアクションでは、@code{$$}への代入が規則の値に関係しないので、
規則全体の値を設定する方法はありません。
規則全体の値を設定する唯一の方法は、
規則の最後に置かれた通常のアクションです。

架空のコンパイラの例を示します。
ここでは、@samp{let (@var{variable}) @var{statement}}のような書式の
@code{let}文を使え、@var{statement}の持続期間中に一時的に
@var{variable}という名前の変数を作ります。
これを構文解析するために、@var{statement}を解析している間、
@var{variable}を記号表に置いておき、
後で記号表から削除する必要があります。
これを実現する方法を示します。

@example
@group
stmt:   LET '(' var ')'
                @{ $<context>$ = push_context ();
                  declare_variable ($3); @}
        stmt    @{ $$ = $6;
                  pop_context ($<context>5); @}
@end group
@end example

@samp{let (@var{variable})}が認識されるとすぐに、
最初のアクションが実行されます。
そのアクションは、現在の意味文脈、すなわち参照可能な変数の表の複製を、
データ型共用体の中の@code{context}型で、
アクションの意味値として保存します。
そして、@code{declare_variable}を呼び出して、
新しい変数を記号表に追加します。
最初のアクションが終わると、後続する@code{stmt}の解析が可能になります。
規則の途中のアクションが5番目の要素であることに注意してください。
したがって、@samp{stmt}は6番目の要素になります。

後続する文が解析されると、その意味値が@code{let}文全体の意味値になります。
そして、最初のアクションの意味値は、
変数の表を元に戻すために使われます。
そこで、@code{let}文中での一時変数が表から削除され、
構文解析されるプログラムの残りの部分では一時変数が存在しません。

構文解析器は、アクションを実行する順序を決めるために、
構文解析する必要があるので、
規則が完全に認識される前にアクションを実行することは、
しばしば不整合を起こします。
たとえば、後述の2個の規則は、規則の途中のアクションを持たないので、
実行可能な構文解析器の中で共存できます。
それは、構文解析器は開きブレーストークンをシフトでき、
宣言があるかどうか調べるために後に続くものを先読みできるからです。

@example
@group
compound: '@{' declarations statements '@}'
        | '@{' statements '@}'
        ;
@end group
@end example

しかし、次の例のように、規則の途中のアクションを加えると、
この規則は働かなくなります。

@example
@group
compound: @{ prepare_for_local_variables (); @}
          '@{' declarations statements '@}'
@end group
@group
        | '@{' statements '@}'
        ;
@end group
@end example

ここでは、開きブレースを見つけた時点で、
規則の途中のアクションを実行する必要があるかどうかの決定を迫られます。
言い換えれば、正しく判断するための十分な情報なしに、
ある規則か別の規則のどちらかにゆだねる必要があります。
開きブレーストークンは、これを読んだ時点では構文解析器が
何をすべきか決定する途中なので、@dfn{先読み(look-ahead)}トークンと
呼ばれます。@xref{Look-Ahead, ,Look-Ahead Tokens}。

次のように同一のアクションを置くことで、
この問題を解決できるように思えるかもしれません。

@example
@group
compound: @{ prepare_for_local_variables (); @}
          '@{' declarations statements '@}'
        | @{ prepare_for_local_variables (); @}
          '@{' statements '@}'
        ;
@end group
@end example

しかし、Bisonには2つのアクションが同一であるかどうかわからないので、
問題は解決しません。
Bisonは、アクションの中のCで書かれたプログラムを、
決して解釈しようとしません。

C言語のように、最初のトークンによって文と宣言を区別できるような
文法ならば、実現可能な解決方法の1つは、次の例のように、
開きブレースの後にアクションを置くことです。

@example
@group
compound: '@{' @{ prepare_for_local_variables (); @}
          declarations statements '@}'
        | '@{' statements '@}'
        ;
@end group
@end example

これで、続く宣言または文の最初のトークンによって、
Bisonがどちらの規則を使うべきかわかります。

別の解決方法は、サブルーチンとして働く非終端記号の内側に、
アクションを埋め込むことです。

@example
@group
subroutine: /* 空 */
          @{ prepare_for_local_variables (); @}
        ;

@end group

@group
compound: subroutine
          '@{' declarations statements '@}'
        | subroutine
          '@{' statements '@}'
        ;
@end group
@end example

これで、Bisonは@code{compound}に対してどちらの規則を使うべきか決めずに、
@code{subroutine}に対する規則中のアクションを実行できます。
任意の規則中のアクションは、この方法によって、
規則の最後のアクションに変換できます。
実際に、Bisonの内部では、このようにして、
規則中のアクションという機能が実現されています。


@node Declarations, Multiple Parsers, Semantics, Grammar File
@section Bison宣言
@cindex declarations, Bison
@cindex Bison declarations
@cindex 宣言, Bison
@cindex Bison宣言

Bison文法ファイルの@dfn{Bison宣言(Bison declarations)}部では、
文法の定式化に使う記号を定義し、意味値のデータ型を定義します。
@xref{Symbols}。

@code{'+'}や@code{'*'}のような1文字リテラルトークンを除く
すべてのトークンの型名を宣言する必要があります。
非終端記号については、その意味値に対してどのデータ型を使うか
指定したければ、宣言する必要があります
(@pxref{Multiple Types, ,More Than One Value Type})。

特に指定しないと、文法ファイル中の最初の規則は、
開始記号を特定します。
他の記号を開始記号にしたければ、明示的に宣言する必要があります
(@pxref{Language and Grammar, ,Languages and Context-Free Grammars})。

@menu
* Token Decl::        終端記号を宣言する.
* Precedence Decl::   優先順位と結合規則とともに終端を宣言する.
* Union Decl::        全ての意味値の型の集合を宣言する.
* Type Decl::         非終端記号のための型の選択を宣言する.
* Expect Decl::       シフト/還元衝突の警告を抑制する.
* Start Decl::        開始記号を指定する.
* Pure Decl::         再入構文解析器を要求する.
* Decl Summary::      全てのBison宣言の表.
@end menu


@node Token Decl, Precedence Decl,  , Declarations
@subsection トークン型名
@cindex declaring token type names
@cindex token type names, declaring
@cindex declaring literal string tokens
@findex %token
@cindex トークン型名の宣言
@cindex トークン型名, 宣言
@cindex リテラル文字列トークンの宣言

トークン型名、すなわち終端記号を、基本的には次のように宣言します。

@example
%token @var{name}
@end example

Bisonは、これを、構文解析器の中の@code{#define}ディレクティブに変換します。
したがって、関数@code{yylex}が構文解析器ファイルの中にあれば、
そこで名前@var{name}をこのトークン型を表すために使えます。

優先順位を指定したければ、@code{%token}の代わりに、
@code{%left}、@code{%right}、@code{%nonassoc}のどれかを使います。
@xref{Precedence Decl, ,Operator Precedence}。

トークンの名前の直後に整数値を書くことで、
そのトークン型に対応する数値符号を明示的に指定できます。

@example
%token NUM 300
@end example

しかし、Bisonにすべてのトークン型に対する数値符号の割り当てをまかせる
ことがいちばんです。Bisonは、トークン型どうしやASCII文字符号と
衝突が起きないように、自動的に数値符号を割り当てます。

スタック型が共用体である場合には、
@code{%token}あるいは他のトークン宣言に、
小なり記号と大なり記号で区切った型名を追加する必要があります
(@pxref{Multiple Types, ,More Than One Value Type})。

例を示します。

@example
@group
%union @{              /* スタックのデータ型を定義する */
  double val;
  symrec *tptr;
@}
%token <val> NUM      /* トークン「NUM」とその型を定義する */
@end group
@end example

トークン型名を宣言する@code{%token}宣言の末尾に
リテラル文字列を書くことで、リテラル文字列トークンと
トークン型名を関連づけできます。

@example
%token arrow "=>"
@end example

C言語に対する文法では、次の例のように、
等価なリテラル文字列トークンに名前を指定しています。

@example
%token  <operator>  OR      "||"
%token  <operator>  LE 134  "<="
%left  OR  "<="
@end example

リテラル文字列とトークン名を等価にすれば、それ以降の文法規則の
宣言の中で、両者を同様に使えます。
@code{yylex}関数は、トークン型の数値符号を得るために、
トークン名とリテラル文字列の両方を使えます
(@pxref{Calling Convention})。


@node Precedence Decl, Union Decl, Token Decl, Declarations
@subsection 演算子の優先順位
@cindex precedence declarations
@cindex declaring operator precedence
@cindex operator precedence, declaring
@cindex 優先順位宣言
@cindex 宣言, 演算子の優先順位
@cindex 演算子の優先順位

トークンの宣言とトークンの優先順位および結合規則の指定をまとめて行いたいならば、
@code{%left}、@code{%right}、@code{%nonassoc}のどれかを使います。
これらは、@dfn{優先順位宣言(precedence declarations)}と呼ばれます。
演算子の優先順位の詳細については、
@xref{Precedence, ,Operator Precedence}。

優先順位宣言の構文は、@code{%token}を使う宣言の構文と同じです。

@example
%left @var{symbols}@dots{}
@end example

次のようにも書けます。

@example
%left <@var{type}> @var{symbols}@dots{}
@end example

これらの宣言は、@code{%token}を使う宣言が目的とする
すべての機能を持っています。
それに加えて、次のように結合性と、すべての@var{symbols}についての優先順位を指定します。

@itemize @bullet
@item
演算子@var{op}の結合性は、この演算子が繰り返し使われた場合の
動作を指定します。つまり、@samp{@var{x} @var{op} @var{y} @var{op} @var{z}}が
構文解析された場合に、最初に@var{x}と@var{y}がグループ化されるか、
それとも@var{y}と@var{z}がグループ化されるかを指定します。
@code{%left}は、左結合性、つまり@var{x}と@var{y}が先に結合されることを
指定します。@code{%right}は、右結合性、つまり、
@var{y}と@var{z}が先に結合されることを指定します。
@code{%nonassoc}は、無結合性を指定し、その場合、
@samp{@var{x} @var{op} @var{y} @var{op} @var{z}}は
構文エラーとみなされます。

@item
演算子の優先順位は、その演算子が他の演算子とともに使われた場合の
動作を指定します。同一の優先順位宣言で宣言されたすべてのトークンは、
同じ優先順位を持ち、その結合性にしたがって処理されます。
2個のトークンが別々の優先順位宣言で宣言されているならば、
文法ファイルの中で後で宣言されたほうの演算子が強い優先順位を持ちます。

@end itemize


@node Union Decl, Type Decl, Precedence Decl, Declarations
@subsection 値型の集合
@cindex declaring value types
@cindex value types, declaring
@findex %union
@cindex 値型の宣言
@cindex 宣言, 値型

@code{%union}宣言は、意味値に対して可能なデータ型すべての集合を指定します。
キーワード@code{%union}に続いて、C言語における共用体の宣言と同様に、
ブレースで囲んだ宣言の並びを書きます。

例を示します。

@example
@group
%union @{
  double val;
  symrec *tptr;
@}
@end group
@end example

これは、2つの選択可能な型@code{double}と@code{symrec *}があると、
宣言しています。
それぞれの型には、名前@code{val}と@code{tptr}が与えられています。
これらの名前は、@code{%token}と@code{type}宣言の中で、
終端記号あるいは非終端記号に対する型を選ぶために使えます
(@pxref{Type Decl, ,Nonterminal Symbols})。

C言語での共用体宣言とは異なり、閉じブレースの後にセミコロンを
@emph{書いてはいけない}ことに注意してください。


@node Type Decl, Expect Decl, Union Decl, Declarations
@subsection 非終端記号
@cindex declaring value types, nonterminals
@cindex value types, nonterminals, declaring
@findex %type
@cindex 値型の宣言, 非終端記号
@cindex 宣言, 非終端記号の値型
@cindex 非終端記号, 値型の宣言

@code{%union}を複数の値型を指定するために使うならば、
値を持つ各非終端記号の値型を宣言する必要があります。
そのためには、次のように@code{%type}宣言を使います。

@example
%type <@var{type}> @var{nonterminal}@dots{}
@end example

ここで、@var{nonterminal}は非終端記号の名前で、
@var{type}は@code{%union}で指定した名前の中からあなたが選んだものです
(@pxref{Union Decl, ,The Collection of Value Types})。
同じ値型を持つ任意の数の非終端記号を、
1つの@code{%type}宣言の中に記述できます。
その場合、記号名を空白で区切ってください。

同様に終端記号の値型の宣言も可能です。
そのためには、終端記号の宣言の中で、同じ@code{<@var{type}>}の
書式を使います。
すべてのトークン宣言で、@code{<@var{type}>}が許可されています。


@node Expect Decl, Start Decl, Type Decl, Declarations
@subsection 衝突警告の回避
@cindex suppressing conflict warnings
@cindex preventing warnings about conflicts
@cindex warnings, preventing
@cindex conflicts, suppressing warnings of
@findex %expect
@cindex 衝突警告の回避
@cindex 回避, 衝突警告
@cindex 警告, 衝突
@cindex 衝突, 警告の回避

文法の中に衝突(@pxref{Shift/Reduce, ,Shift/Reduce Conflicts})があると、
Bisonは通常警告を表示します。
しかし、実際の文法のほとんどは、無害なシフト還元衝突を含み、
その衝突は、予測可能な方法で回避できますが、除去は困難です。
衝突の数が変わらないかぎり、このような衝突の警告は
抑制させるべきです。
そのために、@code{%expect}宣言を使います。

次のように宣言します。

@example
%expect @var{n}
@end example

ここで、@var{n}は10進の整数です。
この宣言によって、@var{n}個のシフト還元衝突があって、
還元/還元衝突がなければ、警告が表示されません。
シフト還元衝突の数が@var{n}でなかったり、
1つでも還元/還元衝突があった場合は、通常の警告が表示されます。

一般に、次のような手順で@code{%expect}を使います。

@itemize @bullet
@item
@code{%expect}なしで文法ファイルをコンパイルします。
衝突が起こる位置の詳細な目録を得るために、@samp{-v}オプションを指定します。
Bisonは、衝突の数も表示します。

@item
衝突のそれぞれについて、Bisonの省略時の解決方法が、
あなたの望みどおりであるか、確かめます。
もし不都合があれば、文法ファイルを書き直して、最初に戻ります。

@item
Bisonが表示した衝突の数@var{n}を書き写して、
@code{%expect}宣言を追加します。

@end itemize

すると、Bisonはチェックした衝突について文句をいわなくなりますが、
文法ファイルを書き換えて衝突の数が変わると、
再び警告を表示します。


@node Start Decl, Pure Decl, Expect Decl, Declarations
@subsection 開始記号
@cindex declaring the start symbol
@cindex start symbol, declaring
@cindex default start symbol
@findex %start
@cindex 開始記号の宣言
@cindex 宣言, 開始記号
@cindex 省略時開始記号

Bisonは、文法定義部にある最初の非終端記号を、
省略時の開始記号と仮定します。
次のような@code{%start}宣言で、明示的に開始記号を指定できます。

@example
%start @var{symbol}
@end example


@node Pure Decl, Decl Summary, Start Decl, Declarations
@subsection 純粋(再入可能)構文解析器
@cindex reentrant parser
@cindex pure parser
@findex %pure_parser
@cindex 再入可能構文解析器
@cindex 純粋構文解析器

@dfn{再入可能(reentrant)}プログラムとは、進路を変えないプログラム、
いいかえれば、完全に@dfn{純粋な(pure)}(読み出し専用)コードからなる
プログラムです。
@footnote{【訳注】ある手続きの終了を待たずに、その手続きを再度呼び出せる
ことでもあります。}
再入可能性は、非同期実行が可能な場合に重要です。
たとえば、再入可能でないプログラムを、
シグナルハンドラから呼び出すことは危険です。マルチスレッド制御システムでは、
再入不能プログラムはインターロックからしか呼び出せません。

通常は、Bisonは再入可能でない構文解析器を生成します。
これはほとんどの使用に合い、YACCとの互換性も保ちます。
(標準のYACCインターフェースは継続的に非再入可能であります。
というのは、@code{yylex}、@code{yylval} や @code{yylloc} との通信に
静的に確保された変数
@footnote{【訳注】他のソースファイルから見えないとう意味ではなく、
メモリ上の固定番地に置かれるという意味。}
を使うからです。

代わりに、純粋な、再入可能な構文解析器を生成することができます。
次のような@code{%pure_parser} Bison宣言は、
再入可能な構文解析器を生成します。

@example
%pure_parser
@end example

この宣言によって、上記の2個の通信用変数@code{yylval}と@code{yylloc}が、
@code{yyparse}の局所変数になり、
@code{yylex}字句解析関数を呼び出す方法が変わります。
詳細については、@xref{Pure Calling, ,Calling Conventions for Pure Parsers}。
@code{yyparse}の中の@code{yynerrs}変数も局所変数になります
(@pxref{Error Reporting, ,The Error Reporting Function @code{yyerror}})。
@code{yypase}関数自体を呼び出す方法は変わりません。

解析器が純粋かどうかは文法規則には全く関係しません。
全ての有効な文法から、純粋な解析器と非再入可能な解析器の
どちらかを生成するこができます。

@node Decl Summary,  , Pure Decl, Declarations
@subsection Bison宣言の要約
@cindex Bison declaration summary
@cindex declaration summary
@cindex summary, Bison declaration
@cindex Bison宣言の要約
@cindex 宣言の要約
@cindex 要約, Bison宣言

Bison宣言の要約を示します。

@table @code
@item %union
意味値が持ちうるデータ型の集合を宣言します
(@pxref{Union Decl, ,The Collection of Value Types})。

@item %token
優先順位と結合性を指定せずに、終端記号(トークン型名)を宣言します
(@pxref{Token Decl, ,Token Type Names})。

@item %right
右結合的な終端記号(トークン型名)を宣言します
(@pxref{Precedence Decl, ,Operator Precedence})。

@item %left
左結合的な終端記号(トークン型名)を宣言します
(@pxref{Precedence Decl, ,Operator Precedence})。

@item %nonassoc
結合性がない、つまり、結合して使おうとすると構文エラーになる、
終端記号(トークン型名)を宣言します
(@pxref{Precedence Decl, ,Operator Precedence})。

@item %type
非終端記号に対する意味値の型を宣言します
(@pxref{Type Decl, ,Nonterminal Symbols})。

@item %start
文法の開始記号を宣言します
(@pxref{Start Decl, ,The Start-Symbol})。

@item %expect
予想されるシフト還元衝突の数を宣言します
(@pxref{Expect Decl, ,Suppressing Conflict Warnings})。

@item %pure_parser
純粋な(再入可能な)構文解析器を生成します
(@pxref{Pure Decl, ,A Pure (Reentrant) Parser})。

@item %no_lines
構文解析器ファイルに、@code{#line}プリプロセッサディレクティブを生成しません。
Bisonは、通常、Cコンパイラとデバッガがエラーとあなたのソースファイル
(文法ファイル)を関連づけられるように、構文解析器ファイルに
@code{#line}ディレクティブを書き込みます。
@code{%no_lines}宣言は、エラーを構文解析器ファイルの行数と関連づけ、
構文解析器ファイルをそれ自身で独立したソースファイルと
みなすことを意味します。

@item %raw
通常、出力ファイル@file{@var{name}.h}は、
Yacc互換トークン番号を定義します。
このオプションが指定されると、代わりに、Bison内部の番号が使われます
(Yacc互換番号は、1文字リテラルトークンを除いて、257から始まりますが、
Bison内部のトークン番号は常に3から始まる連番になります)。

@item %token_table
構文解析器ファイルの中に、トークン名の表を生成します。
その表の名前は@code{yytname}で、@code{yytname[@var{i}]}が
Bison内部トークン番号@var{i}のトークンの名前です。
最初の3個の要素は常に、@code{"$"}、@code{"error"}、@code{"$illegal"}で、
この後に文法ファイルで定義された記号が続きます。

表の中で、1文字リテラルトークンにはシングルクォート記号が、
文字列リテラルトークンにはダブルクォート記号が含まれます。
たとえば、@code{"'+'"}は1文字リテラルトークンで、
@code{"\"<=\""}は文字列リテラルトークンです。
文字列リテラルトークンのすべての文字はそのまま表に現れ、
ダブルクォート記号もエスケープされません。
たとえば、トークンが3文字@samp{*"*}からなれば、
@code{yytname}中の文字列は@samp{"*"*"}となります
(Cでは@code{"\"*\"*\""}と書きます)。

@code{%token_table}を指定すると、Bisonは、マクロ
@code{YYNTOKENS}、@code{YYNNTS}、@code{YYNRULES}、@code{YYNSTATES}の
定義も生成します。

@table @code
@item YYNTOKENS
最大のトークン番号+1。
@item YYNNTS
非終端記号の数。
@item YYNRULES
文法規則の数。
@item YYNSTATES
構文解析器の状態の数(@pxref{Parser States})。
@end table
@end table


@node Multiple Parsers,, Declarations, Grammar File
@section 同一プログラム中の複数の構文解析器

Bisonを使うプログラムのほとんどは、言語を1つだけ構文解析し、
したがって、Bison構文解析器を1つだけ含みます。
しかし、1つのプログラムで2種類以上の言語を構文解析したいときは、
どうすればよいでしょうか? そうするためには、@code{yyparse}、@code{yylval}
などの2重定義の衝突を防ぐ必要があります。

これを容易にする方法が、オプション@samp{-p @var{prefix}}の利用です
(@pxref{Invocation, ,Invoking Bison})。
これによって、Bison構文解析器のインターフェイス関数と変数の名前が、
@samp{yy}で始まる代わりに@var{prefix}で始まります。
これでそれぞれの構文解析器に、衝突しないような異なる名前を与えられます。

変更される名前は、
@code{yyparse}、@code{yylex}、@code{yyerror}、@code{yynerrs}、
@code{yylval}、@code{yychar}、@code{yydebug}で全部です。
たとえば、@samp{-p c}オプションを使えば、これらの名前は、
@code{cparse}、@code{clex}などに変わります。

@strong{Bisonに関連する上記以外の変数とマクロのすべての
名前は変わりません。}これらは、広域ではないので、
異なる構文解析器で同じ名前が使われても衝突しません。
たとえば、@code{YYSTYPE}の名前は変わりませんが、
この定義は構文解析器ごとに異なる方法で行われるので、問題ありません
(@pxref{Value Type, ,Data Types of Semantic Values})。

@samp{-p}オプションは、さらに、構文解析器ソースファイルの始めで、
@code{yyparse}を@code{@var{prefix}parse}と定義するように、
マクロを定義します。
この結果、構文解析器ソースファイル全体で、ある名前を別の名前に変えます。


@node Interface, Algorithm, Grammar File, Top
@chapter 構文解析器のC言語インターフェイス
@cindex C-language interface
@cindex interface
@cindex C言語インターフェイス
@cindex インターフェイス

Bison構文解析器の正体は、@code{yyparse}という名前のCの関数です。
ここでは、@code{yyparse}とほかに使う必要がある関数の間の
インターフェイスの方法を示します。

構文解析器の内部では、多くの@samp{yy}または@samp{YY}で始まるCの識別子が
使われていることに注意してください。
本書で説明しているものを除いて、そのような識別子を
文法ファイルのアクションや追加のCプログラムの中で使うと、
問題が起きるでしょう。

@menu
* Parser Function::   @code{yyparse}の呼び方と、それが返すもの.
* Lexical::           トークンを読み込む関数@code{yylex}を提供しなければ
                        ならない.
* Error Reporting::   関数@code{yyerror}を提供しなければならない.
* Action Features::   アクションで使える特別な機能.
@end menu


@node Parser Function, Lexical,  , Interface
@section 構文解析器関数@code{yyparse}
@findex yyparse

構文解析を始めるには、関数@code{yyparse}を呼び出します。
この関数は、トークンを読み、アクションを実行し、最後には入力ファイルの
終わりに達するか回復不可能な構文エラーに達して、戻ります。
読み込みを打ち切って@code{yyparse}関数から戻るような
アクションを書くことも可能です。

構文解析が成功する、つまり入力ファイルの終わりに達すると、
@code{yyparse}からの戻り値が0になります。

構文解析が失敗する、つまり構文エラーが発生すると、
戻り値が1になります。

アクションの中で、次のマクロを使って、
@code{yyparse}からただちに戻れます。

@table @code
@item YYACCEPT
@findex YYACCEPT
成功の印である戻り値0をともなって、ただちに戻ります。

@item YYABORT
@findex YYABORT
失敗の印である戻り値1をともなって、ただちに戻ります。

@end table


@node Lexical, Error Reporting, Parser Function, Interface
@section 字句解析器関数@code{yylex}
@findex yylex
@cindex lexical analyzer
@cindex 字句解析器

@dfn{字句解析器(lexical analyzer)}関数@code{yylex}は、
入力からトークンを認識し、構文解析器に返します。
Bisonはこの関数を自動的に生成しないので、
@code{yyparse}から呼び出されるように@code{yylex}を書く必要があります。
関数@code{yylex}は``lexical scanner''と呼ばれることもあります。

単純なプログラムでは、よく文法ファイルの最後で@code{yylex}を
定義します。@code{yylex}が別のソースファイルの中で定義する場合は、
そこでトークン型マクロ定義を使えるように準備する必要があります。
そのためには、@samp{-d}オプションを指定してBisonを実行してください。
すると、マクロ定義がヘッダファイル@file{@var{name}.tab.h}に
書き込まれ、それを必要とするソースファイルにインクルードできます。
@xref{Invocation, ,Invoking Bison}。

@menu
* Calling Convention::  @code{yyparse}が@code{yylex}を呼ぶ方法.
* Token Values::      @code{yylex}がどのように読み込んだトークンの
                        意味値を返さなければならないか.
* Token Positions::   アクションが望むときに、どのように@code{yylex}が
                        テキストの位置(行数など)を返さなければならない
                        か。
* Pure Calling::      純粋な構文解析器で呼び出し型の習慣がどのように
                        違うか (@pxref{Pure Decl, ,A Pure (Reentrant) Parser}).
@end menu


@node Calling Convention, Token Values,  , Lexical
@subsection @code{yylex}を呼び出す方法

@code{yylex}が返す値は、見つかったトークンの型に対する番号で、
入力ファイルの終わりに達した場合には0を返します。

トークンが文法規則の中で名前で参照される場合、
構文解析器ファイルの中でのその名前は、
トークン型に対する適切な番号にCのマクロとして定義されます。
したがって、@code{yylex}は型を示すためにその名前を使用できます。
@xref{Symbols}。

文法規則の中でトークンが1文字リテラルとして参照される場合には、
その文字の文字符号がトークン型に対する番号でもあります。
そこで、@code{yylex}は、単純に文字符号を返します。
しかし、戻り値0は入力ファイルの終わりを意味するので、
ヌル文字(@code{'\0'})の文字符号を返してはいけません。

以下に例を示します。

@example
yylex ()
@{
  @dots{}
  if (c == EOF)     /* ファイルの終わりか調べる。 */
    return 0;
  @dots{}
  if (c == '+' || c == '-')
    return c;      /* `+' に対するトークン型が '+' であると仮定する。 */
  @dots{}
  return INT;      /* トークン型を返す。 */
  @dots{}
@}
@end example

このようなインターフェイスは、
@code{lex}が生成した字句解析器を、
@code{yylex}の定義を変えずに使えるように設計されています。

文法規則が文字列リテラルトークンを使っている場合には、
@code{yylex}がそれに対するトークン型番号を使う、
2つの方法があります。

@itemize @bullet
@item
文法が文字列リテラルトークンに対する別名として記号トークン名を
定義しているならば、@code{yylex}はその記号名を他のトークンの記号名と
同様に使えます。この場合、文法ファイルの中での文字列リテラルトークンの
利用は、@code{yylex}にまったく影響しません。

@item
@code{yylex}は、@code{yytname}表の中で、
複数文字トークンを見つけられます。
トークンに対する表の添え字は、そのトークン型の番号です。
複数文字トークンは@code{yytname}の中にダブルクォート記号で囲まれて
記憶されます。
トークンに含まれる文字はエスケープされず、
表の中の文字列にそのまま書き込まれています。

トークンを構成する文字列が@code{token_buffer}に記憶されていると仮定して、
@code{yytname}からトークンを探し出すプログラムを示します。

@smallexample
for (i = 0; i < YYNTOKENS; i++)
  @{
    if (yytname[i] != 0
        && yytname[i][0] == '"'
        && strncmp (yytname[i] + 1, token_buffer,
                    strlen (token_buffer))
        && yytname[i][strlen (token_buffer) + 1] == '"'
        && yytname[i][strlen (token_buffer) + 2] == 0)
      break;
  @}
@end smallexample

@code{yytname}表は、@code{%token_table}宣言をした場合にのみ生成されます。
@xref{Decl Summary}。

@end itemize


@node Token Values, Token Positions, Calling Convention, Lexical
@subsection トークンの意味値

@vindex yylval
通常の再入可能でない構文解析器では、
トークンの意味値が広域変数@code{yylval}に代入される必要があります。
意味値に対してただ1つのデータ型を使っている場合には、
@code{yylval}の型もそうです。
したがって、たとえば、宣言を省略して型が@code{int}ならば、
次のように書けます。

@example
@group
  @dots{}
  yylval = value;  /* 値をBisonスタックに積む。 */
  return INT;      /* トークン型を返す。 */
  @dots{}
@end group
@end example

複数のデータ型を使っている場合には、
@code{%union}宣言で作られた共用体が@code{yylval}の型になります
(@pxref{Union Decl, ,The Collection of Value Types})。
そこで、トークンの値を代入するには、
共用体のメンバの名前を指定する必要があります。
@code{%union}宣言の例を示します。

@example
@group
%union @{
  int intval;
  double val;
  symrec *tptr;
@}
@end group
@end example

すると、@code{yylex}の中のプログラムは次のようになります。

@example
@group
  @dots{}
  yylval.intval = value; /* 値をBisonスタックに積む。 */
  return INT;          /* トークン型を返す。 */
  @dots{}
@end group
@end example


@node Token Positions, Pure Calling, Token Values, Lexical
@subsection トークンのテキスト中の位置

@vindex yylloc
アクションの中で@samp{@@@var{n}}機能
(@pxref{Action Features, ,Special Features for Use in Actions})を
使っている場合には、トークンとグループのテキスト中の位置を
見失わないように、@code{yylex}の中で位置情報を提供する必要があります。
関数@code{yyparse}は、ちょうど解析されたトークンのテキスト中の位置が、
広域変数@code{yylloc}に記憶されていると仮定します。
そこで、@code{yylex}は、@code{yyloc}に正しいデータを記憶する必要があります。
変数@code{yylloc}は構造体で、アクションの中で使われる場合にのみ、
メンバを初期化する必要があります。
メンバは、@code{first_line}、@code{first_column}、
@code{last_line}、@code{last_column}の4つです。
この機能を使うと、構文解析器が著しく遅くなることに注意してください。

@tindex YYLTYPE
@code{yylloc}のデータ型は、@code{YYLTYPE}という名前を持っています。


@node Pure Calling,  , Token Positions, Lexical
@subsection 再入可能構文解析器を呼び出す方法

純粋な、つまり再入可能な、構文解析器を生成するために、
@code{%pure_parser}をBison宣言すると、広域変数@code{yylval}と
@code{yylloc}を使えなくなります
(@pxref{Pure Decl, ,A Pure (Reentrant) Parser})。
このような構文解析器では、2つの広域変数の代わりに、
@code{yylex}への引数として渡されるポインタを使います。
@code{yylex}を次のように宣言し、
これらのポインタを通して情報を受け渡しする必要があります。

@example
yylex (lvalp, llocp)
     YYSTYPE *lvalp;
     YYLTYPE *llocp;
@{
  @dots{}
  *lvalp = value;  /* 値をBisonスタックに積む。  */
  return INT;      /* トークン型を返す。 */
  @dots{}
@}
@end example

文法ファイルがテキスト中の位置を参照するための@samp{@@}機能を
使っていない場合は、@code{YYLTYPE}は定義されません。
この場合、第2引数を省略し、@code{yylex}は
1個の引数をともなって呼び出されます。

@vindex YYPARSE_PARAM
再入可能な構文解析器を使っている場合、
再入可能な方法で構文解析器に追加の引数を渡す方法があります。
そのためには、マクロ@code{YYPARSE_PARAM}を変数名として定義します。
すると、関数@code{yyparse}は、定義された名前で、型が@code{void *}の
追加の引数を受け取ります。

@code{yyparse}を呼び出すときに、オブジェクトの番地を
@code{void *}型にキャストして渡します。
文法のアクションは、ポインタを適切な型へのポインタへキャストし、
逆参照して、オブジェクトの内容を参照できます。
例を示します。

@example
%@{
struct parser_control
@{
  int nastiness;
  int randomness;
@};

#define YYPARSE_PARAM parm
%@}
@end example

次のように構文解析器を呼び出します。

@example
struct parser_control
@{
  int nastiness;
  int randomness;
@};

@dots{}

@{
  struct parser_control foo;
  @dots{}  /* @r{@code{foo}に正しいデータを記憶}  */
  value = yyparse ((void *) &foo);
  @dots{}
@}
@end example

文法アクションの中では、データを参照するために次のような式を使います。

@example
((struct parser_control *) parm)->randomness
@end example

@vindex YYLEX_PARAM
@code{yylex}に追加の引数を渡したい場合には、
@code{YYPARSE_PARAM}と同様に、マクロ@code{YYLEX_PARAM}を定義します。
例を示します。

@example
%@{
struct parser_control
@{
  int nastiness;
  int randomness;
@};

#define YYPARSE_PARAM parm
#define YYLEX_PARAM parm
%@}
@end example

そして、@code{yylex}が追加の引数、@code{parm}の値を受け取るように、
@code{yylex}を定義する必要があります
(型@code{YYLTYPE}のどの引数が渡されるかに応じて、
引数の合計が2個または3個になります)。
引数を正しいオブジェクト型として宣言できます。すなわち@code{void *}として
宣言し、上記の番地を参照できます。

@code{YYPARSE_PARAM}を使わずに、@samp{%pure_parser}を使って、
再入可能な構文解析器を生成することも可能です。
その場合、引数をつけずに@code{yyparse}を呼び出すべきです。


@node Error Reporting, Action Features, Lexical, Interface
@section エラー報告関数@code{yyerror}
@cindex error reporting function
@findex yyerror
@cindex parse error
@cindex syntax error
@cindex エラー報告関数
@cindex 構文解析エラー
@cindex 文法エラー

Bison構文解析器は、文法規則に適合しないトークンを読むたびに、
@dfn{構文解析エラー(parse error)}すなわち@dfn{文法エラー(syntax error)}を
検出します。文法中のアクションは、マクロ@code{YYERROR}を使って、
明示的にエラーを示せます
(@pxref{Action Features, ,Special Features for Use in Actions})。

Bison構文解析器は、@code{yyerror}という名前の関数を使って、
エラーを報告するようになっています。
事前に用意が必要な
この関数は、文法エラーが発生するたびに、1個の引数をともなって、
@code{yyparse}から呼び出されます。
構文解析エラーに対して、引数の文字列は通常@w{@code{"parse error"}}です。

@findex YYERROR_VERBOSE
Bison定義部(@pxref{Bison Declarations, ,The Bison Declarations Section})で、
マクロ@code{YYERROR_VERBOSE}を定義すると、
@w{@code{"parse error"}}の代わりに、
エラーを詳細に報告する文字列が用意されます。
マクロ@code{YYERROR_VERBOSE}の定義はなんでもかまいません。

構文解析器は、もう1種類のエラーであるスタックオーバーフローを検出する
可能性があります。これは、入力がきわめて深い入れ子からなっていると
起こることがあります。Bison構文解析器は自動的にスタックの限界を大きく拡張し
ているので、スタックオーバーフローはめったに起きません。
しかし、もしスタックオーバーフローが起きれば、
@w{@code{"parser stack overflow"}}という
文字列の引数をともなって、@code{yyerror}が呼び出されます。

単純なプログラムでは、次の例のように@code{yyerror}を定義できます。

@example
@group
yyerror (s)
     char *s;
@{
@end group
@group
  fprintf (stderr, "%s\n", s);
@}
@end group
@end example

@code{yyerror}から戻った後、@code{yyparse}は、
適切なエラー回復文法規則(@pxref{Error Recovery})があれば、
エラーからの回復を試みます。
もし、回復が不可能ならば、@code{yyparse}は即座に1を返します。

@vindex yynerrs
変数@code{yynerrs}には、それまでに出くわした文法エラーの数が記憶されています。
通常、この変数は広域変数です。
しかし、再入可能な構文解析器(@pxref{Pure Decl, ,A Pure (Reentrant) Parser})
を生成した場合には、アクションからのみ参照可能な局所変数になります。


@node Action Features,  , Error Reporting, Interface
@section アクション中で使える特別な機能
@cindex summary, action features
@cindex action fetures summary
@cindex 要約, アクション
@cindex アクションの要約
 
ここの表では、アクション中で有用な、Bisonの構造物、変数、
マクロを示します。

@table @samp
@item $$
現在の規則で作られるグループに対する意味値を保持する変数のように働きます。
@xref{Actions}。

@item $@var{n}
現在の規則の@var{n}番目の構成要素に対する意味値を保持する変数のように
働きます。@xref{Actions}。

@item $<@var{typealt}>$
@code{$$}に似ていますが、@code{%union}宣言で指定された共用体の中の
@var{typealt}を選びます。
@xref{Action Types, ,Data Types of Values in Actions}。

@item $<@var{typealt}>@var{n}
@code{$@var{n}}に似ていますが、@code{%union}宣言で指定された共用体の中の
@var{typealt}を選びます。
@xref{Action Types, ,Data Types of Values in Actions}。

@item YYABORT;
@code{yyparse}からただちに戻り、失敗を示します。
@xref{Parser Function, ,The Parser Function @code{yyparse}}。

@item YYACCEPT;
@code{yyparse}からただちに戻り、成功を示します。
@xref{Parser Function, ,The Parser Function @code{yyparse}}。

@item YYBACKUP (@var{token}, @var{value});
@findex YYBACKUP
トークンを逆シフトします。
1個の値を還元する規則の中で、先読みトークンがない場合にのみ、
このマクロが使えます。
このマクロは、トークン型が@var{token}で意味値が@var{value}のトークンを、
先読みトークンとして格納し、この規則で還元されるはずだった値を捨てます。

先読みトークンがすでにあるような、このマクロが無効な状況で
このマクロを使うと、メッセージ@samp{cannnot back up}をともなう
文法エラーが報告され、通常のエラー回復が行われます。

どちらの場合も、アクションの残りの部分は実行されません。

@item YYEMPTY
@vindex YYEMPTY
先読みトークンがない場合に、変数@code{yychar}に記憶されている値です。

@item YYERROR;
@findex YYERROR
ただちに文法エラーを発生させます。この文は、構文解析器がエラーを検出したように
エラー回復を始めますが、@code{yyerror}を呼び出さず、
メッセージは表示されません。
もし、エラーメッセージを表示したければ、@samp{YYERROR}文よりも先に、
明示的に@code{yyerror}を呼び出してください。
@xref{Error Recovery}。

@item YYRECOVERING
このマクロの値は、字句解析器が文法エラーからの回復中ならば1、
そうでなければ0です。
@xref{Error Recovery}。

@item yychar
現在の先読みトークンを含んでいる変数です
(再入可能構文解析器では、@code{yyparse}の局所変数です)。
先読みトークンがない場合には、この変数に
@code{YYEMPTY}という値が入っています。
@xref{Look-Ahead, ,Look-Ahead Tokens}。

@item yyclearin;
現在の先読みトークンを捨てます。エラー規則の中で有用です。
@xref{Error Recovery}。

@item yyerrok;
後に続く文法エラーに対して、エラーメッセージの生成を再開します。
これは、エラー規則で特に重要です。
@xref{Error Recovery}。

@item @@@var{n}
@findex @@@var{n}
現在の規則の第@var{n}要素の、行番号と列番号を含む、
配列変数のように働きます。
次のようなメンバがあります。

@example
struct @{
  int first_line, last_line;
  int first_column, last_column;
@};
@end example

たとえば、第3要素の開始行番号を知るには、
@samp{@@3.first_line}とします。

この構造体のメンバを有効な情報にするためには、
@code{yylex}がそれぞれのトークンに対して、
情報を提供する必要があります。
一部分のメンバだけが必要ならば、
@code{yylex}はそのメンバの値を設定するだけでかまいません。
@footnote{【訳注】@code{yylex}は、変数@code{yylloc}に、
トークンの位置情報を代入します。}

この機能を使うと、字句解析器が著しく遅くなります。
@end table


@node Algorithm, Error Recovery, Interface, Top
@chapter Bison構文解析器のアルゴリズム
@cindex Bison parser algorithm 
@cindex algorithm of parser
@cindex shifting
@cindex reduction
@cindex parser stack
@cindex stack, parser
@cindex Bison構文解析器のアルゴリズム
@cindex シフト
@cindex 還元
@cindex 構文解析器のスタック
@cindex スタック, 構文解析器

Bison構文解析器は、トークンを読むと、トークンの意味値とともにスタックに積みます。
このスタックを@dfn{構文解析器スタック(parser stack)}と呼びます。
トークンをスタックに積むことを、伝統的に
@dfn{シフト(shifting)}と呼びます。

たとえば、中間記法電卓が、@samp{1 + 5 *}をすでに読んでいて、
@samp{3}を受け取ったと仮定します。
スタックには4個の要素があり、トークンそれぞれがシフトされています。

しかし、スタックに常に読み込まれたトークンそれぞれに対する
要素があるわけではありません。
最後の@var{n}個のトークンとグループが文法規則に当てはまる場合には、
それらは規則に従って組み合わされます。
これを、@dfn{還元(reduction)}と呼びます。
スタックにあったトークンとグループは、
規則の結果、つまり左側にある記号である、1個のグループに置き換えられます。
規則のアクションの実行は、結果のグループの意味値を計算するので、
還元の手順の1つです。

たとえば、中間記法電卓の構文解析器スタックの内容は次のようになります。

@example
1 + 5 * 3
@end example

そして、入力された次のトークンが改行符号ならば、
次の規則に従って、最後の3個の要素が15に還元されます。

@example
expr: expr '*' expr;
@end example

そして、スタックは3個の要素を持ちます。

@example
1 + 15
@end example

この時点で、別の還元が可能になり、1個の値16を得ます。
そして、改行符号がシフトされます。

構文解析器は、シフトと還元によって、入力全体を
文法の開始記号である1個のグループに還元しようとします
(@pxref{Language and Grammar, ,Languages and Context-Free Grammars})。

この種類の構文解析器は、ボトムアップ構文解析器として知られています。

@menu
* Look-Ahead::        構文解析器は何をするかを決めるときに一つ先のトーク
                        ンを見る.
* Shift/Reduce::      衝突: シフトと還元の両方が有効なとき.
* Precedence::        演算子の優先順位は衝突を解決することで動作する.
* Contextual Precedence::  演算子の優先順位が文脈に依存するとき.
* Parser States::     構文解析器はスタック付きの有限状態機械.
* Reduce/Reduce::     同じ状況に2つの規則が適用可能なとき.
* Mystery Conflicts::  正しくないように見える還元/還元衝突.
* Stack Overflow::    スタックが一杯になったときに何が起こるうか. それを
                        避ける方法.
@end menu


@node Look-Ahead, Shift/Reduce,  , Algorithm
@section 先読みトークン
@cindex look-ahead token
@cindex 先読みトークン

Bison構文解析器は、必ずしも文法規則に適合する最後の@var{n}個のトークン
またはグループが見つかるとすぐに還元を行う@emph{わけではありません}。
そのような単純な方法は、多くの言語の処理に適さないからです。
その代わりに、還元が可能な場合に、構文解析器は次のトークンを
「先読み」し、次に何をするべきかを決定します。

トークンが読まれると、それはすぐにシフトされるのではなく、
まず、@dfn{先読みトークン(look-ahead token)}になり、
スタックには置かれません。
先読みトークンを残したまま、構文解析器が、スタック上のトークンまたは
グループに対して1個以上の還元を実行します。
それ以上の還元が起こりえない場合に、
先読みトークンはスタックにシフトされます。
これは、すべての可能な還元が実行されたことを意味しません。
先読みトークンのトークン型に応じて、
いくつかの規則は適用を遅らされているかもしれません。

先読みが必要な簡単な例を示します。
下記の3個の規則は、2項加算演算子、単項階乗演算子(@samp{!})、
グループのためのかっこを含みます。

@example
@group
expr:     term '+' expr
        | term
        ;
@end group

@group
term:     '(' expr ')'
        | term '!'
        | NUMBER
        ;
@end group
@end example

トークン@w{@samp{1 + 2}}が読み込まれてシフトされているときに、
何が起きるでしょうか。もし、続くトークンが@samp{)}ならば、
最初の3個のトークンは@code{expr}の形式に還元される必要があります。
これが、唯一有効な道です。
なぜならば、@samp{)}をシフトして、@w{@code{term ')'}}という記号列も
生成可能ですが、どの規則もそのような記号列を許していないからです。

もし、続くトークンが@samp{!}ならば、それはただちにシフトされる必要があり、
@w{@samp{2 !}}から@code{term}が還元されます。
そうではなく、構文解析器がシフトの前に還元していれば、
@w{@samp{1 + 2}}が@code{expr}に還元されます。
しかし、そのような還元をしようとすると@code{expr '!'}という記号列を
スタックに生成しようとするので、@samp{!}をシフトするのは不可能です。
そのような記号列は許されません。

@vindex yychar
現在の先読みトークンは、変数@code{yychar}に記憶されています
@xref{Action Features, ,Special Features for Use in Actions}。


@node Shift/Reduce, Precedence, Look-Ahead, Algorithm
@section シフト還元衝突
@cindex conflicts
@cindex shift/reduce conflicts
@cindex dangling else
@cindex else, dangling
@cindex 衝突
@cindex シフト還元衝突
@cindex ぶらさがりelse
@cindex else, ぶらさがり

次の2個の規則で定められる、``if-then''と``if-then-else''文を持つ
言語の構文解析について考えます。

@example
@group
if_stmt:
          IF expr THEN stmt
        | IF expr THEN stmt ELSE stmt
        ;
@end group
@end example

ここで、@code{IF}、@code{THEN}、@code{ELSE}は、
キーワードトークンを表す終端記号であると仮定します。

@code{ELSE}トークンが読まれて先読みトークンになったときに、
入力が正しいと仮定して、スタックの内容はちょうど
最初の規則で還元される右辺になっています。
しかし、いずれ起こるはずの第2の規則の還元のために、
@code{ELSE}トークンをシフトすることも有効です。

この、シフトと還元の両方が有効な場合を、
@dfn{シフト還元衝突(shift/reduce conflict)}と呼びます。
Bisonは、演算子優先規則宣言で特に指定されていないかぎり、
シフトを選ぶことで衝突を解決するように設計されています。
この理由を理解するために、別の選択肢と比較してみましょう。

構文解析器は@code{ELSE}のシフトを選ぶので、その結果、
else節はもっとも内側のif文に対応し、次の2つの入力は等価になります。

@example
if x then if y then win (); else lose;

if x then do; if y then win (); else lose; end;
@end example

しかし、字句解析器がシフトでなく還元を選ぶと、その結果、
else節がもっとも外側のif文に対応し、次の2つの入力は等価になります。

@example
if x then if y then win (); else lose;

if x then do; if y then win (); end; else lose;
@end example

文法があいまいに書かれているために、衝突が起きます。
つまり、入れ子になったif文について、どちらの構文解析結果も正当なのです。
確立された習慣では、else節をもっとも内側のif文に対応させて、
あいまいさを解決しています。
これが、Bisonが還元よりもシフトを選ぶ理由です
(理想的には、あいまいでない文法を書くべきですが、この場合には困難です)。
この問題は、Algol 60の仕様の中に現れたのが最初で、
「ぶらさがり@code{else}(dangling @code{else})」問題と呼ばれています。

予測可能で正当なシフト還元衝突について、Bisonが警告を表示しないように、
@code{%expect @var{n}}宣言を使えます。
すると、ちょうど@var{n}個のシフト還元衝突があるかぎり、
警告は表示されません。
@xref{Expect Decl, ,Suppressing Conflict Warnings}。

上記の@code{if_stmt}の定義は、衝突をわざと発生させるために書きましたが、
追加の規則がなければ実際には衝突が起きません。
次に、実際に衝突を含む完全なBison入力ファイルの例を示します。

@example
@group
%token IF THEN ELSE variable
%%
@end group
@group
stmt:     expr
        | if_stmt
        ;
@end group

@group
if_stmt:
          IF expr THEN stmt
        | IF expr THEN stmt ELSE stmt
        ;
@end group

expr:     variable
        ;
@end example


@node Precedence, Contextual Precedence, Shift/Reduce, Algorithm
@section 演算子の優先順位
@cindex operator precedence
@cindex precedence of operators
@cindex 演算子の優先順位
@cindex 優先順位, 演算子

シフト還元衝突が起きる別の可能性は、算術式の中にあります。
この場合には、シフトの選択が望ましい解決策であるとは限りません。
どのような場合にシフトしてどのような場合に還元するべきか指定するために、
演算子の優先順位についてのBison宣言を使えます。

@menu
* Why Precedence::    優先順位が必要なことを示す例.
* Using Precedence::  Bison文法で優先順位を指定する方法.
* Precedence Examples::  前の例でこれらの機能が使われた方法.
* How Precedence::    どのように動作するか.
@end menu


@node Why Precedence, Using Precedence,  , Precedence
@subsection 優先順位が必要な場合

次のあいまいな文法の一部を見てください。
入力@w{@samp{1 - 2 * 3}}が2通りに構文解析されうるので、
この文法はあいまいです。

@example
@group
expr:     expr '-' expr
        | expr '*' expr
        | expr '<' expr
        | '(' expr ')'
        @dots{}
        ;
@end group
@end example

構文解析器が、@samp{1}、@samp{-}、@samp{2}というトークンを
読み込んだと仮定します。構文解析器は、減算演算子の規則に従って、
これらのトークンを還元するべきでしょうか。
それは、次のトークンに依存します。
もちろん、次のトークンが@samp{)}ならば、還元する必要があります。
なぜならば、もしシフトすると、@w{@samp{- 2 )}}またはそれで始まる
記号列を還元する必要が生じ、そのような規則はないからです。
しかし、次のトークンが@samp{*}または@samp{<}ならば、
シフトと還元のどちらも可能です。
どちらを選んでも構文解析を完了できますが、解析の結果は異なります。

Bison字句解析器がどちらの処理をすべきか決めるために、
構文解析の結果を考慮する必要があります。
もし、次の演算子トークン@var{op}がシフトされるならば、
還元して差を求める可能性を許すために、
@var{op}は最初に還元される必要があります。
その結果は、@w{@samp{1 - (2 @var{op} 3)}}となります。
逆に、@var{op}をシフトする前に減算を還元するならば、
結果は@w{@samp{(1 - 2) @var{op} 3}}となります。
明らかに、シフトと還元のどちらが起こるべきかの選択は、
演算子@samp{-}と@var{op}の相対的な優先順位に依存します。
@samp{*}は先にシフトされるべきですが、@samp{<}は違います。

@cindex associativity
@cindex 結合性
@w{@samp{1 - 2 - 5}}のような例ではどうなるでしょうか。
@w{@samp{(1 - 2) - 5}}と処理するべきでしょうか。
それとも、@w{@samp{1 - (2 - 5)}}と処理するべきでしょうか。
ほとんどの演算子については前者が適し、これを、
@dfn{左結合性(left association)}と呼びます。
後者の@dfn{右結合性(right association)}は、代入演算子に適します。
左結合性か右結合性かの判断は、スタックに@w{@samp{1 - 2}}が含まれ、
先読みトークンが@samp{-}である場合の、シフトか還元かの選択です。
シフトを選ぶと、右結合的になります。


@node Using Precedence, Precedence Examples, Why Precedence, Precedence
@subsection 演算子の優先順位の指定
@findex %left
@findex %right
@findex %nonassoc

演算子優先順位宣言@code{%left}と@code{%right}によって、
演算子の優先順位と結合規則を指定できます。
どちらの宣言も、優先順位と結合規則を指定したい演算子である、
トークンの並びからなります。
@code{%left}宣言はすべての演算子を左結合的に、
@code{%right}宣言はすべての演算子を右結合的に宣言します。
第3の選択肢は@code{%nonassoc}宣言で、これで宣言した演算子が
続けて2回以上現れると、構文解析器が文法エラーを指摘します。

異なる演算子の相対的な優先順位は、それらが宣言される順序で決まります。
文法ファイルの中の最初の@code{%left}宣言または@code{%right}宣言で
宣言された演算子が、もっとも低い優先順位を持ちます。
後から宣言される演算子ほど、高い優先順位を持ちます。


@node Precedence Examples, How Precedence, Using Precedence, Precedence
@subsection 優先順位の例

先ほどの例では、次のように宣言するべきでした。

@example
%left '<'
%left '-'
%left '*'
@end example

もっと複雑な例では、より多くの演算子を使うだけでなく、
同じ優先順位を持つ演算子があります。
次の例では、@code{'+'}演算子と@code{'-'}演算子が同じ優先順位を持ちます。

@example
%left '<' '>' '=' NE LE GE
%left '+' '-'
%left '*' '/'
@end example

(この例で、@code{NE}は「等しくない」演算子を表し、他も同様です。
これらのトークンは、2文字以上からなるので、
1文字リテラルではなく名前で表されると仮定しています)


@node How Precedence,  , Precedence Examples, Precedence
@subsection 優先順位が働く仕組み

優先順位宣言の最初の働きは、宣言された終端記号への優先順位の割り当てです。
第2の働きは、規則に含まれる最後の終端記号が優先順位を示すように、
ある規則に優先順位を割り当てることです
(規則に対して、明示的に優先順位を指定することも可能です。
@xref{Contextual Precedence, ,Context-Dependent Precedence})。

最後に、衝突の解決は、問題になっている規則の優先順位と、
先読みトークンの優先順位の比較によって行われます。
もし、先読みトークンの優先順位が高ければ、還元されます。
もし、規則の優先順位が高ければ、シフトされます。
もし、優先順位が同じならば、その優先順位での結合規則によって決定されます。
@samp{-v}オプションを付けてBisonを実行し、冗長な出力ファイルを得ると、
どのように衝突が解決されているかがわかります
(@pxref{Invocation, ,Invoking Bison})。

すべての規則とトークンが優先順位を持っているとはかぎりません。
もし、規則と先読みトークンが優先順位を持っていなければ、
シフトが行われます。


@node Contextual Precedence, Parser States, Precedence, Algorithm
@section 文脈依存優先順位
@cindex context-dependent precedence
@cindex unary operator precedence
@cindex precedence, context-dependent
@cindex precedence, unary operator
@findex %prec
@cindex 文脈依存優先順位
@cindex 単項演算子の優先順位
@cindex 優先順位, 文脈依存
@cindex 優先順位, 単項演算子

しばしば、演算子の優先順位は文脈に依存します。
これは、最初は奇異に感じるかもしれませんが、
実際によく起きていることなのです。
たとえば、通常、減算演算子(@samp{-})は、
単項演算子としては非常に高い優先順位を持ちますが、
2項演算子としては乗除算よりも低い優先順位を持ちます。

Bisonの優先順位宣言、@code{%left}、@code{%right}、@code{%nonassoc}は、
あるトークンに対して1回のみ使え、この方法では、
トークンは唯一の優先順位を宣言されます。
文脈に依存する優先順位のためには、別の方法、すなわち、
@code{%prec}で規則を修飾する方法が必要になります。

@code{%prec}修飾子は、ある規則で使われるべき終端記号の優先順位を指定して、
その規則の優先順位を宣言します。
その記号がその規則の中以外に現れる必要はありません。
修飾子の記法は、次のようになっています。

@example
%prec @var{terminal-symbol}
@end example

これは、規則の構成要素の後に書かれます。
これによって、通常の方法で導かれる優先順位に代わって、
@var{terminal-symbol}の優先順位を規則に割り当てます。
規則の優先順位が変更されて、その規則が関係している衝突の解決に影響します
(@pxref{Precedence, ,Operator Precedence})。

@code{%prec}がどのように単項負記号を解決するかを示します。
まず、@code{UMINUS}という名前の終端記号に対する優先順位を宣言します。
この型のトークンは存在しませんが、
この記号が優先順位を表現するために使われます。

@example
@dots{}
%left '+' '-'
%left '*'
%left UMINUS
@end example

さて、@code{UNIMIS}の優先順位を、規則の中で使えます。

@example
@group
exp:    @dots{}
        | exp '-' exp
        @dots{}
        | '-' exp %prec UMINUS
@end group
@end example


@node Parser States, Reduce/Reduce, Contextual Precedence, Algorithm
@section 構文解析器の状態
@cindex finite-state machine
@cindex parser state
@cindex state (of parser)
@cindex 有限状態機械
@cindex 構文解析器の状態
@cindex 状態, 構文解析器

関数@code{yyparse}は、有限状態機械を使って実装されています。
構文解析器のスタックに積まれる値は、トークン型番号だけでなく、
スタックの先頭またはその近くにある終端記号と非終端記号の列を
表現しています。現在の状態は、次にすべきことに関連する、
今までの入力の情報全体の集まりです。

先読みトークンが読まれるたびに、先読みトークンの型と
現在の構文解析器の状態によって、表が引かれます。
この表の項目には、「先読みトークンをシフトしなさい」というような
ことが書かれています。この場合、その表の項目は、
先読みトークンが構文解析器スタックのトップに置かれた、
構文解析器の新しい状態をも示しています。
「@var{n}番目の規則を使って還元しなさい」というような項目もあります。
これによって、決められた数のトークンまたはグループがスタックのトップから
取り除かれ、1個のグループがスタックのトップに置かれます。
言い換えると、その数の状態がスタックからポップされ、
新しい1個の状態がスタックにプッシュされます。

これには、1つの例外があります。
先読みトークンが現在の状態に対してエラーであるという項目もあります。
この場合には、エラー処理が起こります
(@pxref{Error Recovery})。


@node Reduce/Reduce, Mystery Conflicts, Parser States, Algorithm
@section 還元/還元衝突
@cindex reduce/reduce conflict
@cindex conflicts, reduce/reduce
@cindex 還元/還元衝突
@cindex 衝突, 還元/還元

同一の入力列に対して2個以上の規則が適用可能であると、
還元/還元衝突が起きます。
これは、通常、文法の重大なエラーを意味します。

0個以上の@code{word}の並びをグループ化する、
誤った試みの例を示します。

@example
sequence: /* 空 */
                @{ printf ("empty sequence\n"); @}
        | maybeword
        | sequence word
                @{ printf ("added word %s\n", $2); @}
        ;

maybeword: /* 空 */
                @{ printf ("empty maybeword\n"); @}
        | word
                @{ printf ("single word %s\n", $1); @}
        ;
@end example

エラーは、あいまいさにあります。
つまり、1個の@code{word}を@code{sequence}に構文解析する、
2個以上の方法があります。
@code{word}は、@code{maybeword}に還元され、
第2の規則によって@code{sequence}になりえます。
また、最初の規則で、空データが@code{sequence}に還元され、
それが第3の規則によって@code{word}と組み合わされて
@code{sequence}になりえます。

さらに、空データが@code{sequence}に還元される方法が2つ以上あります。
第1の規則で直接還元される方法と、
@code{maybeword}を経由して第2の規則で還元される方法です。

この違いは、特定の入力が正当であるかどうかに関係ないので、
ささいなことに思えるかもしれません。
しかし、これは、どのアクションが実行されるかに影響します。
ある構文解析手順では第2の規則のアクションが実行され、
別の構文解析手順では第1の規則のアクションと第3の規則のアクションが
実行されます。
この例では、プログラムの出力が異なります。

Bisonは、最初に現れた文法を選ぶことで、還元/還元衝突を解決しますが、
これに頼ることは非常に危険です。
還元/還元衝突のそれぞれは、人間によって解析され、
通常は取り除かれるべきです。
@code{sequence}を定義する正しい方法を示します。

@example
sequence: /* 空 */
                @{ printf ("empty sequence\n"); @}
        | sequence word
                @{ printf ("added word %s\n", $2); @}
        ;
@end example

還元/還元衝突を起こす、別のありがちなエラーの例を示します。

@example
sequence: /* 空 */
        | sequence words
        | sequence redirects
        ;

words:    /* 空 */
        | words word
        ;

redirects:/* 空 */
        | redirects redirect
        ;
@end example

ここは、@code{word}または@code{redirect}グループのどちらかを含む
列の定義が目的です。
@code{sequence}、@code{words}、@code{redirects}それぞれ個別の
定義にエラーはありません。しかし、3個を合わせると、あいまいになります。
空の入力には、無限個の構文解析方法があります。

空データが@code{words}になったと仮定しましょう。
それは、2個の@code{words}にも、3個の@code{words}にも、
何個の@code{words}にもなりえます。
あるいは、1個の@code{words}に3個の@code{redirects}ともう1個の@code{word}が
続くことも考えられます。同様に、無限の解釈が可能です。

これらの規則を直す方法が2つあります。
第1に、1段階の列にする方法です。

@example
sequence: /* 空 */
        | sequence word
        | sequence redirect
        ;
@end example

第2に、@code{words}と@code{redirects}が空になるのを防ぐ方法です。
 
@example
sequence: /* 空 */
        | sequence words
        | sequence redirects
        ;

words:    word
        | words word
        ;

redirects:redirect
        | redirects redirect
        ;
@end example


@node Mystery Conflicts, Stack Overflow, Reduce/Reduce, Algorithm
@section 不可解な還元/還元衝突

そうなるはずがないように見えるのに、ときどき
還元/還元衝突が起きることがあります。
例を示します。

@example
@group
%token ID

%%
def:    param_spec return_spec ','
        ;
param_spec:
             type
        |    name_list ':' type
        ;
@end group
@group
return_spec:
             type
        |    name ':' type
        ;
@end group
@group
type:        ID
        ;
@end group
@group
name:        ID
        ;
name_list:
             name
        |    name ',' name_list
        ;
@end group
@end example

この文法は、1個のトークンの先読みによって、構文解析できるように見えます。
たとえば、@code{pram_spec}が読まれた後で、
@code{ID}はカンマかセミコロンが続くならば@code{name}、
そうでなければ@code{type}となります。
言い換えれば、この文法はLR(1)です。

@cindex LR(1)
@cindex LALR(1)
しかし、Bisonは、多くの構文解析器生成器と同様に、
すべてのLR(1)文法を扱えるわけではありません。
前述の例では、@code{ID}の後で、そこが@code{param_spec}の先頭であるという
文脈と、そこが@code{return_spec}の先頭であるという文脈は、
Bisonが同一であるとみなしてしまうほど似ています。
これらの文脈が似てしまう原因は、同じ規則の集合が有効になる、つまり、
@code{name}へ還元するための規則と、@code{type}へ還元するための規則の
両方が有効なことです。
Bisonは、その規則が2つの文脈で異なる先読みトークンを要求するような、
処理の段階を決定できず、両者から1つの構文解析器状態ができてしまいます。
2個の文脈の組み合わせは、後で衝突を起こします。
構文解析器の用語でいえば、この問題の発生は、
文法がLALR(1)でないことを意味します。

一般に、このような欠点は解決して、文書化するべきです。
しかし、この問題は本質的に解決困難です。
LR(1)文法を扱える構文解析器生成器は、作成困難で、
生成される構文解析器が巨大になってしまいます。
実用上、Bisonは今のままでも有用です。

このような問題が現れた場合に、混乱の元になっている2種類の構文解析器の
状態を区別し、それらが違うという目印か何かを追加することによって、
しばしば問題を解決できます。
前述の例では、次のように@code{return_spec}に規則を追加して、
問題を解決できます。

@example
@group
%token BOGUS
@dots{}
%%
@dots{}
return_spec:
             type
        |    name ':' type
         /* この規則は決して使われない。  */
        |    ID BOGUS
        ;
@end group
@end example

@code{ID}の次で@code{return_spec}の先頭である文脈で、
追加の規則が有効になる可能性を導入して、問題を解決しています。
この規則は、@code{param_spec}に関連する文脈では有効にならないので、
2個の文脈は、異なる構文解析器状態を持ちます。
@code{BOGUS}は@code{yylex}によっては決して生成されないので、
追加された規則は入力が実際に構文解析される方法には影響しません。

この具体例では、問題を解決する別の方法があります。
つまり、@code{return_spec}の規則を、@code{name}経由ではなく
@code{ID}を直接使うように書き換えるのです。
@code{return_spec}に対する規則は、@code{name}に対する規則ではなく、
@code{return_spec}に対する規則を有効にするので、
2つの混乱していた文脈は異なる有効な規則の集まりを持ちます。

@example
param_spec:
             type
        |    name_list ':' type
        ;
return_spec:
             type
        |    ID ':' type
        ;
@end example


@node Stack Overflow,  , Mystery Conflicts, Algorithm
@section スタックオーバーフローと防ぎ方
@cindex stack overflow
@cindex parser stack overflow
@cindex overflow of parser stack
@cindex スタックオーバーフロー
@cindex 構文解析器のスタックオーバーフロー
@cindex オーバーフロー, 構文解析器のスタック

Bison構文解析器のスタックは、あまりにも多くのトークンがシフトされて
還元されないでいると、オーバーフローする可能性があります。
スタックがオーバーフローすると、オーバーフローを報告するために@code{yyerror}
を呼び出して、関数@code{yyparse}は0でない値を返します。

@vindex YYMAXDEPTH
マクロ@code{YYMAXDEPTH}を定義して、スタックオーバーフローが起こらないように、
構文解析器のスタックの深さを調節できます。
マクロの値として、整数値を定義してください。
この値は、オーバーフローする前に、シフトされたが還元されていないトークンの
最大数になります。
マクロの値として、コンパイル時に決定可能な定数式を指定してください。

指定されたスタック領域は、割り当てられる必要はありません。
大きな@code{YYMAXDEPTH}を指定すると、
構文解析器はまず小さなスタック領域を割り当て、
必要に応じてより大きなスタック領域を割り当てます。
この割り当ての増加は、何も表示せずに、自動的に行われます。
したがって、スタックをあまり必要としない通常の入力に対して
メモリを節約するために、@code{YYMAXDEPTH}を小さくする必要はありません。

@cindex default stack limit
@cindex 省略時のスタックの限界
@cindex スタックの限界, 省略時
特に指定しないと、@code{YYMAXDEPTH}の値は10000になります。

@vindex YYINITDEPTH
マクロ@code{YYINIDEPTH}を指定して、最初に割り当てられるスタックの量を
調節できます。この値は、コンパイル時に決定可能な整定数の必要があります。
特に指定しないと、200になります。


@node Error Recovery, Context Dependency, Algorithm, Top
@chapter エラーからの回復
@cindex error recovery
@cindex recovery from errors
@cindex エラーからの回復
@cindex 回復

構文解析エラーが起きた場合に、構文解析プログラムが止まることは、
通常望ましくありません。
たとえば、コンパイラは入力の残りを構文解析して他のエラーを探せるように
エラーから回復するべきですし、電卓は次の式を受け入れるべきです。

入力を1行ごとに処理する単純な対話的構文解析器は、
エラーが発生した場合に@code{yyparse}が1を返し、
入力行の残りを無視し、
@code{yyparse}をもう一度呼び出してもかまいません。
しかし、コンパイラでこのように処理すると、
エラーに先立つ文法的文脈を忘れてしまうので不都合です。
深い関数呼び出しの中で構文エラーが発生した場合に、
コンパイラがエラーに続く行をソースファイルの先頭のように
扱うべきではありません。

@findex error
特別なトークン@code{error}を認識するような規則を書くことによって、
構文エラーから回復する方法を定義できます。
@code{error}は定義済みの終端記号で、自分で宣言する必要はなく、
エラー処理のために予約されています。
Bison構文解析器は、構文エラーが起こるたびに、@code{error}トークンを生成します。
現在の文脈で@code{error}トークンを認識できる規則を書いていれば、
構文解析を継続できます。

例を示します。

@example
stmnts:  /* 空文字列 */
        | stmnts '\n'
        | stmnts exp '\n'
        | stmnts error '\n'
@end example

第4の規則は、@code{error}とそれに続く改行が、任意の@code{stmnts}に
続くことを認めます。

@code{exp}の中で構文エラーが発生するとどうなるでしょうか。
エラー回復規則は、厳密に解釈され、@code{stmnts}、@code{error}、改行からなる
列に適用されます。
@code{exp}の中で構文エラーが起きると、おそらく、いくつかの余分なトークンまたは
部分式がスタック上の最後の@code{stmnts}の後に存在し、
したがって、次の改行を読む前に読むべきトークンが存在するでしょう。
したがって、この通常の方法では規則を適用できません。

しかし、意味文脈と入力の一部を捨てることによって、
Bisonは強制的にこの場合に規則を適用できます。
まず、@code{error}トークンが受理可能な状態に戻るまで、
状態とオブジェクトがスタックから捨てられます
(これは、すでに構文解析された部分式が捨てられ、
最後の完全な@code{stmnts}に状態が戻ることを意味します)。
この時点で、@code{error}トークンがシフトされます。
そして、古い先読みトークンのシフトは受理不可能なので、
受理可能なトークンを見つけるまで、
構文解析器はトークンを読んで捨てます。
前述の例では、次の改行がくるまで入力が読み捨てられ、
したがって、第4の規則が適用可能になります。

文法中のエラー規則の選択は、エラー回復の戦略の選択です。
単純で便利な戦略の1つは、エラーを検出したら、
単純に現在の入力行または文を読み飛ばすことです。

@example
stmnt: error ';'  /* エラーがあれば、「;」がくるまで読み飛ばす。 */
@end example

すでに構文解析された開き区切りトークン
@c @footnote{【訳注】C言語での@samp{([@{}、
@c Pascal言語での@samp{begin}など。}
を、閉じ区切りトークンに対応させることは、
エラー処理のうまい方法です。そうしなければ、閉じ区切りトークンが
後で不適切に現れて、別の重大なエラーを引き起こすでしょう。

@example
primary:  '(' expr ')'
        | '(' error ')'
        @dots{}
        ;
@end example

エラー回復の戦略は熟慮されるべきです。
戦略が悪いと、1つの構文エラーがしばしば別のエラーを引き起こします。
前述の例では、エラー回復規則は、1個の@code{stmnt}の中で起きると
仮定されています。
そうでない可能性として、有効な@code{stmnt}の中に誤ってセミコロンが
まぎれ込んでいることを考えてみましょう。
エラー回復規則が最初のエラーを回復した後で、まぎれ込んだセミコロンに続く
入力も無効な@code{stmnt}なので、もう1つの構文エラーがただちにみつかります。

エラー報告の洪水を避けるために、
最初の構文エラーが起きた直後の他の構文エラーに対しては、
構文解析器はエラー報告を表示しないべきでしょう。
3個の連続する入力トークンのシフトに成功してから、
エラー報告を再開するべきです。

@code{error}トークンを受け付ける規則も、他の規則と同様に
アクションを持てることに注意してください。

@findex yyerrok
アクションの中でマクロ@code{yyerrok}を使って、
ただちにエラー報告を再開できます。
もし、エラー規則のアクションの中でこのマクロを使えば、
エラー報告は抑制されません。
このマクロに引数は不要で、@samp{yyerrok;}は有効なCの文です。

@findex yyclearin
直前の先読みトークンは、エラーの直後に再解析されます。
これが不都合ならば、マクロ@code{yyclearin}によって先読みトークンを
消してください。すなわち、エラー規則のアクションに
@samp{yyclearin;}文を書いてください。

たとえば、構文エラーにおいて、構文解析を再開すべき場所まで入力を進めるような、
エラー処理手続きを考えてみましょう。
字句解析器から返される次の記号は、おそらく正しいでしょう。
以前の先読みトークンは@samp{yyclearin;}によって捨てられるべきです。

@vindex YYRECOVERING
マクロ@code{YYRECOVERING}は、式を表し、構文解析器がエラーから回復する
途中にあるならば値が1になり、通常の状態ならば値が0になります。
値が1であるということは、新たな構文エラーに対するエラーの報告が、
現在は抑制されていることを示します。


@node Context Dependency, Debugging, Error Recovery, Top
@chapter 文脈依存性の処理

Bisonの枠組みは、まずトークンを読み、
次にトークンをより大きな文法的単位にグループ化することです。
多くの言語では、トークンの意味は文脈の影響を受けます。
文脈依存性によってBisonの枠組みが壊れますが、
(@dfn{kludges}として知られる)いくつかの技術を使って、
このような言語に対するBison構文解析器を書けます。

@menu
* Semantic Tokens::   トークン構文解析は意味的文脈に依存する.
* Lexical Tie-ins::   トークン構文解析は構文的文脈に依存する.
* Tie-in Recovery::   字句結び付きはエラー回復規則を書く方法に影響する.
@end menu

(実際に、「kludge」は、仕事を可能にしますが、
美しくも頑丈でもない技術を意味します)


@node Semantic Tokens, Lexical Tie-ins,  , Context Dependency
@section トークン型の意味情報

C言語は文脈依存性をもっています。
すなわち、識別子の使われ方は、それの現在の意味に依存します。
次の例を考えてみてください。

@example
foo (x);
@end example

これは、関数を呼び出す文のように見えます。
しかし、もし、@code{foo}が@code{typedef}された型名ならば、
この文は@code{x}の宣言になります。
C言語に対するBison構文解析器は、この入力を構文解析する方法を
どのように決定できるでしょうか。

GNU Cで使っている方法は、@code{IDENTIFIER}と@code{TYPENAME}という、
2種類の異なるトークン型を使うことです。
@code{yylex}が識別子を見つけると、どちらのトークン型を返すか決めるために、
識別子の現在の宣言を検索し、@code{typedef}として宣言されていれば
@code{TYPENAME}を返し、そうでなければ@code{IDENTIFIER}を返します。

そして、認識するトークン型を選ぶことによって、
文法規則は文脈依存性を表現できます。
@code{IDENTIFIER}は、式として受け入れられますが、
@code{TYPENAME}は受け入れられません。
@code{TYPENAME}は、宣言の始まりとして受け入れられますが、
@code{IDENTIFIER}は受け入れられません。
識別子の意味の区別が@emph{必要のない}文脈、
たとえば@code{typedef}名を隠す宣言の中では、
@code{TYPENAME}と@code{IDENTIFIER}の両方が受け入れられます。
すなわち、2個のトークン型に対してそれぞれ1個の規則を書くことが可能です。

この方法は、どの種類の識別子が許されるかの判断が、
その識別子が構文解析される場所の近くで行われるならば、
単純に使えます。
しかし、C言語で、いつもそうであるとは限りません。
次の例のように、以前に指定された明示的な型に規定された@code{typedef}名の
再宣言が許されているからです。

@example
typedef int foo, bar, lose;
static foo (bar);        /* @r{@code{bar}を静的変数として再宣言する。} */
static int foo (lose);   /* @r{@code{foo}を関数として再宣言する。} */
@end example

不幸にも、込み入った文法構造「宣言子(declarator)」によって、
宣言された名前は、その宣言の構造自身から切り離されます。

結果として、C言語に対するBison構文解析器は、
すべての非終端記号の名前を変えて、二重化されました。
第1は、@code{typedef}名が再定義されているかもしれない宣言を構文解析し、
第2は、再定義が起こりえない宣言を構文解析します。
二重化したものの一部分を、簡単にするためにアクションを省略して、示します。

@example
initdcl:
          declarator maybeasm '='
          init
        | declarator maybeasm
        ;

notype_initdcl:
          notype_declarator maybeasm '='
          init
        | notype_declarator maybeasm
        ;
@end example

ここで、@code{initdcl}は@code{typedef}名を再宣言できますが、
@code{notype_initdcl}は再宣言できません。
@code{declarator}と@code{notype_declarator}の違いも同様です。

前述の技術と、後述の字句解析結び付きには、
字句解析に影響する情報が入力の別の部分を構文解析しているときに
変化させられるという、共通点があります。
前者では、情報が広域的で、プログラム@footnote{【訳注】構文解析器。}の別の目的に
使われることが異なります。
本当の字句解析結び付きは、文脈によって制御される、
特別の目的のフラグを持ちます。


@node Lexical Tie-ins, Tie-in Recovery, Semantic Tokens, Context Dependency
@section 字句解析結び付き
@cindex lexical tie-in
@cindex 字句解析結び付き

文脈依存性を処理する1つの方法は、@dfn{字句解析結び付き(lexical tie-in)}で、
Bisonのアクションによって設定されるフラグが、
トークンが構文解析される方法に影響します。

たとえば、C言語によく似ていて、@samp{hex (@var{hex-expr})}という
特別な構造を持つ言語について、考えてみましょう。
予約語@code{hex}がきた後にかっこで囲まれた式が続いて、
そのかっこの中ではすべての整数が16進数になります。
特に、トークン@samp{a1b}は、このような文脈に現れれば、
識別子ではなく整数として扱われる必要があります。
どのようにすればよいかを示します。

@example
@group
%@{
int hexflag;
%@}
%%
@dots{}
@end group
@group
expr:   IDENTIFIER
        | constant
        | HEX '('
                @{ hexflag = 1; @}
          expr ')'
                @{ hexflag = 0;
                   $$ = $4; @}
        | expr '+' expr
                @{ $$ = make_sum ($1, $3); @}
        @dots{}
        ;
@end group

@group
constant:
          INTEGER
        | STRING
        ;
@end group
@end example

@code{yylex}は、@code{hexflag}の値が0でなければ、
すべての整数が16進数であると字句解析し、
英字で始まるトークンも可能な限り整数と解釈すると、仮定します。

@code{hexflag}の宣言は、アクションから参照可能なように、
文法ファイルのC宣言部に書かれる必要があります
(@pxref{C Declarations, ,The C Declarations Section})。
同様に、@code{yylex}のプログラムにも、@code{hexflag}の宣言が必要です。


@node Tie-in Recovery,  , Lexical Tie-ins, Context Dependency
@section 字句解析結び付きとエラー回復

字句解析結び付きは、厳密なエラー回復規則を要求します。
@xref{Error Recovery}。

その理由は、エラー回復規則の目的が、ある構成物の構文解析を中断し、
より大きな構成物の構文解析を再開することです。
前述のC言語に似ている言語の例では、次のように、
標準的なエラー回復規則は、次のセミコロンまでトークンを読み捨て、
新しい文の構文解析を再開します。

@example
stmt:   expr ';'
        | IF '(' expr ')' stmt @{ @dots{} @}
        @dots{}
        error ';'
                @{ hexflag = 0; @}
        ;
@end example

もし、@samp{hex (@var{expr})}の途中で構文エラーが発生すれば、
このエラー回復規則が適用され、完了した@samp{hex @var{expr})}に対する
アクションは決して実行されません。
すると、@code{hexflag}は、入力の残りの間ずっと設定されたままでいるか、
次の@code{hex}予約語の出現までそのままの状態でいて、
識別子が16進整数と誤解されます。

この問題を防ぐためには、エラー回復規則が
@code{hexflag}を元に戻すべきです。

さらに、式の内部で働くエラー回復規則があるかもしれません。
たとえば、次の例のように、かっこの中でエラーが発生すると、
閉じかっこまで読み捨てるようなエラー回復規則が考えられます。

@example
@group
expr:   @dots{}
        | '(' expr ')'
                @{ $$ = $2; @}
        | '(' error ')'
        @dots{}
@end group
@end example

もし、この規則が@code{hex}構造の中で働くならば、
その構造の中の内側のかっこに適用されるので、
構造を中断するべきではありません。
したがって、このアクションではフラグを戻すべきではなく、
@code{hex}構造の残りはフラグを有効にしたまま構文解析されるべきです。

状況に応じて、@code{hex}構造を中断できるかもしれないし、そうでないかもしれない
エラー回復規則があれば、どうなるでしょうか。
@code{hex}構造を中断すべきかどうか決定できるアクションを書けません。
そこで、もし、字句解析結び付きを使っているならば、
あなたが書いたエラー回復規則がそのようになっていないことを確かめるべきです。
それぞれの規則は、常にフラグを戻すべきか、あるいは常にフラグを戻さないべきか、
決定できるべきです。


@node Debugging, Invocation, Context Dependency, Top
@chapter 構文解析器のデバッグ
@findex YYDEBUG
@findex yydebug
@cindex debugging
@cindex tracing the parser
@cindex 追跡, 構文解析器
@cindex 構文解析器の追跡

もし、Bison文法ファイルが正しくコンパイルされたのに、
生成された構文解析器が思いどおりに動かない場合には、
@code{yydebug}構文解析器追跡機能が、調査の役に立つでしょう。

追跡機能のコンパイルを有効にするためには、
構文解析器をコンパイルするときに、マクロ@code{YYDEBUG}を定義する必要があります。
そのためには、コンパイラのオプションに@samp{-DYYDEBUG=1}を指定するか、
あるいは、文法ファイルのC宣言部に@samp{#define YYDEBUG 1}と書いておく
必要があります(@pxref{C Declarations, ,The C Declarations Section})。
あるいは、Bisonを実行するときに(@pxref{Invocation, ,Invoking Bison})、
@samp{-t}オプションを指定しておくと、
@code{YYDEBUG}が定義され、追跡が可能になります。

追跡機能は@code{stderr}を使うので、C宣言部に
@w{@code{#include <stdio.h>}}と書いておく必要があります。

追跡機能付で構文解析器をコンパイルしたら、構文解析器の実行時に、
追跡機能を有効にするために、@code{yydebug}変数を0でない値にしてください。
C言語のプログラム(おそらく@code{main}関数の中)でこの変数に代入するか、
あるいは、デバッガでこの変数の値を変えればいいでしょう。

@code{yydebug}が0でない場合、構文解析器はそれぞれの段階で、
1行まはた2行の追跡情報を生成し、@code{stderr}に出力します。
追跡情報には、次のような情報が含まれています。

@itemize @bullet
@item
構文解析器が@code{yylex}を呼ぶたびに、
読み込まれたトークンの種類が記録されます。

@item
トークンがシフトされるたびに、状態スタックの深さと完全な内容が
表示されます(@pxref{Parser States})。

@item
規則が還元されるたびに、どの規則が使われるか、そして、
還元後の状態スタックの完全な内容が記録されます。

@end itemize

この情報を理解するためには、Bisonに@samp{-v}オプション
(@pxref{Invocation, ,Invoking Bison})を付けて実行すると生成される
明細ファイルが参考になるでしょう。
このファイルには、さまざまな規則の中での位置による表現で
各状態の意味が示され、また、
各状態がそれぞれの可能な入力トークンによって
どのように動作するかが示されています。
連続する追跡の意味を読むことによって、
明細ファイルで仕様が示されている構文解析器の機能について、理解できるでしょう。
何か望ましくないことが起きている部分を確認すれば、
文法ファイルのどこに問題があるかわかるでしょう。

構文解析器ファイルはC言語のプログラムなので、
Cのデバッガを使えますが、
何が起きているか調べることは困難です。
構文解析器関数は、有限状態機械インタープリタで、
アクションが実行されると、
プログラムの同じ部分が何度も何度も実行されます。
実用的なのは文法の中で変数の値を調べることだけでしょう。

@findex YYPRINT
デバッグ情報には、通常、それぞれのトークンのトークン型だけが含まれ、
トークンの意味値は含まれません。
マクロ@code{YYPRINT}を定義することで、
トークンの意味値を表示させられます。
@code{YYPRINT}の定義には、3個の引数がともないます。
構文解析器は、@code{YYPRINT}に、標準入出力ストリーム、
トークン型の数値番号、トークンの値(@code{yylval}による)を渡します。

多機能電卓に適する@code{YYPRINT}の例を示します
(@pxref{Mfcalc Decl, ,Declarations for @code{mfcalc}})。

@smallexample
#define YYPRINT(file, type, value)   yyprint (file, type, value)

static void
yyprint (file, type, value)
     FILE *file;
     int type;
     YYSTYPE value;
@{
  if (type == VAR)
    fprintf (file, " %s", value.tptr->name);
  else if (type == NUM)
    fprintf (file, " %d", value.val);
@}
@end smallexample


@node Invocation, Table of Symbols, Debugging, Top
@chapter Bisonの実行
@cindex invoking Bison
@cindex Bison invocation
@cindex options for invoking Bison
@cindex Bisonの実行
@cindex 実行, Bison
@cindex Bison実行のオプション
@cindex オプション, Bison実行

通常、Bisonは次のように実行します。

@example
bison @var{infile}
@end example

ここで、@var{infile}は文法ファイルで、名前が通常@samp{.y}で終わります。
生成される構文解析器ファイルは、文法ファイルの名前の@samp{.y}を
@samp{.tab.c}に変えたものです。
したがって、@samp{bison foo.y}によって@samp{foo.tab.c}を得られますし、
@samp{bison hack/foo.y}によって@samp{hack/foo.tab.c}を得られます。

@menu
* Bison Options::     全てのオプションが詳しく、短いオプションでアルファ
                        ベット順に説明されている.
* Option Cross Key::  長いオプションのアルファッベット順のリスト.
* VMS Invocation::    VMSでのBisonのコマンド構文.
@end menu


@node Bison Options, Option Cross Key,  , Invocation
@section Bisonのオプション

Bisonは、伝統的な1文字のオプションと、記憶しやすい長いオプション名の
両方を受け付けます。長いオプション名は、@samp{-}の代わりに、
@samp{--}で指定します。
一意性を失わない範囲で、長いオプション名を省略できます。
長いオプションが引数をともなう場合、たとえば、@samp{--file-prefix}では、
オプション名と引数の間に@samp{=}を入れます。

Bisonに対して指定可能なオプションの一覧を、アルファベット順に示します。
さらに、長い名前のアルファベット順の対応を示します。

@table @samp
@item -b @var{file-prefix}
@itemx --file-prefix=@var{prefix}
Bisonが生成するすべてのファイルの名前の前半部分を指定します。
入力される文法ファイルの名前が@file{@var{prefix}.y}であった場合と、
同じ結果を得られます。

@item -d
@itemx --defines
文法ファイル中で定義されたトークン型名に対するマクロ定義、
意味値型@code{YYSTYPE}、いくつかの@code{extern}変数宣言を含む、
追加の出力ファイルを生成します。

生成される構文解析ファイルの名前が@file{@var{name}.c}ならば、
このファイルの名前は@file{@var{name}.h}になります。

@code{yylex}関数を独立なソースファイルの中で定義しているならば、
それはトークン型番号と変数@code{yylval}を必要とするので、
このファイルを@code{#include}する必要があります
@xref{Token Values, ,Semantic Values of Tokens}。

@item -l
@itemx --no-lines
構文解析器ファイルの中に、@code{#line}プリプロセッサディレクティブを生成しません。
通常、Bisonはこれを生成し、Cコンパイラとデバッガが、
文法ファイルのどこでエラーが発生したかを見つけるために使います。
このオプションは、エラーと構文解析器の行番号を結び付け、
構文解析器を独立なソースファイルとして扱います。

@item -n
@itemx --no-parser
構文解析器にCのプログラムを含めず、表だけを生成します。
構文解析器ファイルは、@code{#define}ディレクティブと
静的変数の宣言のみからなります。

このオプションにより、@file{@var{filename}.act}という名前のファイルに、
文法アクションに対するC言語のプログラムが書かれます。
その書式は、@code{switch}文に対応するブレースで囲まれたブロックです。

@item -o @var{outfile}
@itemx --output-file=@var{outfile}
生成される構文解析器ファイルの名前を指定します。

他の出力ファイルのファイル名の指定は
@samp{-v}と@samp{-d}オプションの項を参照してください。

@item -p @var{prefix}
@itemx --name-prefix=@var{prefix}
構文解析器が使う外部名を@samp{yy}でなく@var{prefix}で始まるように変えます。
影響を受ける名前は、
@code{yyparse}、@code{yylex}、@code{yyerror}、@code{yynerrs}、
@code{yylval}、@code{yychar}、@code{yydebug}です。

たとえば、@samp{-p c}オプションを指定すれば、
名前は@code{cparse}、@code{clex}などになります。

@xref{Multiple Parsers, ,Multiple Parsers in the Same Program}。

@item -r
@itemx --raw
@code{%raw}が指定されたように振る舞います。
@xref{Decl Summary}。

@item -t
@itemx --debug
デバッグ機能がコンパイルされるように、
マクロ@code{YYDEBUG}の定義を構文解析器ファイルに入れます
@xref{Debugging, ,Debugging Your Parser}。

@item -v
@itemx --verbose
構文解析器の状態についての詳細な説明と、
それらの状態でそれぞれの先読みトークンが現れると何が起きるか記述した、
追加のファイルを生成します。

このファイルは、演算子の優先順位によって解決したものも解決しなかった
ものも含めて、衝突についての説明を含んでいます。

生成されるファイルの名前は、構文解析器のファイルの名前から、
@samp{.tab.c}または@samp{.c}を取り除いて、
代わりに@samp{.output}を付けたものです。

したがって、入力の文法ファイルの名前が@file{foo.y}ならば、
特に指定しないと、構文解析器ファイルの名前は@file{foo.tab.c}になり、
詳細な説明のファイルの名前は@file{foo.output}になります。

@item -V
@itemx --version
バージョン番号を表示して、Bisonを終了させます。

@item -h
@itemx --help
コマンドラインオプションの要約を表示して、Bisonを終了させます。

@need 1750
@item -y
@itemx --yacc
@itemx --fixed-output-files
@samp{-o y.tab.c}と等価です。構文解析器ファイルの名前は
@file{y.tab.c}になり、他の出力ファイルの名前は@file{y.output}と
@file{y.tab.h}になります。このオプションの目的は、
出力ファイルの名前をYaccに合わせることです。
次のシェルスクリプトは、Yaccの代用になります。

@example
bison -y $*
@end example
@end table


@node Option Cross Key, VMS Invocation, Bison Options, Invocation
@section オプション対応表

オプションを、長い名前のアルファベット順に一覧表記して、
対応する1文字オプションを書きます。

@tex
\def\leaderfill{\leaders\hbox to 1em{\hss.\hss}\hfill}

{\tt
\line{ --debug \leaderfill -t}
\line{ --defines \leaderfill -d}
\line{ --file-prefix \leaderfill -b}
\line{ --fixed-output-files \leaderfill -y}
\line{ --help \leaderfill -h}
\line{ --name-prefix \leaderfill -p}
\line{ --no-lines \leaderfill -l}
\line{ --no-parser \leaderfill -n}
\line{ --output-file \leaderfill -o}
\line{ --raw \leaderfill -r}
\line{ --token-table \leaderfill -k}
\line{ --verbose \leaderfill -v}
\line{ --version \leaderfill -V}
\line{ --yacc \leaderfill -y}
}
@end tex

@ifinfo
@example
--debug                               -t
--defines                             -d
--file-prefix=@var{prefix}                  -b @var{file-prefix}
--fixed-output-files --yacc           -y
--help                                -h
--name-prefix=@var{prefix}                  -p @var{name-prefix}
--no-lines                            -l
--no-parser                           -n
--output-file=@var{outfile}                 -o @var{outfile}
--raw                                 -r			
--token-table                         -k
--verbose                             -v
--version                             -V
@end example
@end ifinfo


@node VMS Invocation,  , Option Cross Key, Invocation
@section VMS上での実行
@cindex invoking Bison under VMS
@cindex VMS
@cindex 実行, VMS上

VMS上のBisonのコマンドライン構文は、VMSの慣習に合わせて、
他のシステム上のBisonのコマンドライン構文と異なっています。

VMSでは、すべてのBisonのオプションについて、
@samp{--}の代わりに@samp{/}に続く長い名前のオプションを書き、
オプション名中の@samp{-}を@samp{_}に変えます。
VMS上での実行例を示します。

@example
bison /debug/name_prefix=bar foo.y
@end example

これは、POSIX上での次のコマンドラインと等価です。

@example
bison --debug --name-prefix=bar foo.y
@end example

VMSファイルシステムでは、@file{foo.tab.c}のようなファイル名が許されないので、
構文解析器の名前は、上記の例の場合には、@file{foo_tab.c}になります。


@node Table of Symbols, Glossary, Invocation, Top
@appendix Bisonの記号一覧
@cindex Bison symbols, table of
@cindex symbols in Bison, table of
@cindex 記号一覧, Bison
@cindex Bisonの記号一覧

@table @code
@item error
エラー回復のために予約されているトークン名です。
このトークンが文法規則の中で使われていると、Bison構文解析器は、
構文エラーを認識し、プロセスの実行を中断しません。
実質的には、エラーを含む文が、有効であると認識されます。
エラーが起きると、@code{error}トークンが現在の先読みトークンになります。
@code{error}に対応するアクションが実行されて、
先読みトークンがエラーの原因になったトークンに戻されます。
@xref{Error Recovery}。

@item YYABORT
回復不可能な構文エラーが発生した場合のためのマクロで、
実行するとただちに@code{yyparse}が1を返します。
エラー報告関数@code{yyerror}は呼び出されません。
@xref{Parser Function, ,The Parser Function @code{yyparse}}。

@item YYACCEPT
構文解析器が言語を完全に読み終えた場合のためのマクロで、
実行するとただちに@code{yyparse}が0を返します。
@xref{Parser Function, ,The Parser Function @code{yyparse}}。

@item YYBACKUP
構文解析器のスタックから1個の値を捨て、先読みトークンのふりをさせます。
@xref{Action Features, ,Special Features for Use in Actions}。

@item YYERROR
構文エラーがちょうど検出された場合のためのマクロで、
@code{yyerror}を呼び、可能ならば通常のエラー回復処理
(@pxref{Error Recovery})を実行し、不可能ならば
@code{yyparse}が1を返します。
@xref{Error Recovery}。

@item YYERROR_VERBOSE
Bison宣言部で@code{#define}によってこのマクロを定義すると、
@code{yyerror}が呼ばれたときに表示されるエラー報告が詳しくなります。

@item YYINITDEPTH
構文解析器スタックの最初の大きさを指定するマクロです。
@xref{Stack Overflow}。

@item YYLEX_PARAM
@code{yyparse}が@code{yylex}に渡すための、追加の引数または
引数の並びを指定するためのマクロです。
@xref{Pure Calling,, Calling Conventions for Pure Parsers}。

@item YYLTYPE
@code{yyloc}のデータ型を示すマクロで、4個のメンバからなる構造体です。
@xref{Token Positions, ,Textual Positions of Tokens}。

@item yyltype
@code{YYLTYPE}の省略時の値です。

@item YYMAXDEPTH
構文解析器のスタックの最大の大きさを指定するマクロです。
@xref{Stack Overflow}。

@item YYPARSE_PARAM
@code{yyparse}が受け取るべき引数の名前を指定するマクロです。
@xref{Pure Calling,, Calling Conventions for Pure Parsers}。

@item YYRECOVERING
構文解析器が構文エラーから回復している途中かどうかを示す値のマクロです。
@xref{Action Features, ,Special Features for Use in Actions}。

@item YYSTYPE
意味値のデータ型を指定するためのマクロで、省略すると@code{int}になります。
@xref{Value Type, ,Data Types of Semantic Values}。

@item yychar
広域的な@code{int}型の変数で、現在の先読みトークンの番号を記憶しています
(再入可能な構文解析器では、この変数は@code{yyparse}に局所的です)。
エラー回復規則のアクションは、この変数の値を調べられます。
@xref{Action Features, ,Special Features for Use in Actions}。

@item yyclearin
エラー回復規則のアクションで使われるマクロです。
直前の先読みトークンを消去します。
@xref{Error Recovery}。

@item yydebug
@code{int}型の広域変数で、初期値は0です。
@code{yydebug}の値が0でないと、構文解析器は、
読み込んだ記号と構文解析器のアクションに関する情報を表示します。
@xref{Debugging, ,Debugging Your Parser}。

@item yyerrok
構文エラーの後で、構文解析器をただちに通常の状態に戻すためのマクロです。
@xref{Error Recovery}。

@item yyerror
エラーが起きたときに@code{yyparse}から呼び出される、ユーザー定義関数です。
この関数は1個の引数を受け取り、その引数はエラーの報告を含む文字列への
ポインタです。
@xref{Error Reporting, ,The Error Reporting Function @code{yyerror}}。

@item yylex
ユーザー定義の字句解析関数で、次のトークンを得るために、
引数なしで呼び出されます。
@xref{Lexical, ,The Lexical Analyzer Function @code{yylex}}。

@item yylval
トークンに関連する意味値を@code{yylex}が置くための広域変数です
(再入可能な構文解析器では、これは@code{yyparse}の局所変数で、
その番地が@code{yylex}に渡されます)。
@xref{Token Values, ,Semantic Values of Tokens}。

@item yylloc
トークンに関連する行番号と桁番号を@code{yylex}が置くための
広域変数です(再入可能な構文解析器では、この変数は@code{yyparse}に
局所的で、その番地が@code{yylex}に渡されます)。
文法アクションで@samp{@@}機能を使わないならば、
この値を無視してかまいません。
@xref{Token Positions, ,Textual Positions of Tokens}。

@item yynerrs
構文エラーが発生するたびにBisonが値を1増やす広域変数です
(再入可能な構文解析器では、この変数は@code{yyparse}に局所的です)。
@xref{Error Reporting, ,The Error Reporting Function @code{yyerror}}。

@item yyparse
Bisonによって生成される構文解析器関数で、
この関数を呼び出すことによって構文解析が始まります。
@xref{Parser Function, ,The Parser Function @code{yyparse}}。

@item %left
トークンに左結合性を与えるBison宣言です。
@xref{Precedence Decl, ,Operator Precedence}。

@item %no_lines
構文解析器ファイルの中に@code{#line}ディレクティブを生成しないための
Bison宣言です。
@xref{Decl Summary}。

@item %nonassoc
トークンに非結合性を与えるためのBison宣言です。
@xref{Precedence Decl, ,Operator Precedence}。

@item %prec
指定された規則に優先順位を与えるためのBison宣言です。
@xref{Contextual Precedence, ,Context-Dependent Precedence}。

@item %pure_parser
再入可能な構文解析器を生成するためのBison宣言です。
@xref{Pure Decl, ,A Pure (Reentrant) Parser}。

@item %raw
通常のYacc互換トークン番号の代わりに、
トークン表のBison内部トークン番号を使うための、Bison宣言です。
@xref{Decl Summary}。

@item %right
トークンに右結合性を与えるためのBison宣言です。
@xref{Precedence Decl, ,Operator Precedence}。

@item %start
開始記号を指定するためのBison宣言です。
@xref{Start Decl, ,The Start-Symbol}。

@item %token
優先順位を指定せずにトークンを宣言するためのBison宣言です。
@xref{Token Decl, ,Token Type Names}。

@item %token_table
構文解析器ファイルの中でトークン名の表を挿入するためのBison宣言です。
@xref{Decl Summary}。

@item %type
非終端記号を宣言するためのBison宣言です。
@xref{Type Decl, ,Nonterminal Symbols}。

@item %union
意味値として可能ないくつかのデータ型を指定するためのBison宣言です。
@xref{Union Decl, ,The Collection of Value Types}.
@end table

Bison文法ファイルの中で使う、区切り記号があります。

@table @samp
@item %%
Bison宣言部、文法規則部、(省略可能な)Cプログラム部を区切る記号です。
@xref{Grammar Layout, ,The Overall Layout of a Bison Grammar}。

@item %@{ %@}
文法ファイルの@samp{%@{}と@samp{%@}}の間に書かれたすべてのプログラムは、
そのまま構文解析器ファイルに複写されます。
このようなプログラムが、文法ファイルのC宣言部を構成します。
@xref{Grammar Outline, ,Outline of a Bison Grammar}。

@item /*@dots{}*/
C言語と同様のコメントです。

@item :
規則の結果と構成要素を分離する記号です。
@xref{Rules, ,Syntax of Grammar Rules}。

@item ;
規則の終わりの記号です。
@xref{Rules, ,Syntax of Grammar Rules}。

@item |
同一の非終端記号を結果とする複数の規則を区切る記号です。
@xref{Rules, ,Syntax of Grammar Rules}。
@end table


@node Glossary, Index, Table of Symbols, Top
@appendix 用語集
@cindex glossary
@cindex 用語集

@table @asis
@item Backus-Naur Form(BNF)(バッカス-ナウア記法)
文脈自由文法を形式的に表現する方法です。
BNFは、1963年の報告@cite{ALGOL-60}で初めて使われました。
@xref{Language and Grammar, ,Languages and Context-Free Grammars}。

@item Context-free grammars(文脈自由文法)
文脈に関係なく適用される規則によって定められる文法です。
したがって、もし、整数は式として使われてもよいという規則があれば、
式が許される@emph{あらゆる場所で}整数の利用が許されます。
@xref{Language and Grammar, ,Languages and Context-Free Grammars}。

@item Dynamic allocation(動的割り当て)
プログラムをコンパイルするときでも、関数の実行を始めるときでもなく、
実行の途中でメモリを割り当てることです。

@item Empty string(空文字列)
集合論での空集合と同様に、空文字列とは長さが0の文字列です。

@item Finite-state stack machine(有限状態スタック機械)
その完全な状態が、各瞬間での状態で記述される「機械」です。
機械への入力が処理されると、機械の論理に応じて、
機械の状態が別の状態に変わります。
本書では、入力とは構文解析されている言語で、
状態とは文法規則のさまざまな段階です。
@xref{Algorithm, ,The Bison Parser Algorithm }。

@item Grouping(グループ)
言語の構成要素で、(一般的に)文法的に分割可能なのもです。
たとえば、C言語の「式」や「宣言」です。
@xref{Language and Grammar, ,Languages and Context-Free Grammars}。

@item Infix operator(中間記法演算子)
演算の対象となるオペランドの中間に置かれる算術演算子です。

@item Input stream(入力ストリーム)
入出力装置またはプログラムの間での、連続的なデータの流れです。

@item Language construct(言語構文)
言語の概要を示す典型的な方法の1つです。
たとえば、C言語の構文の1つは@code{if}文です。
@xref{Language and Grammar, ,Languages and Context-Free Grammars}。

@item Left associativity(左結合性)
左結合性を持つ演算子は、左から右に向かって構文解析されます。
たとえば、@samp{a+b+c}では、まず@samp{a+b}が計算され、
次に@samp{c}との和が計算されます。
@xref{Precedence, ,Operator Precedence}。

@item Left recursion(左再帰)
結果の記号が構成要素の最初の記号と等しいような規則です。
たとえば、@samp{expseq1 : expseq1 ',' exp;}が左再帰です。
@xref{Recursion, ,Recursive Rules}。

@item Left-to-right parsing(LR構文解析)
左側から右側に向かって、トークンを次々に解析していくような、
言語の構文解析方法です。
@xref{Algorithm, ,The Bison Parser Algorithm }。

@item Lexical analyzer(scanner)(字句解析器)
入力ストリームを読んで、トークンを1つずつ返す関数です。
@xref{Lexical, ,The Lexical Analyzer Function @code{yylex}}。

@item Lexical tie-in(字句解析結び付き)
文法規則によって設定されるフラグが、トークンが字句解析される方法に
影響することです。
@xref{Lexical Tie-ins}。

@item Literal string token(リテラル文字列トークン)
2文字以上の決まった文字列からなるトークンです。
@xref{Symbols}。

@item Look-ahead token(先読みトークン)
すでに読み込まれていて、シフトされていないトークンです。
@xref{Look-Ahead, ,Look-Ahead Tokens}。

@item LALR(1)
Bison(または似ているほとんどの構文解析器)によって扱える、
文脈自由文法の一部分で、LR(1)の部分集合です。
@xref{Mystery Conflicts, ,Mysterious Reduce/Reduce Conflicts}。

@item LR(1)
任意の入力のあいまいでない構文解析に対して、
単に1個の先読みトークンを必要とするような、
文脈自由文法の一部分です。

@item Nonterminal symbol(非終端記号)
文法的構成要素を表す文法記号で、文法規則によってより小さな構成要素に
分解できるものです。言い換えると、トークンでない構成要素です。
@xref{Symbols}。

@item Parse error(構文エラー)
入力ストリームを構文解析しているときに、誤った文法によって発生するエラーです。
@xref{Error Recovery}。

@item Parser(構文解析器)
字句解析器から渡されたトークンの集合の文法的構造を解析して、
言語の有効な文を認識する関数です。

@item Postfix operator(後置演算子)
演算の対象のオペランドの後に置かれる算術演算子です。

@item Reduction(還元)
文法規則に従って、非終端記号または終端記号の列を、
1個の非終端記号に置き換えることです。
@xref{Algorithm, ,The Bison Parser Algorithm }。

@item Reentrant(再入可能)
再入可能な手続きとは、複数の呼び出しの間での相互作用なしに、
並行して任意の数を呼び出せる手続きです。
@footnote{【訳注】ある関数が終了する前に、
その同じ関数を非同期に呼び出してもよいということ。}
@xref{Pure Decl, ,A Pure (Reentrant) Parser}。

@item Reverse polish notation(逆ポーランド記法)
すべての演算子が後置記法演算子であるような言語です。

@item Right recursion(右再帰)
規則の結果の記号が、規則の最後の構成要素と同じ記号であるような規則です。
たとえば、@samp{expseq1: exp ',' expseq1;}は右再帰です。
@xref{Recursion, ,Recursive Rules}.

@item Semantics(意味)
計算機言語では、言語の各インスタンスが起こすアクションによって、
意味が指定されます。すなわち、各文の意味です。
@xref{Semantics, ,Defining Language Semantics}。

@item Shift(シフト)
構文解析器がシフトするとは、
すでに認識されているある規則によってただちに還元する代わりに、
ストリームからのさらなる入力を分析することです。
@xref{Algorithm, ,The Bison Parser Algorithm }。

@item Single-character literal(1文字リテラル)
そのままに解釈される@footnote{【訳注】字句解析器によって}1文字です。
@xref{Grammar in Bison, ,From Formal Rules to Bison Input}。

@item Start symbol(開始記号)
構文解析された有効な言語の全体を表す非終端記号です。
通常、言語仕様に書かれた最初の非終端記号です。
@xref{Start Decl, ,The Start-Symbol}。

@item Symbol table(記号表)
繰り返し使われる記号の情報を認識して使うために、
構文解析の途中で、記号の名前と関連する情報を記憶するデータ構造です。
@xref{Multi-function Calc}。

@item Token(トークン)
言語の、基本的で、文法的に分割できない単位です。
文法の中のトークンを記述する記号を終端記号といいます。
Bison構文解析器の入力は、字句解析器からの、
トークンの流れです。
@xref{Symbols}。

@item Terminal symbol(終端記号)
文法規則を持たず、したがって文法的に分割できない文法記号です。
これが表す文字の集まりをトークンといいます。
@xref{Language and Grammar, ,Languages and Context-Free Grammars}。
@ignore
この行を含む3行は info ファイル作成時のエラーを回避するために挿入(編集担当)
@end ignore
@end table


@node Index,  , Glossary, Top
@unnumbered 索引

@printindex cp

@contents

@bye




@c old menu

* Introduction::
* Conditions::
* Copying::           The GNU General Public License says
                        how you can copy and share Bison

Tutorial sections:
* Concepts::          Basic concepts for understanding Bison.
* Examples::          Three simple explained examples of using Bison.

Reference sections:
* Grammar File::      Writing Bison declarations and rules.
* Interface::         C-language interface to the parser function @code{yyparse}.
* Algorithm::         How the Bison parser works at run-time.
* Error Recovery::    Writing rules for error recovery.
* Context Dependency::What to do if your language syntax is too
                        messy for Bison to handle straightforwardly.
* Debugging::         Debugging Bison parsers that parse wrong.
* Invocation::        How to run Bison (to produce the parser source file).
* Table of Symbols::  All the keywords of the Bison language are explained.
* Glossary::          Basic concepts are explained.
* Index::             Cross-references to the text.




FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>