X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/5ab8c47bcf5088cf420db6e03cd44bfa68e92ca0..5fad4d4f094e866b211302f01d556b3bc93350be:/examples/variant.yy diff --git a/examples/variant.yy b/examples/variant.yy index fafb6556..9413cbcf 100644 --- a/examples/variant.yy +++ b/examples/variant.yy @@ -1,106 +1,144 @@ -/* Test file for C++ parsers using variants. - Based on an example by Michiel De Wilde . */ -%language "C++" +/* + Copyright (C) 2008-2013 Free Software Foundation, Inc. + + 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 3 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, see . +*/ + %debug +%skeleton "lalr1.cc" %defines -%define variant +%define api.token.constructor +%define api.value.type variant +%define parse.assert +%locations %code requires // *.hh { +#include #include +typedef std::list strings_type; } %code // *.cc { #include #include +#include #include -static yy::parser::token_type yylex(yy::parser::semantic_type* yylval); + // Prototype of the yylex function providing subsequent tokens. + namespace yy + { + static parser::symbol_type yylex (); + } + + // Printing a list of strings. + // Koening look up will look into std, since that's an std::list. + namespace std + { + std::ostream& + operator<< (std::ostream& o, const strings_type& s) + { + std::copy (s.begin (), s.end (), + std::ostream_iterator (o, "\n")); + return o; + } + } + + // Conversion to string. + template + inline + std::string + string_cast (const T& t) + { + std::ostringstream o; + o << t; + return o.str (); + } } -%token TEXT -%token NUMBER -%printer { debug_stream() << $$; } -%token END_OF_FILE 0 +%token <::std::string> TEXT; +%token NUMBER; +%printer { yyoutput << $$; } <*>; +%token END_OF_FILE 0; -%type text result +%type <::std::string> item; +%type <::std::list> list; %% result: - text { std::cout << $1 << std::endl; } + list { std::cout << $1 << std::endl; } ; -text: - /* nothing */ { /* This will generate an empty string */ } -| text TEXT { std::swap($$,$1); $$.append($2); } -| text NUMBER { - std::swap($$,$1); - std::ostringstream o; - o << ' ' << $2; - $$.append(o.str()); - } +list: + /* nothing */ { /* Generates an empty string list */ } +| list item { std::swap ($$, $1); $$.push_back ($2); } +; + +item: + TEXT { std::swap ($$, $1); } +| NUMBER { $$ = string_cast ($1); } ; %% -// The yylex function providing subsequent tokens: -// TEXT "I have three numbers for you:" -// NUMBER 1 -// NUMBER 2 -// NUMBER 3 -// TEXT " and that's all!" -// END_OF_FILE - -static -yy::parser::token_type -yylex(yy::parser::semantic_type* yylval) +namespace yy { - static int stage = 0; - yy::parser::token_type result; + // The yylex function providing subsequent tokens: + // TEXT "I have three numbers for you." + // NUMBER 1 + // NUMBER 2 + // NUMBER 3 + // TEXT "And that's all!" + // END_OF_FILE - switch (stage) + static + parser::symbol_type + yylex () { - case 0: - yylval->build(); - yylval->as() = std::string("I have three numbers for you:"); - result = yy::parser::token::TEXT; - break; - case 1: - case 2: - case 3: - yylval->build(); - yylval->as() = stage; - result = yy::parser::token::NUMBER; - break; - case 4: - yylval->build(); - yylval->as() = std::string(" and that's all!"); - result = yy::parser::token::TEXT; - break; - default: - result = yy::parser::token::END_OF_FILE; - break; + static int stage = -1; + ++stage; + parser::location_type loc(0, stage + 1, stage + 1); + switch (stage) + { + case 0: + return parser::make_TEXT ("I have three numbers for you.", loc); + case 1: + case 2: + case 3: + return parser::make_NUMBER (stage, loc); + case 4: + return parser::make_TEXT ("And that's all!", loc); + default: + return parser::make_END_OF_FILE (loc); + } } - stage++; - return result; -} - -// Mandatory error function -void -yy::parser::error(const yy::parser::location_type& yylloc, - const std::string& message) -{ - std::cerr << yylloc << ": " << message << std::endl; + // Mandatory error function + void + parser::error (const parser::location_type& loc, const std::string& msg) + { + std::cerr << loc << ": " << msg << std::endl; + } } int -main(int argc, char *argv[]) +main () { yy::parser p; - p.set_debug_level(!!getenv("YYDEBUG")); - p.parse(); + p.set_debug_level (!!getenv ("YYDEBUG")); + return p.parse (); } // Local Variables: