doc: some improvements

* doc/bison.texi (Calc++ Scanner): Show how exception can be thrown
from auxiliary functions.
Clarify the meaning of the various flex %options we use.
Get rid of a warning.
(Calc++ Parsing Driver): Use the parser as a functor.
This commit is contained in:
Akim Demaille
2018-10-25 19:40:50 +02:00
parent f3110c9b9a
commit ee175dfd00

View File

@@ -11607,9 +11607,9 @@ driver::parse (const std::string &f)
file = f; file = f;
location.initialize (&file); location.initialize (&file);
scan_begin (); scan_begin ();
yy::parser parser (*this); yy::parser parse (*this);
parser.set_debug_level (trace_parsing); parse.set_debug_level (trace_parsing);
int res = parser.parse (); int res = parse ();
scan_end (); scan_end ();
return res; return res;
@} @}
@@ -11832,6 +11832,13 @@ then the parser's to get the set of defined tokens.
# pragma GCC diagnostic ignored "-Wnull-dereference" # pragma GCC diagnostic ignored "-Wnull-dereference"
#endif #endif
// Of course, when compiling C as C++, expect warnings about NULL.
#if defined __clang__
# pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
#elif defined __GNUC__
# pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
#endif
#define FLEX_VERSION (YY_FLEX_MAJOR_VERSION * 100 + YY_FLEX_MINOR_VERSION) #define FLEX_VERSION (YY_FLEX_MAJOR_VERSION * 100 + YY_FLEX_MINOR_VERSION)
// Old versions of Flex (2.5.35) generate an incomplete documentation comment. // Old versions of Flex (2.5.35) generate an incomplete documentation comment.
@@ -11872,14 +11879,27 @@ then the parser's to get the set of defined tokens.
@end ignore @end ignore
@noindent @noindent
Because there is no @code{#include}-like feature we don't need Since our calculator has no @code{#include}-like feature, we don't need
@code{yywrap}, we don't need @code{unput} either, and we parse an actual @code{yywrap}. We don't need the @code{unput} and @code{input} functions
file, this is not an interactive session with the user. Finally, we enable either, and we parse an actual file, this is not an interactive session with
scanner tracing. the user. Finally, we enable scanner tracing.
@comment file: calc++/scanner.ll @comment file: calc++/scanner.ll
@example @example
%option noyywrap nounput batch debug noinput %option noyywrap nounput noinput batch debug
@end example
@noindent
The following function will be handy to convert a string denoting a number
into a number token.
@comment file: calc++/scanner.ll
@example
%@{
// A number symbol corresponding to the value in S.
yy::parser::symbol_type
make_NUMBER (const std::string &s, const yy::parser::location_type& loc);
%@}
@end example @end example
@noindent @noindent
@@ -11926,24 +11946,15 @@ The rules are simple. The driver is used to report errors.
@comment file: calc++/scanner.ll @comment file: calc++/scanner.ll
@example @example
"-" return yy::parser::make_MINUS (loc); "-" return yy::parser::make_MINUS (loc);
"+" return yy::parser::make_PLUS (loc); "+" return yy::parser::make_PLUS (loc);
"*" return yy::parser::make_STAR (loc); "*" return yy::parser::make_STAR (loc);
"/" return yy::parser::make_SLASH (loc); "/" return yy::parser::make_SLASH (loc);
"(" return yy::parser::make_LPAREN (loc); "(" return yy::parser::make_LPAREN (loc);
")" return yy::parser::make_RPAREN (loc); ")" return yy::parser::make_RPAREN (loc);
":=" return yy::parser::make_ASSIGN (loc); ":=" return yy::parser::make_ASSIGN (loc);
@group @{int@} return make_NUMBER (yytext, loc);
@{int@} @{
errno = 0;
long n = strtol (yytext, NULL, 10);
if (! (INT_MIN <= n && n <= INT_MAX && errno != ERANGE))
throw yy::parser::syntax_error (loc, "integer is out of range: "
+ std::string(yytext));
return yy::parser::make_NUMBER (int (n), loc);
@}
@end group
@{id@} return yy::parser::make_IDENTIFIER (yytext, loc); @{id@} return yy::parser::make_IDENTIFIER (yytext, loc);
@group @group
. @{ . @{
@@ -11955,6 +11966,25 @@ The rules are simple. The driver is used to report errors.
%% %%
@end example @end example
@noindent
You should keep your rules simple, both in the parser and in the scanner.
Throwing from the auxiliary functions is then very handy to report errors.
@comment file: scanner.ll
@example
@group
yy::parser::symbol_type
make_NUMBER (const std::string &s, const yy::parser::location_type& loc)
@{
errno = 0;
long n = strtol (s.c_str(), NULL, 10);
if (! (INT_MIN <= n && n <= INT_MAX && errno != ERANGE))
throw yy::parser::syntax_error (loc, "integer is out of range: " + s);
return yy::parser::make_NUMBER ((int) n, loc);
@}
@end group
@end example
@noindent @noindent
Finally, because the scanner-related driver's member-functions depend Finally, because the scanner-related driver's member-functions depend
on the scanner's data, it is simpler to implement them in this file. on the scanner's data, it is simpler to implement them in this file.
@@ -12748,9 +12778,9 @@ too. How can I reset the error flag of @code{yyparse}?
or or
@quotation @quotation
My parser includes support for an @samp{#include}-like feature, in My parser includes support for an @samp{#include}-like feature, in which
which case I run @code{yyparse} from @code{yyparse}. This fails case I run @code{yyparse} from @code{yyparse}. This fails although I did
although I did specify @samp{%define api.pure full}. specify @samp{%define api.pure full}.
@end quotation @end quotation
These problems typically come not from Bison itself, but from These problems typically come not from Bison itself, but from