The unary-minus is another typical example where associativity is
usually over-specified, see @ref{Infix Calc, , Infix Notation
-Calculator: @code{calc}}. The @code{%left} directive is traditionally
+Calculator - @code{calc}}. The @code{%left} directive is traditionally
used to declare the precedence of @code{NEG}, which is more than needed
since it also defines its associativity. While this is harmless in the
traditional example, who knows how @code{NEG} might be used in future
in order to compute the (default) value of @code{@@$} in a reduction, the
parser basically runs
@example
-@@$.begin = @@$1.begin;
-@@$.end = @@$@var{N}.end; // The location of last right-hand side symbol.
+@@$.begin = @@1.begin;
+@@$.end = @@@var{N}.end; // The location of last right-hand side symbol.
@end example
@noindent
so there must be copyable @code{begin} and @code{end} members;
@example
[0-9]+ @{
- yylval.ival = text_to_int (yytext);
- return yy::parser::INTEGER;
+ yylval->ival = text_to_int (yytext);
+ return yy::parser::token::INTEGER;
@}
[a-z]+ @{
- yylval.sval = new std::string (yytext);
- return yy::parser::IDENTIFIER;
+ yylval->sval = new std::string (yytext);
+ return yy::parser::token::IDENTIFIER;
@}
@end example
@example
[0-9]+ @{
- yylval.build<int>() = text_to_int (yytext);
- return yy::parser::INTEGER;
+ yylval->build<int> () = text_to_int (yytext);
+ return yy::parser::token::INTEGER;
@}
[a-z]+ @{
- yylval.build<std::string> = yytext;
- return yy::parser::IDENTIFIER;
+ yylval->build<std::string> () = yytext;
+ return yy::parser::token::IDENTIFIER;
@}
@end example
@example
[0-9]+ @{
- yylval.build(text_to_int (yytext));
- return yy::parser::INTEGER;
+ yylval->build (text_to_int (yytext));
+ return yy::parser::token::INTEGER;
@}
[a-z]+ @{
- yylval.build(yytext);
- return yy::parser::IDENTIFIER;
+ yylval->build (yytext);
+ return yy::parser::token::IDENTIFIER;
@}
@end example
So for each token type, Bison generates named constructors as follows.
-@deftypemethod {symbol_type} {} make_@var{token} (const @var{value_type}& @var{value}, const location_type& @var{location})
-@deftypemethodx {symbol_type} {} make_@var{token} (const location_type& @var{location})
+@deftypemethod {symbol_type} {} {make_@var{token}} (const @var{value_type}& @var{value}, const location_type& @var{location})
+@deftypemethodx {symbol_type} {} {make_@var{token}} (const location_type& @var{location})
Build a complete terminal symbol for the token type @var{token} (not
including the @code{api.token.prefix}) whose possible semantic value is
@var{value} of adequate @var{value_type}. If location tracking is enabled,
Bison generates the following functions:
@example
-symbol_type make_IDENTIFIER(const std::string& v,
- const location_type& l);
-symbol_type make_INTEGER(const int& v,
- const location_type& loc);
-symbol_type make_COLON(const location_type& loc);
+symbol_type make_IDENTIFIER (const std::string&, const location_type&);
+symbol_type make_INTEGER (const int&, const location_type&);
+symbol_type make_COLON (const location_type&);
@end example
@noindent
which should be used in a Lex-scanner as follows.
@example
-[0-9]+ return yy::parser::make_INTEGER(text_to_int (yytext), loc);
-[a-z]+ return yy::parser::make_IDENTIFIER(yytext, loc);
-":" return yy::parser::make_COLON(loc);
+[0-9]+ return yy::parser::make_INTEGER (text_to_int (yytext), loc);
+[a-z]+ return yy::parser::make_IDENTIFIER (yytext, loc);
+":" return yy::parser::make_COLON (loc);
@end example
Tokens that do not have an identifier are not accessible: you cannot simply
@noindent
The grammar itself is straightforward (@pxref{Location Tracking Calc, ,
-Location Tracking Calculator: @code{ltcalc}}).
+Location Tracking Calculator - @code{ltcalc}}).
@comment file: calc++-parser.yy
@example
@comment file: calc++-scanner.ll
@example
-"-" return yy::calcxx_parser::make_MINUS(loc);
-"+" return yy::calcxx_parser::make_PLUS(loc);
-"*" return yy::calcxx_parser::make_STAR(loc);
-"/" return yy::calcxx_parser::make_SLASH(loc);
-"(" return yy::calcxx_parser::make_LPAREN(loc);
-")" return yy::calcxx_parser::make_RPAREN(loc);
-":=" return yy::calcxx_parser::make_ASSIGN(loc);
+"-" return yy::calcxx_parser::make_MINUS (loc);
+"+" return yy::calcxx_parser::make_PLUS (loc);
+"*" return yy::calcxx_parser::make_STAR (loc);
+"/" return yy::calcxx_parser::make_SLASH (loc);
+"(" return yy::calcxx_parser::make_LPAREN (loc);
+")" return yy::calcxx_parser::make_RPAREN (loc);
+":=" return yy::calcxx_parser::make_ASSIGN (loc);
@group
@{int@} @{
long n = strtol (yytext, NULL, 10);
if (! (INT_MIN <= n && n <= INT_MAX && errno != ERANGE))
driver.error (loc, "integer is out of range");
- return yy::calcxx_parser::make_NUMBER(n, loc);
+ return yy::calcxx_parser::make_NUMBER (n, loc);
@}
@end group
-@{id@} return yy::calcxx_parser::make_IDENTIFIER(yytext, loc);
+@{id@} return yy::calcxx_parser::make_IDENTIFIER (yytext, loc);
. driver.error (loc, "invalid character");
-<<EOF>> return yy::calcxx_parser::make_END(loc);
+<<EOF>> return yy::calcxx_parser::make_END (loc);
%%
@end example