📄 bison.texinfo
字号:
to the parse that interprets the example as a@code{decl}, which implies that @code{x} is a declarator.The parser therefore prints@example"x" y z + T <init-declare>@end exampleThe @code{%dprec} declarations only come into play when more than oneparse survives. Consider a different input string for this parser:@exampleT (x) + y;@end example@noindentThis is another example of using @acronym{GLR} to parse an unambiguousconstruct, as shown in the previous section (@pxref{Simple GLR Parsers}).Here, there is no ambiguity (this cannot be parsed as a declaration).However, at the time the Bison parser encounters @code{x}, it does nothave enough information to resolve the reduce/reduce conflict (again,between @code{x} as an @code{expr} or a @code{declarator}). In thiscase, no precedence declaration is used. Again, the parser splitsinto two, one assuming that @code{x} is an @code{expr}, and the otherassuming @code{x} is a @code{declarator}. The second of these parsersthen vanishes when it sees @code{+}, and the parser prints@examplex T <cast> y +@end exampleSuppose that instead of resolving the ambiguity, you wanted to see allthe possibilities. For this purpose, you must merge the semanticactions of the two possible parsers, rather than choosing one over theother. To do so, you could change the declaration of @code{stmt} asfollows:@examplestmt : expr ';' %merge <stmtMerge> | decl %merge <stmtMerge> ;@end example@noindentand define the @code{stmtMerge} function as:@examplestatic YYSTYPEstmtMerge (YYSTYPE x0, YYSTYPE x1)@{ printf ("<OR> "); return "";@}@end example@noindentwith an accompanying forward declarationin the C declarations at the beginning of the file:@example%@{ #define YYSTYPE char const * static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1);%@}@end example@noindentWith these declarations, the resulting parser parses the first exampleas both an @code{expr} and a @code{decl}, and prints@example"x" y z + T <init-declare> x T <cast> y z + = <OR>@end exampleBison requires that all of theproductions that participate in any particular merge have identical@samp{%merge} clauses. Otherwise, the ambiguity would be unresolvable,and the parser will report an error during any parse that results inthe offending merge.@node Compiler Requirements@subsection Considerations when Compiling @acronym{GLR} Parsers@cindex @code{inline}@cindex @acronym{GLR} parsers and @code{inline}The @acronym{GLR} parsers require a compiler for @acronym{ISO} C89 orlater. In addition, they use the @code{inline} keyword, which is notC89, but is C99 and is a common extension in pre-C99 compilers. It isup to the user of these parsers to handleportability issues. For instance, if using Autoconf and the Autoconfmacro @code{AC_C_INLINE}, a mere@example%@{ #include <config.h>%@}@end example@noindentwill suffice. Otherwise, we suggest@example%@{ #if __STDC_VERSION__ < 199901 && ! defined __GNUC__ && ! defined inline #define inline #endif%@}@end example@node Locations Overview@section Locations@cindex location@cindex textual location@cindex location, textualMany applications, like interpreters or compilers, have to produce verboseand useful error messages. To achieve this, one must be able to keep track ofthe @dfn{textual location}, or @dfn{location}, of each syntactic construct.Bison provides a mechanism for handling these locations.Each token has a semantic value. In a similar fashion, each token has anassociated location, but the type of locations is the same for all tokens andgroupings. Moreover, the output parser is equipped with a default datastructure for storing locations (@pxref{Locations}, for more details).Like semantic values, locations can be reached in actions using a dedicatedset of constructs. In the example above, the location of the whole groupingis @code{@@$}, while the locations of the subexpressions are @code{@@1} and@code{@@3}.When a rule is matched, a default action is used to compute the semantic valueof its left hand side (@pxref{Actions}). In the same way, another defaultaction is used for locations. However, the action for locations is generalenough for most cases, meaning there is usually no need to describe for eachrule how @code{@@$} should be formed. When building a new location for a givengrouping, the default behavior of the output parser is to take the beginningof the first symbol, and the end of the last symbol.@node Bison Parser@section Bison Output: the Parser File@cindex Bison parser@cindex Bison utility@cindex lexical analyzer, purpose@cindex parserWhen you run Bison, you give it a Bison grammar file as input. The outputis a C source file that parses the language described by the grammar.This file is called a @dfn{Bison parser}. Keep in mind that the Bisonutility and the Bison parser are two distinct programs: the Bison utilityis a program whose output is the Bison parser that becomes part of yourprogram.The job of the Bison parser is to group tokens into groupings according tothe grammar rules---for example, to build identifiers and operators intoexpressions. As it does this, it runs the actions for the grammar rules ituses.The tokens come from a function called the @dfn{lexical analyzer} thatyou must supply in some fashion (such as by writing it in C). The Bisonparser calls the lexical analyzer each time it wants a new token. Itdoesn't know what is ``inside'' the tokens (though their semantic valuesmay reflect this). Typically the lexical analyzer makes the tokens byparsing characters of text, but Bison does not depend on this.@xref{Lexical, ,The Lexical Analyzer Function @code{yylex}}.The Bison parser file is C code which defines a function named@code{yyparse} which implements that grammar. This function does not makea complete C program: you must supply some additional functions. One isthe lexical analyzer. Another is an error-reporting function which theparser calls to report an error. In addition, a complete C program muststart with a function called @code{main}; you have to provide this, andarrange for it to call @code{yyparse} or the parser will never run.@xref{Interface, ,Parser C-Language Interface}.Aside from the token type names and the symbols in the actions youwrite, all symbols defined in the Bison parser file itselfbegin with @samp{yy} or @samp{YY}. This includes interface functionssuch as the lexical analyzer function @code{yylex}, the error reportingfunction @code{yyerror} and the parser function @code{yyparse} itself.This also includes numerous identifiers used for internal purposes.Therefore, you should avoid using C identifiers starting with @samp{yy}or @samp{YY} in the Bison grammar file except for the ones defined inthis manual.In some cases the Bison parser file includes system headers, and inthose cases your code should respect the identifiers reserved by thoseheaders. On some non-@acronym{GNU} hosts, @code{<alloca.h>},@code{<stddef.h>}, and @code{<stdlib.h>} are included as needed todeclare memory allocators and related types. @code{<libintl.h>} isincluded if message translation is in use(@pxref{Internationalization}). Other system headers maybe included if you define @code{YYDEBUG} to a nonzero value(@pxref{Tracing, ,Tracing Your Parser}).@node Stages@section Stages in Using Bison@cindex stages in using Bison@cindex using BisonThe actual language-design process using Bison, from grammar specificationto a working compiler or interpreter, has these parts:@enumerate@itemFormally specify the grammar in a form recognized by Bison(@pxref{Grammar File, ,Bison Grammar Files}). For each grammatical rulein the language, describe the action that is to be taken when aninstance of that rule is recognized. The action is described by asequence of C statements.@itemWrite a lexical analyzer to process input and pass tokens to the parser.The lexical analyzer may be written by hand in C (@pxref{Lexical, ,TheLexical Analyzer Function @code{yylex}}). It could also be producedusing Lex, but the use of Lex is not discussed in this manual.@itemWrite a controlling function that calls the Bison-produced parser.@itemWrite error-reporting routines.@end enumerateTo turn this source code as written into a runnable program, youmust follow these steps:@enumerate@itemRun Bison on the grammar to produce the parser.@itemCompile the code output by Bison, as well as any other source files.@itemLink the object files to produce the finished product.@end enumerate@node Grammar Layout@section The Overall Layout of a Bison Grammar@cindex grammar file@cindex file format@cindex format of grammar file@cindex layout of Bison grammarThe input file for the Bison utility is a @dfn{Bison grammar file}. Thegeneral form of a Bison grammar file is as follows:@example%@{@var{Prologue}%@}@var{Bison declarations}%%@var{Grammar rules}%%@var{Epilogue}@end example@noindentThe @samp{%%}, @samp{%@{} and @samp{%@}} are punctuation that appearsin every Bison grammar file to separate the sections.The prologue may define types and variables used in the actions. You canalso use preprocessor commands to define macros used there, and use@code{#include} to include header files that do any of these things.You need to declare the lexical analyzer @code{yylex} and the errorprinter @code{yyerror} here, along with any other global identifiersused by the actions in the grammar rules.The Bison declarations declare the names of the terminal and nonterminalsymbols, and may also describe operator precedence and the data types ofsemantic values of various symbols.The grammar rules define how to construct each nonterminal symbol from itsparts.The epilogue can contain any code you want to use. Often thedefinitions of functions declared in the prologue go here. In asimple program, all the rest of the program can go here.@node Examples@chapter Examples@cindex simple examples@cindex examples, simpleNow we show and explain three sample programs written using Bison: areverse polish notation calculator, an algebraic (infix) notationcalculator, and a multi-function calculator. All three have been testedunder BSD Unix 4.3; each produces a usable, though limited, interactivedesk-top calculator.These examples are simple, but Bison grammars for real programminglanguages are written the same way.@ifinfoYou can copy these examples out of the Info file and into a source fileto try them.@end ifinfo@menu* RPN Calc:: Reverse polish notation calculator; a first example with no operator precedence.* Infix Calc:: Infix (algebraic) notation calculator. Operator precedence is introduced.* Simple Error Recovery:: Continuing after syntax errors.* Location Tracking Calc:: Demonstrating the use of @@@var{n} and @@$.* Multi-function Calc:: Calculator with memory and trig functions. It uses multiple data-types for semantic values.* Exercises:: Ideas for improving the multi-function calculator.@end menu@node RPN Calc@section Reverse Polish Notation Calculator@cindex reverse polish notation@cindex polish notation calculator@cindex @code{rpcalc}@cindex calculator, simpleThe first example is that of a simple double-precision @dfn{reverse polishnotation} calculator (a calculator using postfix operators). This exampleprovides a good starting point, since operator precedence is not an issue.The second example will illustrate how operator precedence is handled.The source code for this calculator is named @file{rpcalc.y}. The@samp{.y} extension is a convention used for Bison input files.@menu* Decls: Rpcalc Decls. Prologue (declarations) for rpcalc.* Rules: Rpcalc Rules. Grammar Rules for rpcalc, with explanation.* Lexer: Rpcalc Lexer. The lexical analyzer.* Main: Rpcalc Main. The controlling function.* Error: Rpcalc Error. The error reporting function.* Gen: Rpcalc Gen. Running Bison on the grammar file.* Comp: Rpcalc Compile. Run the C compiler on the output code.@end menu@node Rpcalc Decls@subsection Declarations for @code{rpcalc}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -